diff --git a/decoder.go b/decoder.go index cfddbf3..a6938fe 100644 --- a/decoder.go +++ b/decoder.go @@ -489,7 +489,7 @@ func (d *decoder) decodeStruct(name string, node ast.Node, result reflect.Value) // the yacc parser would always ensure top-level elements were arrays. The new // parser does not make the same guarantees, thus we need to convert any // top-level literal elements into a list. - if _, ok := node.(*ast.LiteralType); ok { + if _, ok := node.(*ast.LiteralType); ok && item != nil { node = &ast.ObjectList{Items: []*ast.ObjectItem{item}} } diff --git a/decoder_test.go b/decoder_test.go index c074981..b423033 100644 --- a/decoder_test.go +++ b/decoder_test.go @@ -328,6 +328,20 @@ func TestDecode_interface(t *testing.T) { }, }, }, + + // Terraform GH-8295 sanity test that basic decoding into + // interface{} works. + { + "terraform_variable_invalid.json", + false, + map[string]interface{}{ + "variable": []map[string]interface{}{ + map[string]interface{}{ + "whatever": "abc123", + }, + }, + }, + }, } for _, tc := range cases { @@ -676,6 +690,26 @@ func TestDecode_structureMap(t *testing.T) { } } +func TestDecode_structureMapInvalid(t *testing.T) { + // Terraform GH-8295 + + type hclVariable struct { + Default interface{} + Description string + Fields []string `hcl:",decodedFields"` + } + + type rawConfig struct { + Variable map[string]*hclVariable + } + + var actual rawConfig + err := Decode(&actual, testReadFile(t, "terraform_variable_invalid.json")) + if err == nil { + t.Fatal("expected error") + } +} + func TestDecode_interfaceNonPointer(t *testing.T) { var value interface{} err := Decode(value, testReadFile(t, "basic_int_string.hcl")) diff --git a/test-fixtures/terraform_variable_invalid.json b/test-fixtures/terraform_variable_invalid.json new file mode 100644 index 0000000..081247e --- /dev/null +++ b/test-fixtures/terraform_variable_invalid.json @@ -0,0 +1,5 @@ +{ + "variable": { + "whatever": "abc123" + } +}