From 3636ced112d89da03739fa7d5468c0270addaa28 Mon Sep 17 00:00:00 2001 From: Joe Tsai Date: Thu, 24 Jul 2025 12:16:35 -0700 Subject: encoding/json: fix extra data regression under goexperiment.jsonv2 When operating under v1 semantics in the v2 implementation, a extra data error should take precedence over any semantic error that could theoretically occur within the value itself. This change only affects code compiled under goexperiment.jsonv2. Fixes #74614 Change-Id: I055a606b053fa66b0c766ae205487b8290109285 Reviewed-on: https://go-review.googlesource.com/c/go/+/689919 Reviewed-by: Damien Neil Reviewed-by: Michael Knyszek Auto-Submit: Michael Knyszek LUCI-TryBot-Result: Go LUCI --- src/encoding/json/jsontext/decode.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'src/encoding/json/jsontext/decode.go') diff --git a/src/encoding/json/jsontext/decode.go b/src/encoding/json/jsontext/decode.go index 44b436686f..b9f247bff4 100644 --- a/src/encoding/json/jsontext/decode.go +++ b/src/encoding/json/jsontext/decode.go @@ -776,7 +776,8 @@ func (d *decoderState) ReadValue(flags *jsonwire.ValueFlags) (Value, error) { // CheckNextValue checks whether the next value is syntactically valid, // but does not advance the read offset. -func (d *decoderState) CheckNextValue() error { +// If last, it verifies that the stream cleanly terminates with [io.EOF]. +func (d *decoderState) CheckNextValue(last bool) error { d.PeekKind() // populates d.peekPos and d.peekErr pos, err := d.peekPos, d.peekErr d.peekPos, d.peekErr = 0, nil @@ -787,13 +788,18 @@ func (d *decoderState) CheckNextValue() error { var flags jsonwire.ValueFlags if pos, err := d.consumeValue(&flags, pos, d.Tokens.Depth()); err != nil { return wrapSyntacticError(d, err, pos, +1) + } else if last { + return d.checkEOF(pos) } return nil } // CheckEOF verifies that the input has no more data. func (d *decoderState) CheckEOF() error { - switch pos, err := d.consumeWhitespace(d.prevEnd); err { + return d.checkEOF(d.prevEnd) +} +func (d *decoderState) checkEOF(pos int) error { + switch pos, err := d.consumeWhitespace(pos); err { case nil: err := jsonwire.NewInvalidCharacterError(d.buf[pos:], "after top-level value") return wrapSyntacticError(d, err, pos, 0) -- cgit v1.3-5-g9baa