1
2
3
4
5
6
7 package json
8
9 import (
10 "cmp"
11 "errors"
12 "fmt"
13 "io"
14 "reflect"
15 "strconv"
16 "strings"
17 "sync"
18
19 "encoding/json/internal/jsonflags"
20 "encoding/json/internal/jsonopts"
21 "encoding/json/internal/jsonwire"
22 "encoding/json/jsontext"
23 )
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 var ErrUnknownName = errors.New("unknown object member name")
41
42 const errorPrefix = "json: "
43
44 func isSemanticError(err error) bool {
45 _, ok := err.(*SemanticError)
46 return ok
47 }
48
49 func isSyntacticError(err error) bool {
50 _, ok := err.(*jsontext.SyntacticError)
51 return ok
52 }
53
54
55
56
57
58 func isFatalError(err error, flags jsonflags.Flags) bool {
59 return !flags.Get(jsonflags.ReportErrorsWithLegacySemantics) ||
60 isSyntacticError(err) || export.IsIOError(err)
61 }
62
63
64
65
66
67
68
69
70
71
72 type SemanticError struct {
73 requireKeyedLiterals
74 nonComparable
75
76 action string
77
78
79 ByteOffset int64
80
81
82 JSONPointer jsontext.Pointer
83
84
85 JSONKind jsontext.Kind
86
87
88 JSONValue jsontext.Value
89
90 GoType reflect.Type
91
92
93 Err error
94 }
95
96
97 type coder interface {
98 StackPointer() jsontext.Pointer
99 Options() Options
100 }
101
102
103
104
105
106
107
108
109 func newInvalidFormatError(c coder, t reflect.Type) error {
110 err := fmt.Errorf("invalid format flag %q", c.Options().(*jsonopts.Struct).Format)
111 switch c := c.(type) {
112 case *jsontext.Encoder:
113 err = newMarshalErrorBefore(c, t, err)
114 case *jsontext.Decoder:
115 err = newUnmarshalErrorBeforeWithSkipping(c, t, err)
116 }
117 return err
118 }
119
120
121
122 func newMarshalErrorBefore(e *jsontext.Encoder, t reflect.Type, err error) error {
123 return &SemanticError{action: "marshal", GoType: t, Err: toUnexpectedEOF(err),
124 ByteOffset: e.OutputOffset() + int64(export.Encoder(e).CountNextDelimWhitespace()),
125 JSONPointer: jsontext.Pointer(export.Encoder(e).AppendStackPointer(nil, +1))}
126 }
127
128
129
130
131
132
133
134 func newUnmarshalErrorBefore(d *jsontext.Decoder, t reflect.Type, err error) error {
135 var k jsontext.Kind
136 if export.Decoder(d).Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
137 k = d.PeekKind()
138 }
139 return &SemanticError{action: "unmarshal", GoType: t, Err: toUnexpectedEOF(err),
140 ByteOffset: d.InputOffset() + int64(export.Decoder(d).CountNextDelimWhitespace()),
141 JSONPointer: jsontext.Pointer(export.Decoder(d).AppendStackPointer(nil, +1)),
142 JSONKind: k}
143 }
144
145
146
147
148 func newUnmarshalErrorBeforeWithSkipping(d *jsontext.Decoder, t reflect.Type, err error) error {
149 err = newUnmarshalErrorBefore(d, t, err)
150 if export.Decoder(d).Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
151 if err2 := export.Decoder(d).SkipValue(); err2 != nil {
152 return err2
153 }
154 }
155 return err
156 }
157
158
159
160 func newUnmarshalErrorAfter(d *jsontext.Decoder, t reflect.Type, err error) error {
161 tokOrVal := export.Decoder(d).PreviousTokenOrValue()
162 byteOffset := d.InputOffset() - int64(len(tokOrVal))
163 if export.Decoder(d).Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
164
165 if k := jsontext.Value(tokOrVal).Kind(); k == '[' || k == '{' {
166 byteOffset++
167 } else {
168 byteOffset += int64(len(tokOrVal))
169 }
170 }
171 return &SemanticError{action: "unmarshal", GoType: t, Err: toUnexpectedEOF(err),
172 ByteOffset: byteOffset,
173 JSONPointer: jsontext.Pointer(export.Decoder(d).AppendStackPointer(nil, -1)),
174 JSONKind: jsontext.Value(tokOrVal).Kind()}
175 }
176
177
178
179
180 func newUnmarshalErrorAfterWithValue(d *jsontext.Decoder, t reflect.Type, err error) error {
181 serr := newUnmarshalErrorAfter(d, t, err).(*SemanticError)
182 if serr.JSONKind == '"' || serr.JSONKind == '0' {
183 serr.JSONValue = jsontext.Value(export.Decoder(d).PreviousTokenOrValue()).Clone()
184 }
185 return serr
186 }
187
188
189
190
191 func newUnmarshalErrorAfterWithSkipping(d *jsontext.Decoder, t reflect.Type, err error) error {
192 err = newUnmarshalErrorAfter(d, t, err)
193 if export.Decoder(d).Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
194 if err2 := export.Decoder(d).SkipValueRemainder(); err2 != nil {
195 return err2
196 }
197 }
198 return err
199 }
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215 func newSemanticErrorWithPosition(c coder, t reflect.Type, prevDepth int, prevLength int64, err error) error {
216 serr, _ := err.(*SemanticError)
217 if serr == nil {
218 serr = &SemanticError{Err: err}
219 }
220 serr.Err = toUnexpectedEOF(serr.Err)
221 var currDepth int
222 var currLength int64
223 var coderState interface{ AppendStackPointer([]byte, int) []byte }
224 var offset int64
225 switch c := c.(type) {
226 case *jsontext.Encoder:
227 e := export.Encoder(c)
228 serr.action = cmp.Or(serr.action, "marshal")
229 currDepth, currLength = e.Tokens.DepthLength()
230 offset = c.OutputOffset() + int64(export.Encoder(c).CountNextDelimWhitespace())
231 coderState = e
232 case *jsontext.Decoder:
233 d := export.Decoder(c)
234 serr.action = cmp.Or(serr.action, "unmarshal")
235 currDepth, currLength = d.Tokens.DepthLength()
236 tokOrVal := d.PreviousTokenOrValue()
237 offset = c.InputOffset() - int64(len(tokOrVal))
238 if (prevDepth == currDepth && prevLength == currLength) || len(tokOrVal) == 0 {
239
240
241 offset = c.InputOffset() + int64(export.Decoder(c).CountNextDelimWhitespace())
242 }
243 coderState = d
244 }
245 serr.ByteOffset = cmp.Or(serr.ByteOffset, offset)
246 if serr.JSONPointer == "" {
247 where := 0
248 switch {
249 case prevDepth == currDepth && prevLength+0 == currLength:
250 where = +1
251 case prevDepth == currDepth && prevLength+1 == currLength:
252 where = -1
253 }
254 serr.JSONPointer = jsontext.Pointer(coderState.AppendStackPointer(nil, where))
255 }
256 serr.GoType = cmp.Or(serr.GoType, t)
257 return serr
258 }
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300 func collapseSemanticErrors(err error) error {
301 if serr1, ok := err.(*SemanticError); ok {
302 if serr2, ok := serr1.Err.(*SemanticError); ok {
303 serr2.ByteOffset = serr1.ByteOffset + serr2.ByteOffset
304 serr2.JSONPointer = serr1.JSONPointer + serr2.JSONPointer
305 *serr1 = *serr2
306 }
307 }
308 return err
309 }
310
311 func wrapErrUnsupported(err error, what string) error {
312 if errors.Is(err, errors.ErrUnsupported) {
313 return errors.New(what + " may not return errors.ErrUnsupported")
314 }
315 return err
316 }
317
318
319
320
321
322
323
324 var errorModalVerb = sync.OnceValue(func() string {
325 for phrase := range map[string]struct{}{"cannot": {}, "unable to": {}} {
326 return phrase
327 }
328 return ""
329 })
330
331 func (e *SemanticError) Error() string {
332 var sb strings.Builder
333 sb.WriteString(errorPrefix)
334 sb.WriteString(errorModalVerb())
335
336
337 var preposition string
338 switch e.action {
339 case "marshal":
340 sb.WriteString(" marshal")
341 preposition = " from"
342 case "unmarshal":
343 sb.WriteString(" unmarshal")
344 preposition = " into"
345 default:
346 sb.WriteString(" handle")
347 preposition = " with"
348 }
349
350
351 switch e.JSONKind {
352 case 'n':
353 sb.WriteString(" JSON null")
354 case 'f', 't':
355 sb.WriteString(" JSON boolean")
356 case '"':
357 sb.WriteString(" JSON string")
358 case '0':
359 sb.WriteString(" JSON number")
360 case '{', '}':
361 sb.WriteString(" JSON object")
362 case '[', ']':
363 sb.WriteString(" JSON array")
364 default:
365 if e.action == "" {
366 preposition = ""
367 }
368 }
369 if len(e.JSONValue) > 0 && len(e.JSONValue) < 100 {
370 sb.WriteByte(' ')
371 sb.Write(e.JSONValue)
372 }
373
374
375 if e.GoType != nil {
376 typeString := e.GoType.String()
377 if len(typeString) > 100 {
378
379
380
381
382
383 typeString = e.GoType.Kind().String()
384 if e.GoType.Kind() == reflect.Struct && e.GoType.Name() == "" {
385 for i := range e.GoType.NumField() {
386 if pkgPath := e.GoType.Field(i).PkgPath; pkgPath != "" {
387 typeString = pkgPath[strings.LastIndexByte(pkgPath, '/')+len("/"):] + ".struct"
388 break
389 }
390 }
391 }
392 }
393 sb.WriteString(preposition)
394 sb.WriteString(" Go ")
395 sb.WriteString(typeString)
396 }
397
398
399 if e.Err == ErrUnknownName {
400 sb.WriteString(": ")
401 sb.WriteString(ErrUnknownName.Error())
402 sb.WriteString(" ")
403 sb.WriteString(strconv.Quote(e.JSONPointer.LastToken()))
404 if parent := e.JSONPointer.Parent(); parent != "" {
405 sb.WriteString(" within ")
406 sb.WriteString(strconv.Quote(jsonwire.TruncatePointer(string(parent), 100)))
407 }
408 return sb.String()
409 }
410
411
412
413 switch serr, _ := e.Err.(*jsontext.SyntacticError); {
414 case e.JSONPointer != "":
415 if serr == nil || !e.JSONPointer.Contains(serr.JSONPointer) {
416 sb.WriteString(" within ")
417 sb.WriteString(strconv.Quote(jsonwire.TruncatePointer(string(e.JSONPointer), 100)))
418 }
419 case e.ByteOffset > 0:
420 if serr == nil || !(e.ByteOffset <= serr.ByteOffset) {
421 sb.WriteString(" after offset ")
422 sb.WriteString(strconv.FormatInt(e.ByteOffset, 10))
423 }
424 }
425
426
427 if e.Err != nil {
428 errString := e.Err.Error()
429 if isSyntacticError(e.Err) {
430 errString = strings.TrimPrefix(errString, "jsontext: ")
431 }
432 sb.WriteString(": ")
433 sb.WriteString(errString)
434 }
435
436 return sb.String()
437 }
438
439 func (e *SemanticError) Unwrap() error {
440 return e.Err
441 }
442
443 func newDuplicateNameError(ptr jsontext.Pointer, quotedName []byte, offset int64) error {
444 if quotedName != nil {
445 name, _ := jsonwire.AppendUnquote(nil, quotedName)
446 ptr = ptr.AppendToken(string(name))
447 }
448 return &jsontext.SyntacticError{
449 ByteOffset: offset,
450 JSONPointer: ptr,
451 Err: jsontext.ErrDuplicateName,
452 }
453 }
454
455
456 func toUnexpectedEOF(err error) error {
457 if err == io.EOF {
458 return io.ErrUnexpectedEOF
459 }
460 return err
461 }
462
View as plain text