@@ -234,6 +234,7 @@ type decodeState struct {
234
234
235
235
savedStrictErrors []error
236
236
seenStrictErrors map [string ]struct {}
237
+ strictFieldStack []string
237
238
238
239
caseSensitive bool
239
240
@@ -261,6 +262,8 @@ func (d *decodeState) init(data []byte) *decodeState {
261
262
// Reuse the allocated space for the FieldStack slice.
262
263
d .errorContext .FieldStack = d .errorContext .FieldStack [:0 ]
263
264
}
265
+ // Reuse the allocated space for the strict FieldStack slice.
266
+ d .strictFieldStack = d .strictFieldStack [:0 ]
264
267
return d
265
268
}
266
269
@@ -555,6 +558,12 @@ func (d *decodeState) array(v reflect.Value) error {
555
558
break
556
559
}
557
560
561
+ origStrictFieldStackLen := len (d .strictFieldStack )
562
+ defer func () {
563
+ // Reset to original length and reuse the allocated space for the strict FieldStack slice.
564
+ d .strictFieldStack = d .strictFieldStack [:origStrictFieldStackLen ]
565
+ }()
566
+
558
567
i := 0
559
568
for {
560
569
// Look ahead for ] - can only happen on first iteration.
@@ -580,6 +589,7 @@ func (d *decodeState) array(v reflect.Value) error {
580
589
}
581
590
}
582
591
592
+ d .appendStrictFieldStackIndex (i )
583
593
if i < v .Len () {
584
594
// Decode into element.
585
595
if err := d .value (v .Index (i )); err != nil {
@@ -591,6 +601,8 @@ func (d *decodeState) array(v reflect.Value) error {
591
601
return err
592
602
}
593
603
}
604
+ // Reset to original length and reuse the allocated space for the strict FieldStack slice.
605
+ d .strictFieldStack = d .strictFieldStack [:origStrictFieldStackLen ]
594
606
i ++
595
607
596
608
// Next token must be , or ].
@@ -683,7 +695,7 @@ func (d *decodeState) object(v reflect.Value) error {
683
695
seenKeys = map [string ]struct {}{}
684
696
}
685
697
if _ , seen := seenKeys [fieldName ]; seen {
686
- d .saveStrictError (fmt . Errorf ("duplicate field %q " , fieldName ))
698
+ d .saveStrictError (d . newFieldError ("duplicate field" , fieldName ))
687
699
} else {
688
700
seenKeys [fieldName ] = struct {}{}
689
701
}
@@ -699,7 +711,7 @@ func (d *decodeState) object(v reflect.Value) error {
699
711
var seenKeys uint64
700
712
checkDuplicateField = func (fieldNameIndex int , fieldName string ) {
701
713
if seenKeys & (1 << fieldNameIndex ) != 0 {
702
- d .saveStrictError (fmt . Errorf ("duplicate field %q " , fieldName ))
714
+ d .saveStrictError (d . newFieldError ("duplicate field" , fieldName ))
703
715
} else {
704
716
seenKeys = seenKeys | (1 << fieldNameIndex )
705
717
}
@@ -712,7 +724,7 @@ func (d *decodeState) object(v reflect.Value) error {
712
724
seenIndexes = make ([]bool , len (fields .list ))
713
725
}
714
726
if seenIndexes [fieldNameIndex ] {
715
- d .saveStrictError (fmt . Errorf ("duplicate field %q " , fieldName ))
727
+ d .saveStrictError (d . newFieldError ("duplicate field" , fieldName ))
716
728
} else {
717
729
seenIndexes [fieldNameIndex ] = true
718
730
}
@@ -732,6 +744,7 @@ func (d *decodeState) object(v reflect.Value) error {
732
744
if d .errorContext != nil {
733
745
origErrorContext = * d .errorContext
734
746
}
747
+ origStrictFieldStackLen := len (d .strictFieldStack )
735
748
736
749
for {
737
750
// Read opening " of string key or closing }.
@@ -768,6 +781,7 @@ func (d *decodeState) object(v reflect.Value) error {
768
781
if checkDuplicateField != nil {
769
782
checkDuplicateField (0 , string (key ))
770
783
}
784
+ d .appendStrictFieldStackKey (string (key ))
771
785
} else {
772
786
var f * field
773
787
if i , ok := fields .nameIndex [string (key )]; ok {
@@ -820,8 +834,9 @@ func (d *decodeState) object(v reflect.Value) error {
820
834
}
821
835
d .errorContext .FieldStack = append (d .errorContext .FieldStack , f .name )
822
836
d .errorContext .Struct = t
837
+ d .appendStrictFieldStackKey (f .name )
823
838
} else if d .disallowUnknownFields {
824
- d .saveStrictError (fmt . Errorf ("unknown field %q " , key ))
839
+ d .saveStrictError (d . newFieldError ("unknown field" , string ( key ) ))
825
840
}
826
841
}
827
842
@@ -905,6 +920,8 @@ func (d *decodeState) object(v reflect.Value) error {
905
920
d .errorContext .FieldStack = d .errorContext .FieldStack [:len (origErrorContext .FieldStack )]
906
921
d .errorContext .Struct = origErrorContext .Struct
907
922
}
923
+ // Reset to original length and reuse the allocated space for the strict FieldStack slice.
924
+ d .strictFieldStack = d .strictFieldStack [:origStrictFieldStackLen ]
908
925
if d .opcode == scanEndObject {
909
926
break
910
927
}
@@ -1141,6 +1158,12 @@ func (d *decodeState) valueInterface() (val interface{}) {
1141
1158
1142
1159
// arrayInterface is like array but returns []interface{}.
1143
1160
func (d * decodeState ) arrayInterface () []interface {} {
1161
+ origStrictFieldStackLen := len (d .strictFieldStack )
1162
+ defer func () {
1163
+ // Reset to original length and reuse the allocated space for the strict FieldStack slice.
1164
+ d .strictFieldStack = d .strictFieldStack [:origStrictFieldStackLen ]
1165
+ }()
1166
+
1144
1167
var v = make ([]interface {}, 0 )
1145
1168
for {
1146
1169
// Look ahead for ] - can only happen on first iteration.
@@ -1149,7 +1172,10 @@ func (d *decodeState) arrayInterface() []interface{} {
1149
1172
break
1150
1173
}
1151
1174
1175
+ d .appendStrictFieldStackIndex (len (v ))
1152
1176
v = append (v , d .valueInterface ())
1177
+ // Reset to original length and reuse the allocated space for the strict FieldStack slice.
1178
+ d .strictFieldStack = d .strictFieldStack [:origStrictFieldStackLen ]
1153
1179
1154
1180
// Next token must be , or ].
1155
1181
if d .opcode == scanSkipSpace {
@@ -1167,6 +1193,12 @@ func (d *decodeState) arrayInterface() []interface{} {
1167
1193
1168
1194
// objectInterface is like object but returns map[string]interface{}.
1169
1195
func (d * decodeState ) objectInterface () map [string ]interface {} {
1196
+ origStrictFieldStackLen := len (d .strictFieldStack )
1197
+ defer func () {
1198
+ // Reset to original length and reuse the allocated space for the strict FieldStack slice.
1199
+ d .strictFieldStack = d .strictFieldStack [:origStrictFieldStackLen ]
1200
+ }()
1201
+
1170
1202
m := make (map [string ]interface {})
1171
1203
for {
1172
1204
// Read opening " of string key or closing }.
@@ -1199,12 +1231,15 @@ func (d *decodeState) objectInterface() map[string]interface{} {
1199
1231
1200
1232
if d .disallowDuplicateFields {
1201
1233
if _ , exists := m [key ]; exists {
1202
- d .saveStrictError (fmt . Errorf ("duplicate field %q " , key ))
1234
+ d .saveStrictError (d . newFieldError ("duplicate field" , key ))
1203
1235
}
1204
1236
}
1205
1237
1206
1238
// Read value.
1239
+ d .appendStrictFieldStackKey (key )
1207
1240
m [key ] = d .valueInterface ()
1241
+ // Reset to original length and reuse the allocated space for the strict FieldStack slice.
1242
+ d .strictFieldStack = d .strictFieldStack [:origStrictFieldStackLen ]
1208
1243
1209
1244
// Next token must be , or }.
1210
1245
if d .opcode == scanSkipSpace {
0 commit comments