diff options
author | Luke Shumaker <lukeshu@lukeshu.com> | 2023-02-24 09:20:15 -0700 |
---|---|---|
committer | Luke Shumaker <lukeshu@lukeshu.com> | 2023-02-25 20:59:23 -0700 |
commit | 3b4ca665fbe89bdf44560454684bb6829070d7f4 (patch) | |
tree | 3a3ccc02a39edad8aa4116890e6070bd18d921ef /internal | |
parent | 0fa9f8b14f04f4b0099f038cc43e4cef57a155a1 (diff) |
jsonparse: Fix a bug allowing a trailing comma in objects
Diffstat (limited to 'internal')
-rw-r--r-- | internal/jsonparse/parse.go | 33 | ||||
-rw-r--r-- | internal/jsonparse/parse_test.go | 14 |
2 files changed, 29 insertions, 18 deletions
diff --git a/internal/jsonparse/parse.go b/internal/jsonparse/parse.go index 5547df4..ce71a65 100644 --- a/internal/jsonparse/parse.go +++ b/internal/jsonparse/parse.go @@ -279,7 +279,8 @@ type Parser struct { // rule; they need some special assignments: // // { object: waiting for key to start or '}' - // » object: reading key / waiting for colon + // } object: waiting for key to start + // : object: reading key / waiting for colon // o object: reading value / waiting for ',' or '}' // // [ array: waiting for item to start or ']' @@ -298,17 +299,17 @@ type Parser struct { // stack processed // ? // { { - // »" {" - // »" {"x - // » {"x" + // :" {" + // :" {"x + // : {"x" // o? {"x": // o" {"x":" // o" {"x":"y // o {"x":"y" - // { {"x":"y", - // »" {"x":"y"," - // »" {"x":"y","a - // » {"x":"y","a" + // } {"x":"y", + // :" {"x":"y"," + // :" {"x":"y","a + // : {"x":"y","a" // o? {"x":"y","a": // o" {"x":"y","a":" // o" {"x":"y","a":"b @@ -627,7 +628,7 @@ func (par *Parser) HandleRune(c rune, isRune bool) (RuneType, error) { case 0x0020, 0x000A, 0x000D, 0x0009: return RuneTypeSpace, nil case '"': - par.replaceState(RuneTypeStringEnd) + par.replaceState(RuneTypeObjectColon) return par.pushState(RuneTypeStringBeg), nil case '}': par.popState() @@ -635,7 +636,17 @@ func (par *Parser) HandleRune(c rune, isRune bool) (RuneType, error) { default: return RuneTypeError, &InvalidCharacterError{c, isRune, "looking for beginning of object key string"} } - case RuneTypeStringEnd: // waiting for ':' + case RuneTypeObjectEnd: // waiting for key to start + switch c { + case 0x0020, 0x000A, 0x000D, 0x0009: + return RuneTypeSpace, nil + case '"': + par.replaceState(RuneTypeObjectColon) + return par.pushState(RuneTypeStringBeg), nil + default: + return RuneTypeError, &InvalidCharacterError{c, isRune, "looking for beginning of object key string"} + } + case RuneTypeObjectColon: // waiting for ':' switch c { case 0x0020, 0x000A, 0x000D, 0x0009: return RuneTypeSpace, nil @@ -651,7 +662,7 @@ func (par *Parser) HandleRune(c rune, isRune bool) (RuneType, error) { case 0x0020, 0x000A, 0x000D, 0x0009: return RuneTypeSpace, nil case ',': - par.replaceState(RuneTypeObjectBeg) + par.replaceState(RuneTypeObjectEnd) return RuneTypeObjectComma, nil case '}': par.popState() diff --git a/internal/jsonparse/parse_test.go b/internal/jsonparse/parse_test.go index acb43e8..fe94c58 100644 --- a/internal/jsonparse/parse_test.go +++ b/internal/jsonparse/parse_test.go @@ -24,17 +24,17 @@ func TestParserHandleRune(t *testing.T) { // st,// processed `?`, `{`, // { - `»"`, // {" - `»"`, // {"x - `»`, // {"x" + `:"`, // {" + `:"`, // {"x + `:`, // {"x" `o?`, // {"x": `o"`, // {"x":" `o"`, // {"x":"y `o`, // {"x":"y" - `{`, // {"x":"y", - `»"`, // {"x":"y"," - `»"`, // {"x":"y","a - `»`, // {"x":"y","a" + `}`, // {"x":"y", + `:"`, // {"x":"y"," + `:"`, // {"x":"y","a + `:`, // {"x":"y","a" `o?`, // {"x":"y","a": `o"`, // {"x":"y","a":" `o"`, // {"x":"y","a":"b |