diff --git a/common/json/internal/contextjson/unmarshal.go b/common/json/internal/contextjson/unmarshal.go new file mode 100644 index 0000000..2940539 --- /dev/null +++ b/common/json/internal/contextjson/unmarshal.go @@ -0,0 +1,12 @@ +package json + +func UnmarshalDisallowUnknownFields(data []byte, v any) error { + var d decodeState + d.disallowUnknownFields = true + err := checkValid(data, &d.scan) + if err != nil { + return err + } + d.init(data) + return d.unmarshal(v) +} diff --git a/common/json/unmarshal.go b/common/json/unmarshal.go index fa6452d..7505ebc 100644 --- a/common/json/unmarshal.go +++ b/common/json/unmarshal.go @@ -2,6 +2,7 @@ package json import ( "bytes" + "errors" "strings" "github.com/sagernet/sing/common" @@ -15,7 +16,8 @@ func UnmarshalExtended[T any](content []byte) (T, error) { if err == nil { return value, err } - if syntaxError, isSyntaxError := err.(*SyntaxError); isSyntaxError { + var syntaxError *SyntaxError + if errors.As(err, &syntaxError) { prefix := string(content[:syntaxError.Offset]) row := strings.Count(prefix, "\n") + 1 column := len(prefix) - strings.LastIndex(prefix, "\n") - 1 diff --git a/common/json/unmarshal_context.go b/common/json/unmarshal_context.go new file mode 100644 index 0000000..01f7962 --- /dev/null +++ b/common/json/unmarshal_context.go @@ -0,0 +1,9 @@ +//go:build go1.20 && !without_contextjson + +package json + +import ( + json "github.com/sagernet/sing/common/json/internal/contextjson" +) + +var UnmarshalDisallowUnknownFields = json.UnmarshalDisallowUnknownFields diff --git a/common/json/unmarshal_std.go b/common/json/unmarshal_std.go new file mode 100644 index 0000000..a4d36f4 --- /dev/null +++ b/common/json/unmarshal_std.go @@ -0,0 +1,13 @@ +//go:build !go1.20 || without_contextjson + +package json + +import ( + "bytes" +) + +func UnmarshalDisallowUnknownFields(content []byte, value any) error { + decoder := NewDecoder(bytes.NewReader(content)) + decoder.DisallowUnknownFields() + return decoder.Decode(value) +}