From e4a5d3612761009add67205f28d14c3f4b7bec27 Mon Sep 17 00:00:00 2001 From: Martin Atkins Date: Fri, 7 Apr 2017 15:30:53 -0700 Subject: [PATCH] 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. --- terraform/eval_variable.go | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/terraform/eval_variable.go b/terraform/eval_variable.go index b39a4d198f..e39a33c2a9 100644 --- a/terraform/eval_variable.go +++ b/terraform/eval_variable.go @@ -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)