Skip to content

Commit

Permalink
Merge pull request #32543 from hashicorp/nf/jan23-attr-path-value-mar…
Browse files Browse the repository at this point in the history
…ks-corruption

Fix accidental mutation of shared `cty.Path`s in ValueMarks funcs
  • Loading branch information
nfagerlund committed Jan 20, 2023
2 parents 9001bef + 83428c9 commit 3b26f68
Showing 1 changed file with 18 additions and 16 deletions.
34 changes: 18 additions & 16 deletions internal/configs/configschema/marks.go
Expand Up @@ -7,6 +7,15 @@ import (
"github.com/zclconf/go-cty/cty"
)

// copyAndExtendPath returns a copy of a cty.Path with some additional
// `cty.PathStep`s appended to its end, to simplify creating new child paths.
func copyAndExtendPath(path cty.Path, nextSteps ...cty.PathStep) cty.Path {
newPath := make(cty.Path, len(path), len(path)+len(nextSteps))
copy(newPath, path)
newPath = append(newPath, nextSteps...)
return newPath
}

// ValueMarks returns a set of path value marks for a given value and path,
// based on the sensitive flag for each attribute within the schema. Nested
// blocks are descended (if present in the given value).
Expand All @@ -17,9 +26,7 @@ func (b *Block) ValueMarks(val cty.Value, path cty.Path) []cty.PathValueMarks {
for name, attrS := range b.Attributes {
if attrS.Sensitive {
// Create a copy of the path, with this step added, to add to our PathValueMarks slice
attrPath := make(cty.Path, len(path), len(path)+1)
copy(attrPath, path)
attrPath = append(path, cty.GetAttrStep{Name: name})
attrPath := copyAndExtendPath(path, cty.GetAttrStep{Name: name})
pvm = append(pvm, cty.PathValueMarks{
Path: attrPath,
Marks: cty.NewValueMarks(marks.Sensitive),
Expand All @@ -41,9 +48,7 @@ func (b *Block) ValueMarks(val cty.Value, path cty.Path) []cty.PathValueMarks {
}

// Create a copy of the path, with this step added, to add to our PathValueMarks slice
attrPath := make(cty.Path, len(path), len(path)+1)
copy(attrPath, path)
attrPath = append(path, cty.GetAttrStep{Name: name})
attrPath := copyAndExtendPath(path, cty.GetAttrStep{Name: name})

pvm = append(pvm, attrS.NestedType.ValueMarks(val.GetAttr(name), attrPath)...)
}
Expand All @@ -61,17 +66,18 @@ func (b *Block) ValueMarks(val cty.Value, path cty.Path) []cty.PathValueMarks {
}

// Create a copy of the path, with this step added, to add to our PathValueMarks slice
blockPath := make(cty.Path, len(path), len(path)+1)
copy(blockPath, path)
blockPath = append(path, cty.GetAttrStep{Name: name})
blockPath := copyAndExtendPath(path, cty.GetAttrStep{Name: name})

switch blockS.Nesting {
case NestingSingle, NestingGroup:
pvm = append(pvm, blockS.Block.ValueMarks(blockV, blockPath)...)
case NestingList, NestingMap, NestingSet:
for it := blockV.ElementIterator(); it.Next(); {
idx, blockEV := it.Element()
morePaths := blockS.Block.ValueMarks(blockEV, append(blockPath, cty.IndexStep{Key: idx}))
// Create a copy of the path, with this block instance's index
// step added, to add to our PathValueMarks slice
blockInstancePath := copyAndExtendPath(blockPath, cty.IndexStep{Key: idx})
morePaths := blockS.Block.ValueMarks(blockEV, blockInstancePath)
pvm = append(pvm, morePaths...)
}
default:
Expand Down Expand Up @@ -100,9 +106,7 @@ func (o *Object) ValueMarks(val cty.Value, path cty.Path) []cty.PathValueMarks {
switch o.Nesting {
case NestingSingle, NestingGroup:
// Create a path to this attribute
attrPath := make(cty.Path, len(path), len(path)+1)
copy(attrPath, path)
attrPath = append(path, cty.GetAttrStep{Name: name})
attrPath := copyAndExtendPath(path, cty.GetAttrStep{Name: name})

if attrS.Sensitive {
// If the entire attribute is sensitive, mark it so
Expand All @@ -127,9 +131,7 @@ func (o *Object) ValueMarks(val cty.Value, path cty.Path) []cty.PathValueMarks {
// of the loops: index into the collection, then the contained
// attribute name. This is because we have one type
// representing multiple collection elements.
attrPath := make(cty.Path, len(path), len(path)+2)
copy(attrPath, path)
attrPath = append(path, cty.IndexStep{Key: idx}, cty.GetAttrStep{Name: name})
attrPath := copyAndExtendPath(path, cty.IndexStep{Key: idx}, cty.GetAttrStep{Name: name})

if attrS.Sensitive {
// If the entire attribute is sensitive, mark it so
Expand Down

0 comments on commit 3b26f68

Please sign in to comment.