From e717b9c6dba9243d58beb0ef9bc6241fd9e023e8 Mon Sep 17 00:00:00 2001 From: Jack Lee Date: Tue, 21 Feb 2023 02:02:04 -0500 Subject: [PATCH] Add option to disallow unknown fields --- nbt/decode.go | 8 ++++---- nbt/decode_test.go | 20 ++++++++++++++++++++ nbt/nbt.go | 9 ++++++++- 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/nbt/decode.go b/nbt/decode.go index 4d76f6a..b63858e 100644 --- a/nbt/decode.go +++ b/nbt/decode.go @@ -370,10 +370,10 @@ func (d *Decoder) unmarshal(val reflect.Value, tagType byte) error { if err != nil { return fmt.Errorf("fail to decode tag %q: %w", tn, err) } - } else { - if err := d.rawRead(tt); err != nil { - return err - } + } else if d.disallowUnknownFields { + return fmt.Errorf("unknown field %q", tn) + } else if err := d.rawRead(tt); err != nil { + return err } } case reflect.Map: diff --git a/nbt/decode_test.go b/nbt/decode_test.go index e8ecf45..5aac4db 100644 --- a/nbt/decode_test.go +++ b/nbt/decode_test.go @@ -3,10 +3,12 @@ package nbt import ( "bytes" "compress/gzip" + "fmt" "io" "math" "reflect" "strconv" + "strings" "testing" ) @@ -428,3 +430,21 @@ func TestDecoder_Decode_textUnmarshaler(t *testing.T) { t.Errorf("b should be true") } } + +func TestDecoder_Decode_ErrorUnknownField(t *testing.T) { + data := []byte{ + TagCompound, 0, 1, 'S', + TagByte, 0, 1, 'A', 1, + TagByte, 0, 1, 'B', 2, + TagEnd, + } + var v struct { + A byte `nbt:"a"` + } + d := NewDecoder(bytes.NewReader(data)) + d.DisallowUnknownFields() + if _, err := d.Decode(&v); err == nil || !strings.Contains(err.Error(), "unknown field") { + t.Errorf("should return an error unmarshalling unknown field") + fmt.Println(err) + } +} diff --git a/nbt/nbt.go b/nbt/nbt.go index 983b088..7fc6786 100644 --- a/nbt/nbt.go +++ b/nbt/nbt.go @@ -33,7 +33,8 @@ type DecoderReader = interface { io.Reader } type Decoder struct { - r DecoderReader + r DecoderReader + disallowUnknownFields bool } func NewDecoder(r io.Reader) *Decoder { @@ -46,6 +47,12 @@ func NewDecoder(r io.Reader) *Decoder { return d } +// DisallowUnknownFields makes the decoder return an error when unmarshalling a compound +// tag item that has a tag name not present in the destination struct. +func (d *Decoder) DisallowUnknownFields() { + d.disallowUnknownFields = true +} + type reader struct { io.Reader }