-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathjsondecoder.go
More file actions
43 lines (36 loc) · 1.16 KB
/
jsondecoder.go
File metadata and controls
43 lines (36 loc) · 1.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
package jsondecoder
import (
"bytes"
"encoding/json"
"errors"
"strings"
)
var (
ErrExtraDataAfterDecoding = errors.New("extra data after decoding")
ErrUnknownField = errors.New("unknown field in JSON input")
)
// UnmarshalDisallowUnknownFields parses the JSON-encoded data
// and stores the result in the value pointed to by v like json.Unmarshal,
// but with DisallowUnknownFields() set by default for extra security.
func UnmarshalDisallowUnknownFields(data []byte, v any) error {
dec := json.NewDecoder(bytes.NewReader(data))
dec.DisallowUnknownFields()
if err := dec.Decode(v); err != nil {
// Ugly, but the encoding/json uses a dynamic error here
if strings.HasPrefix(err.Error(), "json: unknown field ") {
return ErrUnknownField
}
// we want to provide an alternative implementation, with the
// unwrapped errors
//nolint:wrapcheck
return err
}
// Check if there's any data left in the decoder's buffer.
// This ensures that there's no extra JSON after the main object
// otherwise something like '{"foo": 1}{"bar": 2}' or even '{}garbage'
// will not error out.
if dec.More() {
return ErrExtraDataAfterDecoding
}
return nil
}