From 32c8218c7240b05a7af791ebf5187f107f015c2b Mon Sep 17 00:00:00 2001 From: youdie006 Date: Mon, 7 Sep 2026 12:04:00 +0900 Subject: [PATCH] fix: Do not reject a maximal-length number followed by a delimiter parseNumber evaluates the length bound at the top of the loop, before looking at the next character, so a 15-digit integer or 16-character decimal fails as soon as anything follows it. RFC 9651 section 4.2.4 appends the character first and fails only when input_number already holds more than 15 or 16 characters, so those inputs are valid. marshalInteger allows the full +/-999999999999999 range, so the library emits headers it cannot read back: Marshal of a list containing 123456789012345 and 1 gives '123456789012345, 1', and UnmarshalList of that string returns 'integer or decimal out of range: character 15'. Move the check after the digit is consumed and compare with > instead of >=, matching the form the '.' branch already uses. --- integer.go | 12 ++++++------ integer_test.go | 2 ++ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/integer.go b/integer.go index dd7636b..74a764f 100644 --- a/integer.go +++ b/integer.go @@ -59,20 +59,20 @@ func parseNumber(s *scanner) (interface{}, error) { ) for s.off < len(s.data) { - size := s.off - start - if (t == typeInteger && (size >= 15)) || size >= 16 { - return 0, &UnmarshalError{s.off, ErrNumberOutOfRange} - } - c := s.data[s.off] if isDigit(c) { s.off++ + // The length limit applies to the consumed digits, not to the delimiter that follows them. + if size := s.off - start; (t == typeInteger && size > 15) || size > 16 { + return 0, &UnmarshalError{s.off, ErrNumberOutOfRange} + } + continue } if t == typeInteger && c == '.' { - if size > maxDigit { + if s.off-start > maxDigit { return 0, &UnmarshalError{s.off, ErrNumberOutOfRange} } diff --git a/integer_test.go b/integer_test.go index 099e2b9..26a1ff0 100644 --- a/integer_test.go +++ b/integer_test.go @@ -59,6 +59,8 @@ func TestParseIntegerOrDecimal(t *testing.T) { {"10.", 0, true}, {"10.1234", 0, true}, {"-", 0, true}, + {"123456789012345, 1", int64(123456789012345), false}, + {"123456789012.123, 1.1", 123456789012.123, false}, {"1234567890123456", 0, true}, {"123456789012345.6", 0, true}, {"1234567890123.", 0, true},