Skip to content

Commit 7c2017f

Browse files
authored
fix(terraform): Attribute and fileset fixes (aquasecurity#6544)
1 parent 63c9469 commit 7c2017f

File tree

3 files changed

+81
-7
lines changed

3 files changed

+81
-7
lines changed

pkg/iac/scanners/terraform/parser/funcs/filesystem.go

+4-6
Original file line numberDiff line numberDiff line change
@@ -249,11 +249,9 @@ func MakeFileSetFunc(target fs.FS, baseDir string) function.Function {
249249
path = filepath.Join(baseDir, path)
250250
}
251251

252-
// Join the path to the glob pattern, while ensuring the full
253-
// pattern is canonical for the host OS. The joined path is
254-
// automatically cleaned during this operation.
255-
pattern = filepath.Join(path, pattern)
256-
// Trivy uses a virtual file system
252+
// Join the path to the glob pattern, and ensure both path and pattern
253+
// agree on path separators, so the globbing works as expected.
254+
pattern = filepath.ToSlash(filepath.Join(path, pattern))
257255
path = filepath.ToSlash(path)
258256

259257
matches, err := doublestar.Glob(target, pattern)
@@ -263,7 +261,7 @@ func MakeFileSetFunc(target fs.FS, baseDir string) function.Function {
263261

264262
var matchVals []cty.Value
265263
for _, match := range matches {
266-
fi, err := os.Stat(match)
264+
fi, err := fs.Stat(target, match)
267265

268266
if err != nil {
269267
return cty.UnknownVal(cty.Set(cty.String)), fmt.Errorf("failed to stat (%s): %s", match, err)

pkg/iac/scanners/terraform/parser/parser_test.go

+68
Original file line numberDiff line numberDiff line change
@@ -1631,3 +1631,71 @@ output "test_out" {
16311631
assert.Equal(t, "test_value", attr.GetRawValue())
16321632
}
16331633
}
1634+
1635+
func TestExtractSetValue(t *testing.T) {
1636+
files := map[string]string{
1637+
"main.tf": `
1638+
resource "test" "set-value" {
1639+
value = toset(["x", "y", "x"])
1640+
}
1641+
`,
1642+
}
1643+
1644+
resources := parse(t, files).GetResourcesByType("test")
1645+
require.Len(t, resources, 1)
1646+
attr := resources[0].GetAttribute("value")
1647+
require.NotNil(t, attr)
1648+
assert.Equal(t, []string{"x", "y"}, attr.GetRawValue())
1649+
}
1650+
1651+
func TestFunc_fileset(t *testing.T) {
1652+
files := map[string]string{
1653+
"main.tf": `
1654+
resource "test" "fileset-func" {
1655+
value = fileset(path.module, "**/*.py")
1656+
}
1657+
`,
1658+
"a.py": ``,
1659+
"path/b.py": ``,
1660+
}
1661+
1662+
resources := parse(t, files).GetResourcesByType("test")
1663+
require.Len(t, resources, 1)
1664+
attr := resources[0].GetAttribute("value")
1665+
require.NotNil(t, attr)
1666+
assert.Equal(t, []string{"a.py", "path/b.py"}, attr.GetRawValue())
1667+
}
1668+
1669+
func TestVarTypeShortcut(t *testing.T) {
1670+
files := map[string]string{
1671+
"main.tf": `
1672+
variable "magic_list" {
1673+
type = list
1674+
default = ["x", "y"]
1675+
}
1676+
1677+
variable "magic_map" {
1678+
type = map
1679+
default = {a = 1, b = 2}
1680+
}
1681+
1682+
resource "test" "values" {
1683+
l = var.magic_list
1684+
m = var.magic_map
1685+
}
1686+
`,
1687+
}
1688+
1689+
resources := parse(t, files).GetResourcesByType("test")
1690+
require.Len(t, resources, 1)
1691+
1692+
list_attr := resources[0].GetAttribute("l")
1693+
require.NotNil(t, list_attr)
1694+
assert.Equal(t, []string{"x", "y"}, list_attr.GetRawValue())
1695+
1696+
map_attr := resources[0].GetAttribute("m")
1697+
require.NotNil(t, map_attr)
1698+
assert.True(t, map_attr.Value().RawEquals(cty.MapVal(map[string]cty.Value{
1699+
"a": cty.NumberIntVal(1), "b": cty.NumberIntVal(2),
1700+
})))
1701+
}

pkg/iac/terraform/attribute.go

+9-1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,14 @@ type Attribute struct {
2727
}
2828

2929
func (a *Attribute) DecodeVarType() (cty.Type, *typeexpr.Defaults, error) {
30+
// Special-case the shortcuts for list(any) and map(any) which aren't hcl.
31+
switch hcl.ExprAsKeyword(a.hclAttribute.Expr) {
32+
case "list":
33+
return cty.List(cty.DynamicPseudoType), nil, nil
34+
case "map":
35+
return cty.Map(cty.DynamicPseudoType), nil, nil
36+
}
37+
3038
t, def, diag := typeexpr.TypeConstraintWithDefaults(a.hclAttribute.Expr)
3139
if diag.HasErrors() {
3240
return cty.NilType, nil, diag
@@ -68,7 +76,7 @@ func (a *Attribute) GetRawValue() interface{} {
6876
return float
6977
default:
7078
switch {
71-
case typ.IsTupleType(), typ.IsListType():
79+
case typ.IsTupleType(), typ.IsListType(), typ.IsSetType():
7280
values := a.Value().AsValueSlice()
7381
if len(values) == 0 {
7482
return []string{}

0 commit comments

Comments
 (0)