Skip to content

Commit e377047

Browse files
authored
Merge branch 'master' into fix/goccy#417
2 parents 2ce36cd + b68305f commit e377047

File tree

4 files changed

+64
-17
lines changed

4 files changed

+64
-17
lines changed

decode_test.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4015,3 +4015,18 @@ func TestIssue408(t *testing.T) {
40154015
t.Fatal(err)
40164016
}
40174017
}
4018+
4019+
func TestIssue429(t *testing.T) {
4020+
var x struct {
4021+
N int32
4022+
}
4023+
for _, b := range []string{
4024+
`{"\u"`,
4025+
`{"\u0"`,
4026+
`{"\u00"`,
4027+
} {
4028+
if err := json.Unmarshal([]byte(b), &x); err == nil {
4029+
t.Errorf("unexpected success")
4030+
}
4031+
}
4032+
}

encode_test.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2645,3 +2645,18 @@ func TestIssue417(t *testing.T) {
26452645
assertEq(t, "key b", "b", y["b"])
26462646
assertEq(t, "key a", "a", y["a"])
26472647
}
2648+
2649+
func TestIssue426(t *testing.T) {
2650+
type I interface {
2651+
Foo()
2652+
}
2653+
type A struct {
2654+
I
2655+
Val string
2656+
}
2657+
var s A
2658+
s.Val = "456"
2659+
2660+
b, _ := json.Marshal(s)
2661+
assertEq(t, "unexpected result", `{"I":null,"Val":"456"}`, string(b))
2662+
}

internal/decoder/struct.go

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -158,49 +158,53 @@ func (d *structDecoder) tryOptimize() {
158158
}
159159

160160
// decode from '\uXXXX'
161-
func decodeKeyCharByUnicodeRune(buf []byte, cursor int64) ([]byte, int64) {
161+
func decodeKeyCharByUnicodeRune(buf []byte, cursor int64) ([]byte, int64, error) {
162162
const defaultOffset = 4
163163
const surrogateOffset = 6
164164

165+
if cursor+defaultOffset >= int64(len(buf)) {
166+
return nil, 0, errors.ErrUnexpectedEndOfJSON("escaped string", cursor)
167+
}
168+
165169
r := unicodeToRune(buf[cursor : cursor+defaultOffset])
166170
if utf16.IsSurrogate(r) {
167171
cursor += defaultOffset
168172
if cursor+surrogateOffset >= int64(len(buf)) || buf[cursor] != '\\' || buf[cursor+1] != 'u' {
169-
return []byte(string(unicode.ReplacementChar)), cursor + defaultOffset - 1
173+
return []byte(string(unicode.ReplacementChar)), cursor + defaultOffset - 1, nil
170174
}
171175
cursor += 2
172176
r2 := unicodeToRune(buf[cursor : cursor+defaultOffset])
173177
if r := utf16.DecodeRune(r, r2); r != unicode.ReplacementChar {
174-
return []byte(string(r)), cursor + defaultOffset - 1
178+
return []byte(string(r)), cursor + defaultOffset - 1, nil
175179
}
176180
}
177-
return []byte(string(r)), cursor + defaultOffset - 1
181+
return []byte(string(r)), cursor + defaultOffset - 1, nil
178182
}
179183

180-
func decodeKeyCharByEscapedChar(buf []byte, cursor int64) ([]byte, int64) {
184+
func decodeKeyCharByEscapedChar(buf []byte, cursor int64) ([]byte, int64, error) {
181185
c := buf[cursor]
182186
cursor++
183187
switch c {
184188
case '"':
185-
return []byte{'"'}, cursor
189+
return []byte{'"'}, cursor, nil
186190
case '\\':
187-
return []byte{'\\'}, cursor
191+
return []byte{'\\'}, cursor, nil
188192
case '/':
189-
return []byte{'/'}, cursor
193+
return []byte{'/'}, cursor, nil
190194
case 'b':
191-
return []byte{'\b'}, cursor
195+
return []byte{'\b'}, cursor, nil
192196
case 'f':
193-
return []byte{'\f'}, cursor
197+
return []byte{'\f'}, cursor, nil
194198
case 'n':
195-
return []byte{'\n'}, cursor
199+
return []byte{'\n'}, cursor, nil
196200
case 'r':
197-
return []byte{'\r'}, cursor
201+
return []byte{'\r'}, cursor, nil
198202
case 't':
199-
return []byte{'\t'}, cursor
203+
return []byte{'\t'}, cursor, nil
200204
case 'u':
201205
return decodeKeyCharByUnicodeRune(buf, cursor)
202206
}
203-
return nil, cursor
207+
return nil, cursor, nil
204208
}
205209

206210
func decodeKeyByBitmapUint8(d *structDecoder, buf []byte, cursor int64) (int64, *structFieldSet, error) {
@@ -242,7 +246,10 @@ func decodeKeyByBitmapUint8(d *structDecoder, buf []byte, cursor int64) (int64,
242246
return 0, nil, errors.ErrUnexpectedEndOfJSON("string", cursor)
243247
case '\\':
244248
cursor++
245-
chars, nextCursor := decodeKeyCharByEscapedChar(buf, cursor)
249+
chars, nextCursor, err := decodeKeyCharByEscapedChar(buf, cursor)
250+
if err != nil {
251+
return 0, nil, err
252+
}
246253
for _, c := range chars {
247254
curBit &= bitmap[keyIdx][largeToSmallTable[c]]
248255
if curBit == 0 {
@@ -305,7 +312,10 @@ func decodeKeyByBitmapUint16(d *structDecoder, buf []byte, cursor int64) (int64,
305312
return 0, nil, errors.ErrUnexpectedEndOfJSON("string", cursor)
306313
case '\\':
307314
cursor++
308-
chars, nextCursor := decodeKeyCharByEscapedChar(buf, cursor)
315+
chars, nextCursor, err := decodeKeyCharByEscapedChar(buf, cursor)
316+
if err != nil {
317+
return 0, nil, err
318+
}
309319
for _, c := range chars {
310320
curBit &= bitmap[keyIdx][largeToSmallTable[c]]
311321
if curBit == 0 {

internal/encoder/compiler.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -617,6 +617,13 @@ func (c *Compiler) structCode(typ *runtime.Type, isPtr bool) (*StructCode, error
617617
return code, nil
618618
}
619619

620+
func toElemType(t *runtime.Type) *runtime.Type {
621+
for t.Kind() == reflect.Ptr {
622+
t = t.Elem()
623+
}
624+
return t
625+
}
626+
620627
func (c *Compiler) structFieldCode(structCode *StructCode, tag *runtime.StructTag, isPtr, isOnlyOneFirstField bool) (*StructFieldCode, error) {
621628
field := tag.Field
622629
fieldType := runtime.Type2RType(field.Type)
@@ -626,7 +633,7 @@ func (c *Compiler) structFieldCode(structCode *StructCode, tag *runtime.StructTa
626633
key: tag.Key,
627634
tag: tag,
628635
offset: field.Offset,
629-
isAnonymous: field.Anonymous && !tag.IsTaggedKey,
636+
isAnonymous: field.Anonymous && !tag.IsTaggedKey && toElemType(fieldType).Kind() == reflect.Struct,
630637
isTaggedKey: tag.IsTaggedKey,
631638
isNilableType: c.isNilableType(fieldType),
632639
isNilCheck: true,

0 commit comments

Comments
 (0)