Add option to disallow unknown fields

This commit is contained in:
Jack Lee
2023-02-21 02:02:04 -05:00
parent 7fa4b32dd0
commit e717b9c6db
3 changed files with 32 additions and 5 deletions

View File

@ -370,12 +370,12 @@ func (d *Decoder) unmarshal(val reflect.Value, tagType byte) error {
if err != nil { if err != nil {
return fmt.Errorf("fail to decode tag %q: %w", tn, err) return fmt.Errorf("fail to decode tag %q: %w", tn, err)
} }
} else { } else if d.disallowUnknownFields {
if err := d.rawRead(tt); err != nil { return fmt.Errorf("unknown field %q", tn)
} else if err := d.rawRead(tt); err != nil {
return err return err
} }
} }
}
case reflect.Map: case reflect.Map:
if val.Type().Key().Kind() != reflect.String { if val.Type().Key().Kind() != reflect.String {
return errors.New("cannot parse TagCompound as " + val.Type().String()) return errors.New("cannot parse TagCompound as " + val.Type().String())

View File

@ -3,10 +3,12 @@ package nbt
import ( import (
"bytes" "bytes"
"compress/gzip" "compress/gzip"
"fmt"
"io" "io"
"math" "math"
"reflect" "reflect"
"strconv" "strconv"
"strings"
"testing" "testing"
) )
@ -428,3 +430,21 @@ func TestDecoder_Decode_textUnmarshaler(t *testing.T) {
t.Errorf("b should be true") 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)
}
}

View File

@ -34,6 +34,7 @@ type DecoderReader = interface {
} }
type Decoder struct { type Decoder struct {
r DecoderReader r DecoderReader
disallowUnknownFields bool
} }
func NewDecoder(r io.Reader) *Decoder { func NewDecoder(r io.Reader) *Decoder {
@ -46,6 +47,12 @@ func NewDecoder(r io.Reader) *Decoder {
return d 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 { type reader struct {
io.Reader io.Reader
} }