diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2021-04-20 14:11:30 +0200 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2021-04-28 07:08:41 +0200 |
| commit | de0456bb5ab22e568b8a3ffcce6bf85e2a7de164 (patch) | |
| tree | 1d8603e4ee455b2c6c4e5ea36d42e28ce7977b1c /pkg/config/config.go | |
| parent | 805b5003de8c474f5d317a67f739597ebc78fcca (diff) | |
pkg/config: use DisallowUnknownFields
DisallowUnknownFields was added in Go 1.10,
remove our custom machinery for checking unknown fields.
Diffstat (limited to 'pkg/config/config.go')
| -rw-r--r-- | pkg/config/config.go | 88 |
1 files changed, 4 insertions, 84 deletions
diff --git a/pkg/config/config.go b/pkg/config/config.go index 49d030499..a4f56c225 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -4,11 +4,10 @@ package config import ( + "bytes" "encoding/json" "fmt" "io/ioutil" - "reflect" - "strings" "github.com/google/syzkaller/pkg/osutil" ) @@ -25,10 +24,9 @@ func LoadFile(filename string, cfg interface{}) error { } func LoadData(data []byte, cfg interface{}) error { - if err := checkUnknownFields(data, reflect.ValueOf(cfg).Type()); err != nil { - return err - } - if err := json.Unmarshal(data, cfg); err != nil { + dec := json.NewDecoder(bytes.NewReader(data)) + dec.DisallowUnknownFields() + if err := dec.Decode(cfg); err != nil { return fmt.Errorf("failed to parse config file: %v", err) } return nil @@ -45,81 +43,3 @@ func SaveFile(filename string, cfg interface{}) error { func SaveData(cfg interface{}) ([]byte, error) { return json.MarshalIndent(cfg, "", "\t") } - -func checkUnknownFields(data []byte, typ reflect.Type) error { - if typ.Kind() != reflect.Ptr || typ.Elem().Kind() != reflect.Struct { - return fmt.Errorf("config type is not pointer to struct") - } - return checkUnknownFieldsRec(data, "", typ) -} - -func checkUnknownFieldsRec(data []byte, prefix string, typ reflect.Type) error { - if typ.Kind() == reflect.Ptr { - typ = typ.Elem() - } - if typ.Kind() != reflect.Struct { - return fmt.Errorf("config type is not pointer to struct") - } - fields := make(map[string]reflect.Type) - for i := 0; i < typ.NumField(); i++ { - field := typ.Field(i) - tag := field.Tag.Get("json") - tag = strings.TrimSuffix(tag, ",omitempty") - if tag == "-" { - continue - } - name := strings.ToLower(field.Name) - if tag != "" { - if tag != strings.ToLower(tag) { - return fmt.Errorf("json tag on '%v%v' should be lower-case", prefix, name) - } - name = tag - } - fields[name] = field.Type - } - f := make(map[string]interface{}) - if err := json.Unmarshal(data, &f); err != nil { - return fmt.Errorf("failed to parse config file: %v", err) - } - for k, v := range f { - field, ok := fields[strings.ToLower(k)] - if !ok { - return fmt.Errorf("unknown field '%v%v' in config", prefix, k) - } - if v != nil && field.Kind() == reflect.Slice && - (field.PkgPath() != "encoding/json" || field.Name() != "RawMessage") { - vv := reflect.ValueOf(v) - if vv.Type().Kind() != reflect.Slice { - return fmt.Errorf("bad json array type '%v%v'", prefix, k) - } - for i := 0; i < vv.Len(); i++ { - e := vv.Index(i).Interface() - prefix1 := fmt.Sprintf("%v%v[%v].", prefix, k, i) - if err := checkUnknownFieldsStruct(e, prefix1, field.Elem()); err != nil { - return err - } - } - } - if err := checkUnknownFieldsStruct(v, prefix+k+".", field); err != nil { - return err - } - } - return nil -} - -func checkUnknownFieldsStruct(val interface{}, prefix string, typ reflect.Type) error { - if typ.Kind() == reflect.Ptr { - typ = typ.Elem() - } - if typ.Kind() != reflect.Struct { - return nil - } - if typ.PkgPath() == "time" && typ.Name() == "Time" { - return nil - } - inner, err := json.Marshal(val) - if err != nil { - return fmt.Errorf("failed to marshal inner struct %q: %v", prefix, err) - } - return checkUnknownFieldsRec(inner, prefix, typ) -} |
