[Backport #1801] Sensitive path usage in templatefile shouldn't panic (#1846)

Signed-off-by: James Humphries <james@james-humphries.co.uk>
This commit is contained in:
James Humphries 2024-07-23 14:24:36 +01:00 committed by GitHub
parent eb61c454f4
commit d28afdab5a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 27 additions and 8 deletions

View File

@ -34,7 +34,7 @@ BUG FIXES:
* Fixed issue with migration between versions can cause an update in-place for resources when no changes are needed. ([#1640](https://github.com/opentofu/opentofu/pull/1640)) * Fixed issue with migration between versions can cause an update in-place for resources when no changes are needed. ([#1640](https://github.com/opentofu/opentofu/pull/1640))
* Add source context for the 'insufficient feature blocks' error ([#1777](https://github.com/opentofu/opentofu/pull/1777)) * Add source context for the 'insufficient feature blocks' error ([#1777](https://github.com/opentofu/opentofu/pull/1777))
* Remove encryption diags from autocomplete ([#1793](https://github.com/opentofu/opentofu/pull/1793)) * Remove encryption diags from autocomplete ([#1793](https://github.com/opentofu/opentofu/pull/1793))
* Ensure that using a sensitive path for templatefile that it doesn't panic([#1801](https://github.com/opentofu/opentofu/issues/1801))
## Previous Releases ## Previous Releases

View File

@ -121,7 +121,6 @@ func MakeTemplateFileFunc(baseDir string, funcsCb func() map[string]function.Fun
return makeTemplateFileFuncImpl(baseDir, funcsCb, 0) return makeTemplateFileFuncImpl(baseDir, funcsCb, 0)
} }
func makeTemplateFileFuncImpl(baseDir string, funcsCb func() map[string]function.Function, depth int) function.Function { func makeTemplateFileFuncImpl(baseDir string, funcsCb func() map[string]function.Function, depth int) function.Function {
params := []function.Parameter{ params := []function.Parameter{
{ {
Name: "path", Name: "path",
@ -134,7 +133,7 @@ func makeTemplateFileFuncImpl(baseDir string, funcsCb func() map[string]function
}, },
} }
loadTmpl := func(fn string, marks cty.ValueMarks) (hcl.Expression, error) { loadTmpl := func(path string, marks cty.ValueMarks) (hcl.Expression, error) {
maxDepth, err := templateMaxRecursionDepth() maxDepth, err := templateMaxRecursionDepth()
if err != nil { if err != nil {
return nil, err return nil, err
@ -146,12 +145,15 @@ func makeTemplateFileFuncImpl(baseDir string, funcsCb func() map[string]function
// We re-use File here to ensure the same filename interpretation // We re-use File here to ensure the same filename interpretation
// as it does, along with its other safety checks. // as it does, along with its other safety checks.
tmplVal, err := File(baseDir, cty.StringVal(fn).WithMarks(marks)) templateValue, err := File(baseDir, cty.StringVal(path).WithMarks(marks))
if err != nil { if err != nil {
return nil, err return nil, err
} }
expr, diags := hclsyntax.ParseTemplate([]byte(tmplVal.AsString()), fn, hcl.Pos{Line: 1, Column: 1}) // unmark the template ready to be handled
templateValue, _ = templateValue.Unmark()
expr, diags := hclsyntax.ParseTemplate([]byte(templateValue.AsString()), path, hcl.Pos{Line: 1, Column: 1})
if diags.HasErrors() { if diags.HasErrors() {
return nil, diags return nil, diags
} }
@ -206,7 +208,6 @@ func makeTemplateFileFuncImpl(baseDir string, funcsCb func() map[string]function
return result.WithMarks(pathMarks), err return result.WithMarks(pathMarks), err
}, },
}) })
} }
// MakeFileExistsFunc constructs a function that takes a path // MakeFileExistsFunc constructs a function that takes a path

View File

@ -6,16 +6,18 @@
package funcs package funcs
import ( import (
"errors"
"fmt" "fmt"
"os" "os"
"path/filepath" "path/filepath"
"testing" "testing"
homedir "github.com/mitchellh/go-homedir" homedir "github.com/mitchellh/go-homedir"
"github.com/opentofu/opentofu/internal/lang/marks"
"github.com/zclconf/go-cty/cty" "github.com/zclconf/go-cty/cty"
"github.com/zclconf/go-cty/cty/function" "github.com/zclconf/go-cty/cty/function"
"github.com/zclconf/go-cty/cty/function/stdlib" "github.com/zclconf/go-cty/cty/function/stdlib"
"github.com/opentofu/opentofu/internal/lang/marks"
) )
func TestFile(t *testing.T) { func TestFile(t *testing.T) {
@ -181,6 +183,21 @@ func TestTemplateFile(t *testing.T) {
cty.True, // since this template contains only an interpolation, its true value shines through cty.True, // since this template contains only an interpolation, its true value shines through
``, ``,
}, },
{
// write to a sensitive file path that exists
cty.StringVal("testdata/hello.txt").Mark(marks.Sensitive),
cty.EmptyObjectVal,
cty.StringVal("Hello World").Mark(marks.Sensitive),
``,
},
{
cty.StringVal("testdata/bare.tmpl"),
cty.ObjectVal(map[string]cty.Value{
"val": cty.True.Mark(marks.Sensitive),
}),
cty.True.Mark(marks.Sensitive),
``,
},
} }
templateFileFn := MakeTemplateFileFunc(".", func() map[string]function.Function { templateFileFn := MakeTemplateFileFunc(".", func() map[string]function.Function {
@ -194,7 +211,8 @@ func TestTemplateFile(t *testing.T) {
t.Run(fmt.Sprintf("TemplateFile(%#v, %#v)", test.Path, test.Vars), func(t *testing.T) { t.Run(fmt.Sprintf("TemplateFile(%#v, %#v)", test.Path, test.Vars), func(t *testing.T) {
got, err := templateFileFn.Call([]cty.Value{test.Path, test.Vars}) got, err := templateFileFn.Call([]cty.Value{test.Path, test.Vars})
if argErr, ok := err.(function.ArgError); ok { var argErr function.ArgError
if errors.As(err, &argErr) {
if argErr.Index < 0 || argErr.Index > 1 { if argErr.Index < 0 || argErr.Index > 1 {
t.Errorf("ArgError index %d is out of range for templatefile (must be 0 or 1)", argErr.Index) t.Errorf("ArgError index %d is out of range for templatefile (must be 0 or 1)", argErr.Index)
} }