diff --git a/gjson.go b/gjson.go index 813c71e..6b873bd 100644 --- a/gjson.go +++ b/gjson.go @@ -1865,8 +1865,14 @@ func validobject(data []byte, i int) (outi int, ok bool) { if data[i] == '}' { return i + 1, true } + i++ for ; i < len(data); i++ { - if data[i] == '"' { + switch data[i] { + default: + return i, false + case ' ', '\t', '\n', '\r': + continue + case '"': goto key } } diff --git a/gjson_test.go b/gjson_test.go index 9258e1b..105ffbd 100644 --- a/gjson_test.go +++ b/gjson_test.go @@ -970,80 +970,82 @@ func TestUnmarshal(t *testing.T) { assert(t, str == Get(complicatedJSON, "LeftOut").String()) } -func testvalid(json string, expect bool) { +func testvalid(t *testing.T, json string, expect bool) { + t.Helper() _, ok := validpayload([]byte(json), 0) if ok != expect { - panic("mismatch") + t.Fatal("mismatch") } } func TestValidBasic(t *testing.T) { - testvalid("0", true) - testvalid("00", false) - testvalid("-00", false) - testvalid("-.", false) - testvalid("0.0", true) - testvalid("10.0", true) - testvalid("10e1", true) - testvalid("10EE", false) - testvalid("10E-", false) - testvalid("10E+", false) - testvalid("10E123", true) - testvalid("10E-123", true) - testvalid("10E-0123", true) - testvalid("", false) - testvalid(" ", false) - testvalid("{}", true) - testvalid("{", false) - testvalid("-", false) - testvalid("-1", true) - testvalid("-1.", false) - testvalid("-1.0", true) - testvalid(" -1.0", true) - testvalid(" -1.0 ", true) - testvalid("-1.0 ", true) - testvalid("-1.0 i", false) - testvalid("-1.0 i", false) - testvalid("true", true) - testvalid(" true", true) - testvalid(" true ", true) - testvalid(" True ", false) - testvalid(" tru", false) - testvalid("false", true) - testvalid(" false", true) - testvalid(" false ", true) - testvalid(" False ", false) - testvalid(" fals", false) - testvalid("null", true) - testvalid(" null", true) - testvalid(" null ", true) - testvalid(" Null ", false) - testvalid(" nul", false) - testvalid(" []", true) - testvalid(" [true]", true) - testvalid(" [ true, null ]", true) - testvalid(" [ true,]", false) - testvalid(`{"hello":"world"}`, true) - testvalid(`{ "hello": "world" }`, true) - testvalid(`{ "hello": "world", }`, false) - testvalid(`{"a":"b",}`, false) - testvalid(`{"a":"b","a"}`, false) - testvalid(`{"a":"b","a":}`, false) - testvalid(`{"a":"b","a":1}`, true) - testvalid(`{"a":"b","a": 1, "c":{"hi":"there"} }`, true) - testvalid(`{"a":"b","a": 1, "c":{"hi":"there", "easy":["going",{"mixed":"bag"}]} }`, true) - testvalid(`""`, true) - testvalid(`"`, false) - testvalid(`"\n"`, true) - testvalid(`"\"`, false) - testvalid(`"\\"`, true) - testvalid(`"a\\b"`, true) - testvalid(`"a\\b\\\"a"`, true) - testvalid(`"a\\b\\\uFFAAa"`, true) - testvalid(`"a\\b\\\uFFAZa"`, false) - testvalid(`"a\\b\\\uFFA"`, false) - testvalid(string(complicatedJSON), true) - testvalid(string(exampleJSON), true) + testvalid(t, "0", true) + testvalid(t, "00", false) + testvalid(t, "-00", false) + testvalid(t, "-.", false) + testvalid(t, "0.0", true) + testvalid(t, "10.0", true) + testvalid(t, "10e1", true) + testvalid(t, "10EE", false) + testvalid(t, "10E-", false) + testvalid(t, "10E+", false) + testvalid(t, "10E123", true) + testvalid(t, "10E-123", true) + testvalid(t, "10E-0123", true) + testvalid(t, "", false) + testvalid(t, " ", false) + testvalid(t, "{}", true) + testvalid(t, "{", false) + testvalid(t, "-", false) + testvalid(t, "-1", true) + testvalid(t, "-1.", false) + testvalid(t, "-1.0", true) + testvalid(t, " -1.0", true) + testvalid(t, " -1.0 ", true) + testvalid(t, "-1.0 ", true) + testvalid(t, "-1.0 i", false) + testvalid(t, "-1.0 i", false) + testvalid(t, "true", true) + testvalid(t, " true", true) + testvalid(t, " true ", true) + testvalid(t, " True ", false) + testvalid(t, " tru", false) + testvalid(t, "false", true) + testvalid(t, " false", true) + testvalid(t, " false ", true) + testvalid(t, " False ", false) + testvalid(t, " fals", false) + testvalid(t, "null", true) + testvalid(t, " null", true) + testvalid(t, " null ", true) + testvalid(t, " Null ", false) + testvalid(t, " nul", false) + testvalid(t, " []", true) + testvalid(t, " [true]", true) + testvalid(t, " [ true, null ]", true) + testvalid(t, " [ true,]", false) + testvalid(t, `{"hello":"world"}`, true) + testvalid(t, `{ "hello": "world" }`, true) + testvalid(t, `{ "hello": "world", }`, false) + testvalid(t, `{"a":"b",}`, false) + testvalid(t, `{"a":"b","a"}`, false) + testvalid(t, `{"a":"b","a":}`, false) + testvalid(t, `{"a":"b","a":1}`, true) + testvalid(t, `{"a":"b",2"1":2}`, false) + testvalid(t, `{"a":"b","a": 1, "c":{"hi":"there"} }`, true) + testvalid(t, `{"a":"b","a": 1, "c":{"hi":"there", "easy":["going",{"mixed":"bag"}]} }`, true) + testvalid(t, `""`, true) + testvalid(t, `"`, false) + testvalid(t, `"\n"`, true) + testvalid(t, `"\"`, false) + testvalid(t, `"\\"`, true) + testvalid(t, `"a\\b"`, true) + testvalid(t, `"a\\b\\\"a"`, true) + testvalid(t, `"a\\b\\\uFFAAa"`, true) + testvalid(t, `"a\\b\\\uFFAZa"`, false) + testvalid(t, `"a\\b\\\uFFA"`, false) + testvalid(t, string(complicatedJSON), true) + testvalid(t, string(exampleJSON), true) } var jsonchars = []string{"{", "[", ",", ":", "}", "]", "1", "0", "true", "false", "null", `""`, `"\""`, `"a"`}