This commit is contained in:
Fabio Nascimento Brandão 2024-11-22 06:54:47 +00:00 committed by GitHub
commit 42a5eaf686
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 60 additions and 3 deletions

View File

@ -4057,3 +4057,28 @@ func TestIssue429(t *testing.T) {
} }
} }
} }
func TestIssue464(t *testing.T) {
type testStruct struct {
Name string
Value int
Description string
}
jsonValue := []byte("{\"Name\":\"Test Name\",\"Value\":\"incorrect\",\"Description\":\"Test Description\"}")
jsonData := testStruct{}
err := stdjson.Unmarshal(jsonValue, &jsonData)
assertIsType(t, "Incorrect error type stdjson", &stdjson.UnmarshalTypeError{}, err)
gojsonData := testStruct{}
err = json.Unmarshal(jsonValue, &gojsonData)
assertIsType(t, "Incorrect error type go-json", &json.UnmarshalTypeError{}, err)
assertEq(t, "Incorrect name stdjson", "Test Name", jsonData.Name)
assertEq(t, "Incorrect name go-json", "Test Name", gojsonData.Name)
assertEq(t, "Incorrect value stdjson", 0, jsonData.Value)
assertEq(t, "Incorrect value go-json", 0, gojsonData.Value)
assertEq(t, "Incorrect description stdjson", "Test Description", jsonData.Description)
assertEq(t, "Incorrect description go-json", "Test Description", gojsonData.Description)
}

View File

@ -1,6 +1,9 @@
package json_test package json_test
import "testing" import (
"reflect"
"testing"
)
func assertErr(t *testing.T, err error) { func assertErr(t *testing.T, err error) {
t.Helper() t.Helper()
@ -22,3 +25,12 @@ func assertNeq(t *testing.T, msg string, exp interface{}, act interface{}) {
t.Fatalf("failed to test for %s. expected value is not [%v] but got same value", msg, act) t.Fatalf("failed to test for %s. expected value is not [%v] but got same value", msg, act)
} }
} }
func assertIsType(t *testing.T, msg string, exp interface{}, act interface{}) {
t.Helper()
expType := reflect.TypeOf(exp)
actType := reflect.TypeOf(act)
if expType != actType {
t.Fatalf("failed to test for %s. exp[%v] bug act=[%v]", msg, expType, actType)
}
}

View File

@ -778,6 +778,7 @@ func (d *structDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsaf
if firstWin { if firstWin {
seenFields = make(map[int]struct{}, d.fieldUniqueNameNum) seenFields = make(map[int]struct{}, d.fieldUniqueNameNum)
} }
var lastTypeMismatchError error
for { for {
c, field, err := d.keyDecoder(d, buf, cursor) c, field, err := d.keyDecoder(d, buf, cursor)
if err != nil { if err != nil {
@ -805,7 +806,15 @@ func (d *structDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsaf
} else { } else {
c, err := field.dec.Decode(ctx, cursor, depth, unsafe.Pointer(uintptr(p)+field.offset)) c, err := field.dec.Decode(ctx, cursor, depth, unsafe.Pointer(uintptr(p)+field.offset))
if err != nil { if err != nil {
return 0, err if _, ok := err.(*errors.UnmarshalTypeError); ok {
lastTypeMismatchError = err
c, err = skipValue(buf, cursor, depth)
if err != nil {
return 0, err
}
} else {
return 0, err
}
} }
cursor = c cursor = c
seenFieldNum++ seenFieldNum++
@ -817,7 +826,15 @@ func (d *structDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsaf
} else { } else {
c, err := field.dec.Decode(ctx, cursor, depth, unsafe.Pointer(uintptr(p)+field.offset)) c, err := field.dec.Decode(ctx, cursor, depth, unsafe.Pointer(uintptr(p)+field.offset))
if err != nil { if err != nil {
return 0, err if _, ok := err.(*errors.UnmarshalTypeError); ok {
lastTypeMismatchError = err
c, err = skipValue(buf, cursor, depth)
if err != nil {
return 0, err
}
} else {
return 0, err
}
} }
cursor = c cursor = c
} }
@ -831,6 +848,9 @@ func (d *structDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsaf
cursor = skipWhiteSpace(buf, cursor) cursor = skipWhiteSpace(buf, cursor)
if char(b, cursor) == '}' { if char(b, cursor) == '}' {
cursor++ cursor++
if lastTypeMismatchError != nil {
return 0, lastTypeMismatchError
}
return cursor, nil return cursor, nil
} }
if char(b, cursor) != ',' { if char(b, cursor) != ',' {