Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions decode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4057,3 +4057,25 @@ func TestIssue429(t *testing.T) {
}
}
}

func TestIssue604(t *testing.T) {
// A dangling escape at the end of an object key (e.g. `{"\`) must return an
// error, not silently advance the cursor past the buffer. Decoding it in a
// sequence with another malformed input used to panic with an out-of-range
// index because the key scanner over-read a reused (pooled) buffer.
type doc struct {
ID string `json:"id"`
Meta map[string][]string `json:"meta"`
ContentMD string `json:"contentMd"`
}
inputs := []string{
`[{"x":1},{"y":`, // unterminated array of objects
`{"\`, // object key ending in a dangling escape
}
for i := 0; i < 20; i++ {
var d doc
if err := json.Unmarshal([]byte(inputs[i%len(inputs)]), &d); err == nil {
t.Fatalf("input %q: expected error, got nil", inputs[i%len(inputs)])
}
}
}
2 changes: 2 additions & 0 deletions internal/decoder/struct.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,8 @@ func decodeKeyCharByEscapedChar(buf []byte, cursor int64) ([]byte, int64, error)
return []byte{'\t'}, cursor, nil
case 'u':
return decodeKeyCharByUnicodeRune(buf, cursor)
case nul:
return nil, 0, errors.ErrUnexpectedEndOfJSON("escaped string", cursor)
}
return nil, cursor, nil
}
Expand Down