From 61f0922ceb366d06c160529b8b378661d568488b Mon Sep 17 00:00:00 2001 From: Rose Hogenson Date: Wed, 3 Dec 2025 17:49:18 -0800 Subject: Fix a few bugs in parsing numbers --- ccl.go | 19 ++++++++++++++----- ccl_test.go | 23 +++++++++++++++++++---- 2 files changed, 33 insertions(+), 9 deletions(-) diff --git a/ccl.go b/ccl.go index 3cce7a1..4b11392 100644 --- a/ccl.go +++ b/ccl.go @@ -310,14 +310,17 @@ func checkNum(b []byte) bool { if !haveDigits { return false } - if len(b) == 0 || !(b[0] == 'e' || b[0] == 'E') { + if len(b) == 0 { return true } + if !(b[0] == 'e' || b[0] == 'E') { + return false + } b = b[1:] if len(b) > 0 && (b[0] == '-' || b[0] == '+') { b = b[1:] } - if len(b) == 0 { + if len(b) == 0 || !('1' <= b[0] && b[0] <= '9') { return false } for ; len(b) > 0 && '0' <= b[0] && b[0] <= '9'; b = b[1:] { @@ -352,7 +355,10 @@ func (p *parser) parseInt(numBytes []byte) (integer, error) { } un, err := strconv.ParseUint(string(n), 10, 64) if err != nil { - return integer{}, p.error("(unreachable) invalid number: %s", err) + if errors.Is(err, strconv.ErrSyntax) { + panic(fmt.Sprintf("Invalid number that wasn't caught by checkNum: %s", err)) + } + return integer{}, p.error("%s", err) } return integer{un, sgn}, nil } @@ -363,7 +369,10 @@ func (p *parser) parseFloat(nBytes []byte) (float64, error) { } n, err := strconv.ParseFloat(string(nBytes), 64) if err != nil { - return 0, p.error("(unreachable) invalid number: %s", err) + if errors.Is(err, strconv.ErrSyntax) { + panic(fmt.Sprintf("Invalid number that wasn't caught by checkNum: %s", err)) + } + return 0, p.error("%s", err) } return n, nil } @@ -429,7 +438,7 @@ func (p *parser) unescape(rawStr []byte) ([]byte, error) { } n, err := strconv.ParseUint(string(rawStr[i:end]), 16, 8) if err != nil { - return nil, p.error("(unreachable) invalid hex escape %q: %s", rawStr[i-2:end], err) + panic(fmt.Sprintf("Invalid hex escape %q: %s", rawStr[i-2:end], err)) } i = end - 1 b = []byte{byte(n)} diff --git a/ccl_test.go b/ccl_test.go index ac64d58..7ec9da2 100644 --- a/ccl_test.go +++ b/ccl_test.go @@ -411,10 +411,6 @@ func TestUnmarshal_Invalid(t *testing.T) { desc: "BadNum", msg: `int: .`, want: &syntaxError{line: 1, col: 6}, - }, { - desc: "WeirdNum", - msg: `float:1e+`, - want: &syntaxError{line: 1, col: 7}, }, { desc: "BadHex", msg: `int:0xgg`, @@ -539,6 +535,10 @@ func TestUnmarshal_Invalid(t *testing.T) { desc: "FloatMissingExponent", msg: `float:1e`, want: &syntaxError{line: 1, col: 7}, + }, { + desc: "FloatPositiveMissingExponent", + msg: `float:1e+`, + want: &syntaxError{line: 1, col: 7}, }, { desc: "UnterminatedComment", msg: `/*`, @@ -551,6 +551,18 @@ func TestUnmarshal_Invalid(t *testing.T) { int:12345; # oops typo `, want: &syntaxError{line: 4, col: 10}, + }, { + desc: "OutOfRange", + msg: `int:20000000000000000000`, + want: &syntaxError{line: 1, col: 5}, + }, { + desc: "FloatRange", + msg: `float:1e309`, + want: &syntaxError{line: 1, col: 7}, + }, { + desc: "IntLetter", + msg: `int: 1A`, + want: &syntaxError{line: 1, col: 6}, }} { t.Run(tc.desc, func(t *testing.T) { t.Parallel() @@ -926,6 +938,9 @@ from string'`, `nested_repeated: [[1]]`, `float:1e`, `/*`, + `bytes:100000000000000000000`, + `float:1e700`, + `float:1A000`, } { f.Add([]byte(tc)) } -- cgit v1.3.1