core: EvalVariableBlock to decode maps and slices more carefully
Previously this function was depending on the mapstructure behavior of failing with an error when trying to decode a map into a list or vice-versa, but mapstructure's WeakDecode behavior changed so that it will go to greater lengths to coerce the given value to fit into the target type, causing us to mis-handle certain ambigous cases. Here we exert a bit more control over what's going on by using 'reflect' to first check whether we have a slice or map value and only then try to decode into one with mapstructure. This allows us to still rely on mapstructure's ability to decode nested structures but ensure that lists and maps never get implicitly converted to each other.
This commit is contained in:
parent
46994483e1
commit
e4a5d36127
|
@ -123,22 +123,27 @@ func (n *EvalVariableBlock) Eval(ctx EvalContext) (interface{}, error) {
|
|||
// Get our configuration
|
||||
rc := *n.Config
|
||||
for k, v := range rc.Config {
|
||||
var vString string
|
||||
if err := hilmapstructure.WeakDecode(v, &vString); err == nil {
|
||||
n.VariableValues[k] = vString
|
||||
continue
|
||||
}
|
||||
vKind := reflect.ValueOf(v).Type().Kind()
|
||||
|
||||
var vMap map[string]interface{}
|
||||
if err := hilmapstructure.WeakDecode(v, &vMap); err == nil {
|
||||
n.VariableValues[k] = vMap
|
||||
continue
|
||||
}
|
||||
|
||||
var vSlice []interface{}
|
||||
if err := hilmapstructure.WeakDecode(v, &vSlice); err == nil {
|
||||
n.VariableValues[k] = vSlice
|
||||
continue
|
||||
switch vKind {
|
||||
case reflect.Slice:
|
||||
var vSlice []interface{}
|
||||
if err := hilmapstructure.WeakDecode(v, &vSlice); err == nil {
|
||||
n.VariableValues[k] = vSlice
|
||||
continue
|
||||
}
|
||||
case reflect.Map:
|
||||
var vMap map[string]interface{}
|
||||
if err := hilmapstructure.WeakDecode(v, &vMap); err == nil {
|
||||
n.VariableValues[k] = vMap
|
||||
continue
|
||||
}
|
||||
default:
|
||||
var vString string
|
||||
if err := hilmapstructure.WeakDecode(v, &vString); err == nil {
|
||||
n.VariableValues[k] = vString
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("Variable value for %s is not a string, list or map type", k)
|
||||
|
|
Loading…
Reference in New Issue