From 29dfb15b53749522b0b924077323a22b96b99bbe Mon Sep 17 00:00:00 2001 From: "liuqiang.06" Date: Tue, 3 Dec 2024 09:52:35 +0800 Subject: [PATCH] fix(aarch64): skip number for object value --- decode_test.go | 13 +++++++++++++ internal/decoder/optdec/helper.go | 9 +++++++-- internal/decoder/optdec/node.go | 8 ++++---- internal/decoder/optdec/stringopts.go | 4 ++-- 4 files changed, 26 insertions(+), 8 deletions(-) diff --git a/decode_test.go b/decode_test.go index acee43790..53bcb3fd4 100644 --- a/decode_test.go +++ b/decode_test.go @@ -1009,6 +1009,8 @@ var unmarshalTests = []unmarshalTest{ ptr: new(map[string]json.Number), err: fmt.Errorf("json: invalid number literal, trying to unmarshal %q into Number", `"invalid"`), }, + + // UTF-8 and string validation tests {in: `\u`, ptr: new(interface{}), err: fmt.Errorf("json: invald char"), validateString: true}, {in: `\u`, ptr: new(string), err: fmt.Errorf("json: invald char"), validateString: true}, @@ -1020,6 +1022,17 @@ var unmarshalTests = []unmarshalTest{ {in: "\"\x00\"", ptr: new(string), out: "\x00", validateString: false}, {in: "\"\xff\"", ptr: new(interface{}), out: interface{}("\xff"), validateString: false}, {in: "\"\xff\"", ptr: new(string), out: "\xff", validateString: false}, + + // cases found by fuzz + { + in: `{"H":{"A": {}}}`, + ptr: new(struct { + F0 struct { + F1 json.Number "json:\"a,omitempty\"" + } "json:\"H,\"" + }), + err: fmt.Errorf("Mismatch type json.Number with value object.."), + }, } func trim(b []byte) []byte { diff --git a/internal/decoder/optdec/helper.go b/internal/decoder/optdec/helper.go index 143fa6708..7bf8a8f39 100644 --- a/internal/decoder/optdec/helper.go +++ b/internal/decoder/optdec/helper.go @@ -10,7 +10,7 @@ import ( ) -func SkipNumberFast(json string, start int) (int, error) { +func SkipNumberFast(json string, start int) (int, bool) { // find the number ending, we pasred in native, it alway valid pos := start for pos < len(json) && json[pos] != ']' && json[pos] != '}' && json[pos] != ',' { @@ -20,7 +20,12 @@ func SkipNumberFast(json string, start int) (int, error) { break } } - return pos, nil + + // if not found number, return false + if pos == start { + return pos, false + } + return pos, true } diff --git a/internal/decoder/optdec/node.go b/internal/decoder/optdec/node.go index 690fbd5d4..3f60a3368 100644 --- a/internal/decoder/optdec/node.go +++ b/internal/decoder/optdec/node.go @@ -401,9 +401,9 @@ func (val Node) ParseNumber(ctx *Context) (json.Number, bool) { return json.Number(""), true } - end, err := SkipNumberFast(s, 0) + end, ok := SkipNumberFast(s, 0) // has error or trailing chars - if err != nil || end != len(s) { + if !ok || end != len(s) { return json.Number(""), false } return json.Number(s), true @@ -531,8 +531,8 @@ func (val Node) NonstrAsNumber(ctx *Context) (json.Number, bool) { } start := val.Position() - end, err := SkipNumberFast(ctx.Parser.Json, start) - if err != nil { + end, ok := SkipNumberFast(ctx.Parser.Json, start) + if !ok { return "", false } return json.Number(ctx.Parser.Json[start:end]), true diff --git a/internal/decoder/optdec/stringopts.go b/internal/decoder/optdec/stringopts.go index 627b5ebea..5af8c97e2 100644 --- a/internal/decoder/optdec/stringopts.go +++ b/internal/decoder/optdec/stringopts.go @@ -349,9 +349,9 @@ func (d *numberStringDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context return error_mismatch(node, ctx, jsonNumberType) } - end, err := SkipNumberFast(s, 0) + end, ok := SkipNumberFast(s, 0) // has error or trailing chars - if err != nil || end != len(s) { + if !ok || end != len(s) { return error_mismatch(node, ctx, jsonNumberType) }