fastjson icon indicating copy to clipboard operation
fastjson copied to clipboard

Parser does not fully validate the JSON

Open mna opened this issue 2 years ago • 1 comments

Hello,

I was checking out fastjson and noticed that some invalid JSON strings were accepted without error, e.g. the following program:

func main() {
	s := `"foo
bar"`
	err := fastjson.Validate(s)
	fmt.Printf(">>> Validate: %v\n", err)
	var p fastjson.Parser
	v, err := p.Parse(s)
	fmt.Printf(">>> Parse: %s - %v\n", v.GetStringBytes(), err)

	s = `"ab\c\de"`
	err = fastjson.Validate(s)
	fmt.Printf(">>> Validate: %v\n", err)
	v, err = p.Parse(s)
	fmt.Printf(">>> Parse: %s - %v\n", v.GetStringBytes(), err)
}

// prints:
// >>> Validate: cannot parse JSON: string cannot contain control char 0x0A; unparsed tail: ""
// >>> Parse: foo
// bar - <nil>
// >>> Validate: cannot parse JSON: cannot parse string: unknown escape sequence \c; unparsed tail: ""
// >>> Parse: ab\c\de - <nil>

That is, calling fastjson.Validate properly catches the error, but Parser.Parse doesn't. Is that to be expected (the README does mention "Validates the parsed JSON unlike ...")? Having to call Validate prior to parsing any value to ensure its correctness would obviously make the performance benefits much less interesting, but maybe I'm missing something.

Thanks, Martin

mna avatar Jan 20 '23 22:01 mna

Another example:

package main

import (
	"fmt"

	"github.com/valyala/fastjson"
)

func main() {
	v, err := fastjson.ParseBytes([]byte(`[127.0.0.1]`))
	if err != nil {
		fmt.Println("failed:", err.Error())
	} else {
		fmt.Println("passed:", v.Type())
	}

	err = fastjson.ValidateBytes([]byte(`[127.0.0.1]`))
	if err != nil {
		fmt.Println("validation failed:", err.Error())
	}

	// Output:
	// passed: array
	// validation failed: cannot parse JSON: cannot parse array: missing ',' after array value; unparsed tail: ".0.1]"
}

vearutop avatar Feb 02 '23 14:02 vearutop