valyala / fastjson

Fast JSON parser and validator for Go. No custom structs, no code generation, no reflection

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Simply calling Type() changes value of key

patrikhermansson opened this issue · comments

Hi,
Thanks for a great library. It seems like i've found an edge case where unescapeStringBestEffort(), which is called from .Type() on a value ends up changing the value of the field. Meaning that simply calling .Type() results in a change of the data which is unexpected.

So it's two issues really. One is that unescapeStringBestEffort() have issues unescaping some strings. I've included an example json below. In my testing it seems to be some emojis followed by a line break.

The second and bigger issue is that, unescapeStringBestEffort() is called when checking type of a value. Resulting in simply checking the Type changes the data which seems like unwanted behaviour as it brings about quite unexpected issues.

Steps to reproduce:

Json affected:
{"caption":"󠁧󠁢󠁥󠁮󠁧󠁿🏴󠁧󠁢\n"}

Code:
var p fastjson.Parser strBytes := []byte({"caption":"󠁧󠁢󠁥󠁮󠁧󠁿🏴󠁧󠁢\n"}`)

parser, _ := p.ParseBytes(strBytes)
ob, _ := parser.Object()

// Marshals correctly: {"caption":"󠁧󠁢󠁥󠁮󠁧󠁿🏴󠁧󠁢\n"}
fmt.Println(string(ob.MarshalTo(nil)))

ob.Visit(func(key []byte, v *fastjson.Value) {
v.Type()
})

// Marshals incorrectly:{"caption":"\U000e0067\U000e0062\U000e0065\U000e006e\U000e0067\U000e007f🏴\U000e0067\U000e0062\n"}

fmt.Println(string(ob.MarshalTo(nil)))
`

This error wont happen if you comment out the .Type() in the visit loop or take out line 660 and 661 in parser.go.