mirror of https://github.com/hashicorp/packer
hcl2: fix crash on malformed overrides (#11881)
When an override block is either not an object, or if one of its contents are not an object, Packer would crash trying to forcefully cast the cty.Value to a cty.Collection. To avoid this behaviour, we add extra checks that return hcl.Diagnostics when they fail.pull/11888/head
parent
6794c6053a
commit
6ab16561b5
@ -0,0 +1,4 @@
|
||||
provisioner "shell-local" {
|
||||
inline = ["echo 'hi'"]
|
||||
override = "hello"
|
||||
}
|
||||
@ -0,0 +1,6 @@
|
||||
provisioner "shell-local" {
|
||||
inline = ["echo 'hi'"]
|
||||
override = {
|
||||
test = "hello"
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
provisioner "shell-local" {
|
||||
inline = ["echo 'hi'"]
|
||||
override = {
|
||||
test = {
|
||||
"hello" = "new value"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,82 @@
|
||||
package hcl2template
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/hcl/v2"
|
||||
)
|
||||
|
||||
func TestPackerConfig_ParseProvisionerBlock(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
inputFile string
|
||||
expectError bool
|
||||
expectedErrorMessage string
|
||||
}{
|
||||
{
|
||||
"success - provisioner is valid",
|
||||
"fixtures/well_formed_provisioner.pkr.hcl",
|
||||
false,
|
||||
"",
|
||||
},
|
||||
{
|
||||
"failure - provisioner override is malformed",
|
||||
"fixtures/malformed_override.pkr.hcl",
|
||||
true,
|
||||
"provisioner's override block must be an HCL object",
|
||||
},
|
||||
{
|
||||
"failure - provisioner override.test is malformed",
|
||||
"fixtures/malformed_override_innards.pkr.hcl",
|
||||
true,
|
||||
"provisioner's override.'test' block must be an HCL object",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
cfg := PackerConfig{parser: getBasicParser()}
|
||||
f, diags := cfg.parser.ParseHCLFile(test.inputFile)
|
||||
if diags.HasErrors() {
|
||||
t.Errorf("failed to parse input file %s", test.inputFile)
|
||||
for _, d := range diags {
|
||||
t.Errorf("%s", d)
|
||||
}
|
||||
return
|
||||
}
|
||||
provBlock := f.OutermostBlockAtPos(hcl.Pos{
|
||||
Line: 1,
|
||||
Column: 1,
|
||||
Byte: 0,
|
||||
})
|
||||
_, diags = cfg.parser.decodeProvisioner(provBlock, nil)
|
||||
|
||||
if !diags.HasErrors() {
|
||||
if !test.expectError {
|
||||
return
|
||||
}
|
||||
|
||||
t.Fatalf("unexpected success")
|
||||
}
|
||||
|
||||
if !test.expectError {
|
||||
for _, d := range diags {
|
||||
t.Errorf("%s", d)
|
||||
}
|
||||
}
|
||||
|
||||
gotExpectedErr := false
|
||||
for _, d := range diags {
|
||||
if d.Summary == test.expectedErrorMessage {
|
||||
gotExpectedErr = true
|
||||
}
|
||||
|
||||
t.Logf("got error (expected): '%s'", d.Summary)
|
||||
}
|
||||
|
||||
if !gotExpectedErr {
|
||||
t.Errorf("never got expected error: '%s'", test.expectedErrorMessage)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Loading…
Reference in new issue