core: Fix panic on concat() w/ list of nonprimitives

The `concat()` interpolation function does not yet support types other
than strings / lists of strings. Make it an error message instead of a
panic when a list of non-primitives is supplied.

Fixes the panic in #7030
This commit is contained in:
Paul Hinze 2016-06-12 13:21:47 -05:00
parent 2127466280
commit 9bc980f569
No known key found for this signature in database
GPG Key ID: B69DEDF2D55501C0
2 changed files with 43 additions and 2 deletions

View File

@ -240,12 +240,18 @@ func interpolationFuncConcat() ast.Function {
// Otherwise variables
if argument, ok := arg.([]ast.Variable); ok {
for _, element := range argument {
finalListElements = append(finalListElements, element.Value.(string))
t := element.Type
switch t {
case ast.TypeString:
finalListElements = append(finalListElements, element.Value.(string))
default:
return nil, fmt.Errorf("concat() does not support lists of %s", t.Printable())
}
}
continue
}
return nil, fmt.Errorf("arguments to concat() must be a string or list")
return nil, fmt.Errorf("arguments to concat() must be a string or list of strings")
}
return stringSliceToVariableValue(finalListElements), nil

View File

@ -5,6 +5,7 @@ import (
"io/ioutil"
"os"
"reflect"
"strings"
"testing"
"github.com/hashicorp/hil"
@ -226,6 +227,40 @@ func TestInterpolateFuncConcat(t *testing.T) {
})
}
// TODO: This test is split out and calls a private function
// because there's no good way to get a list of maps into the unit
// tests due to GH-7142 - once lists of maps can be expressed properly as
// literals this unit test can be wrapped back into the suite above.
//
// Reproduces crash reported in GH-7030.
func TestInterpolationFuncConcatListOfMaps(t *testing.T) {
listOfMapsOne := ast.Variable{
Type: ast.TypeList,
Value: []ast.Variable{
{
Type: ast.TypeMap,
Value: map[string]interface{}{"one": "foo"},
},
},
}
listOfMapsTwo := ast.Variable{
Type: ast.TypeList,
Value: []ast.Variable{
{
Type: ast.TypeMap,
Value: map[string]interface{}{"two": "bar"},
},
},
}
args := []interface{}{listOfMapsOne.Value, listOfMapsTwo.Value}
_, err := interpolationFuncConcat().Callback(args)
if err == nil || !strings.Contains(err.Error(), "concat() does not support lists of type map") {
t.Fatalf("Expected err, got: %v", err)
}
}
func TestInterpolateFuncFile(t *testing.T) {
tf, err := ioutil.TempFile("", "tf")
if err != nil {