From 5ad5fe42d49ffd7808a1b981b089ada50b335ca9 Mon Sep 17 00:00:00 2001 From: James Phillips Date: Tue, 9 Aug 2016 17:34:07 -0700 Subject: [PATCH] Updates mitchellh/copystructure, mitchellh/mapstructure, and mitchellh/reflectwalk. --- .../mitchellh/copystructure/copystructure.go | 16 ++--- .../mitchellh/mapstructure/.travis.yml | 7 -- .../mitchellh/mapstructure/decode_hooks.go | 5 +- .../mitchellh/mapstructure/mapstructure.go | 65 ++++++++++++++++--- vendor/vendor.json | 12 +++- 5 files changed, 76 insertions(+), 29 deletions(-) delete mode 100644 vendor/github.com/mitchellh/mapstructure/.travis.yml diff --git a/vendor/github.com/mitchellh/copystructure/copystructure.go b/vendor/github.com/mitchellh/copystructure/copystructure.go index c248e4f6f2..98c5144e2f 100644 --- a/vendor/github.com/mitchellh/copystructure/copystructure.go +++ b/vendor/github.com/mitchellh/copystructure/copystructure.go @@ -95,7 +95,9 @@ func (w *walker) Exit(l reflectwalk.Location) error { if v.IsValid() { s := w.cs[len(w.cs)-1] sf := reflect.Indirect(s).FieldByName(f.Name) - sf.Set(v) + if sf.CanSet() { + sf.Set(v) + } } case reflectwalk.WalkLoc: // Clear out the slices for GC @@ -111,16 +113,12 @@ func (w *walker) Map(m reflect.Value) error { return nil } - // Get the type for the map - t := m.Type() - mapType := reflect.MapOf(t.Key(), t.Elem()) - // Create the map. If the map itself is nil, then just make a nil map var newMap reflect.Value if m.IsNil() { - newMap = reflect.Indirect(reflect.New(mapType)) + newMap = reflect.Indirect(reflect.New(m.Type())) } else { - newMap = reflect.MakeMap(reflect.MapOf(t.Key(), t.Elem())) + newMap = reflect.MakeMap(m.Type()) } w.cs = append(w.cs, newMap) @@ -155,8 +153,10 @@ func (w *walker) Primitive(v reflect.Value) error { return nil } + // IsValid verifies the v is non-zero and CanInterface verifies + // that we're allowed to read this value (unexported fields). var newV reflect.Value - if v.IsValid() { + if v.IsValid() && v.CanInterface() { newV = reflect.New(v.Type()) reflect.Indirect(newV).Set(v) } diff --git a/vendor/github.com/mitchellh/mapstructure/.travis.yml b/vendor/github.com/mitchellh/mapstructure/.travis.yml deleted file mode 100644 index 7f3fe9a969..0000000000 --- a/vendor/github.com/mitchellh/mapstructure/.travis.yml +++ /dev/null @@ -1,7 +0,0 @@ -language: go - -go: - - 1.4 - -script: - - go test diff --git a/vendor/github.com/mitchellh/mapstructure/decode_hooks.go b/vendor/github.com/mitchellh/mapstructure/decode_hooks.go index aa91f76ce4..115ae67c11 100644 --- a/vendor/github.com/mitchellh/mapstructure/decode_hooks.go +++ b/vendor/github.com/mitchellh/mapstructure/decode_hooks.go @@ -72,7 +72,10 @@ func ComposeDecodeHookFunc(fs ...DecodeHookFunc) DecodeHookFunc { } // Modify the from kind to be correct with the new data - f = reflect.ValueOf(data).Type() + f = nil + if val := reflect.ValueOf(data); val.IsValid() { + f = val.Type() + } } return data, nil diff --git a/vendor/github.com/mitchellh/mapstructure/mapstructure.go b/vendor/github.com/mitchellh/mapstructure/mapstructure.go index 40be5116db..a554e799bb 100644 --- a/vendor/github.com/mitchellh/mapstructure/mapstructure.go +++ b/vendor/github.com/mitchellh/mapstructure/mapstructure.go @@ -8,6 +8,7 @@ package mapstructure import ( + "encoding/json" "errors" "fmt" "reflect" @@ -67,6 +68,7 @@ type DecoderConfig struct { // FALSE, false, False. Anything else is an error) // - empty array = empty map and vice versa // - negative numbers to overflowed uint values (base 10) + // - slice of maps to a merged map // WeaklyTypedInput bool @@ -245,6 +247,10 @@ func (d *Decoder) decode(name string, data interface{}, val reflect.Value) error // value to "data" of that type. func (d *Decoder) decodeBasic(name string, data interface{}, val reflect.Value) error { dataVal := reflect.ValueOf(data) + if !dataVal.IsValid() { + dataVal = reflect.Zero(val.Type()) + } + dataValType := dataVal.Type() if !dataValType.AssignableTo(val.Type()) { return fmt.Errorf( @@ -301,6 +307,7 @@ func (d *Decoder) decodeString(name string, data interface{}, val reflect.Value) func (d *Decoder) decodeInt(name string, data interface{}, val reflect.Value) error { dataVal := reflect.ValueOf(data) dataKind := getKind(dataVal) + dataType := dataVal.Type() switch { case dataKind == reflect.Int: @@ -322,6 +329,14 @@ func (d *Decoder) decodeInt(name string, data interface{}, val reflect.Value) er } else { return fmt.Errorf("cannot parse '%s' as int: %s", name, err) } + case dataType.PkgPath() == "encoding/json" && dataType.Name() == "Number": + jn := data.(json.Number) + i, err := jn.Int64() + if err != nil { + return fmt.Errorf( + "error decoding json.Number into %s: %s", name, err) + } + val.SetInt(i) default: return fmt.Errorf( "'%s' expected type '%s', got unconvertible type '%s'", @@ -408,6 +423,7 @@ func (d *Decoder) decodeBool(name string, data interface{}, val reflect.Value) e func (d *Decoder) decodeFloat(name string, data interface{}, val reflect.Value) error { dataVal := reflect.ValueOf(data) dataKind := getKind(dataVal) + dataType := dataVal.Type() switch { case dataKind == reflect.Int: @@ -429,6 +445,14 @@ func (d *Decoder) decodeFloat(name string, data interface{}, val reflect.Value) } else { return fmt.Errorf("cannot parse '%s' as float: %s", name, err) } + case dataType.PkgPath() == "encoding/json" && dataType.Name() == "Number": + jn := data.(json.Number) + i, err := jn.Float64() + if err != nil { + return fmt.Errorf( + "error decoding json.Number into %s: %s", name, err) + } + val.SetFloat(i) default: return fmt.Errorf( "'%s' expected type '%s', got unconvertible type '%s'", @@ -456,15 +480,30 @@ func (d *Decoder) decodeMap(name string, data interface{}, val reflect.Value) er // Check input type dataVal := reflect.Indirect(reflect.ValueOf(data)) if dataVal.Kind() != reflect.Map { - // Accept empty array/slice instead of an empty map in weakly typed mode - if d.config.WeaklyTypedInput && - (dataVal.Kind() == reflect.Slice || dataVal.Kind() == reflect.Array) && - dataVal.Len() == 0 { - val.Set(valMap) - return nil - } else { - return fmt.Errorf("'%s' expected a map, got '%s'", name, dataVal.Kind()) + // In weak mode, we accept a slice of maps as an input... + if d.config.WeaklyTypedInput { + switch dataVal.Kind() { + case reflect.Array, reflect.Slice: + // Special case for BC reasons (covered by tests) + if dataVal.Len() == 0 { + val.Set(valMap) + return nil + } + + for i := 0; i < dataVal.Len(); i++ { + err := d.decode( + fmt.Sprintf("%s[%d]", name, i), + dataVal.Index(i).Interface(), val) + if err != nil { + return err + } + } + + return nil + } } + + return fmt.Errorf("'%s' expected a map, got '%s'", name, dataVal.Kind()) } // Accumulate errors @@ -607,11 +646,12 @@ func (d *Decoder) decodeStruct(name string, data interface{}, val reflect.Value) structs = structs[1:] structType := structVal.Type() + for i := 0; i < structType.NumField(); i++ { fieldType := structType.Field(i) + fieldKind := fieldType.Type.Kind() if fieldType.Anonymous { - fieldKind := fieldType.Type.Kind() if fieldKind != reflect.Struct { errors = appendErrors(errors, fmt.Errorf("%s: unsupported type: %s", fieldType.Name, fieldKind)) @@ -630,7 +670,12 @@ func (d *Decoder) decodeStruct(name string, data interface{}, val reflect.Value) } if squash { - structs = append(structs, val.FieldByName(fieldType.Name)) + if fieldKind != reflect.Struct { + errors = appendErrors(errors, + fmt.Errorf("%s: unsupported type for squash: %s", fieldType.Name, fieldKind)) + } else { + structs = append(structs, val.FieldByName(fieldType.Name)) + } continue } diff --git a/vendor/vendor.json b/vendor/vendor.json index b00ec223ee..78c1b40065 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -438,16 +438,22 @@ "revisionTime": "2016-03-23T17:07:00Z" }, { + "checksumSHA1": "86nE93o1VIND0Doe8PuhCXnhUx0=", "path": "github.com/mitchellh/copystructure", - "revision": "6fc66267e9da7d155a9d3bd489e00dad02666dc6" + "revision": "cdac8253d00f2ecf0a0b19fbff173a9a72de4f82", + "revisionTime": "2016-08-04T03:23:30Z" }, { + "checksumSHA1": "LUrnGREfnifW4WDMaavmc9MlLI0=", "path": "github.com/mitchellh/mapstructure", - "revision": "281073eb9eb092240d33ef253c404f1cca550309" + "revision": "ca63d7c062ee3c9f34db231e352b60012b4fd0c1", + "revisionTime": "2016-08-08T18:12:53Z" }, { + "checksumSHA1": "mrqMlK6gqe//WsJSrJ1HgkPM0lM=", "path": "github.com/mitchellh/reflectwalk", - "revision": "eecf4c70c626c7cfbb95c90195bc34d386c74ac6" + "revision": "eecf4c70c626c7cfbb95c90195bc34d386c74ac6", + "revisionTime": "2015-05-27T15:31:53Z" }, { "checksumSHA1": "3AoPMXlmVq2+iWMpsdJZkcUKHB8=",