Skip to content

Commit 5062118

Browse files
committed
Fix Interpolation interference from outer string
Signed-off-by: Ulysses Souza <[email protected]>
1 parent 56e6c33 commit 5062118

File tree

2 files changed

+75
-20
lines changed

2 files changed

+75
-20
lines changed

template/template.go

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,14 @@ type SubstituteFunc func(string, Mapping) (string, bool, error)
6161
// SubstituteWith substitute variables in the string with their values.
6262
// It accepts additional substitute function.
6363
func SubstituteWith(template string, mapping Mapping, pattern *regexp.Regexp, subsFuncs ...SubstituteFunc) (string, error) {
64-
var err error
64+
var outerErr error
6565

66-
if len(subsFuncs) == 0 {
67-
_, subsFunc := getSubstitutionFunctionForTemplate(template)
68-
subsFuncs = []SubstituteFunc{subsFunc}
69-
}
7066
result := pattern.ReplaceAllStringFunc(template, func(substring string) string {
67+
_, subsFunc := getSubstitutionFunctionForTemplate(substring)
68+
if len(subsFuncs) > 0 {
69+
subsFunc = subsFuncs[0]
70+
}
71+
7172
closingBraceIndex := getFirstBraceClosingIndex(substring)
7273
rest := ""
7374
if closingBraceIndex > -1 {
@@ -89,24 +90,21 @@ func SubstituteWith(template string, mapping Mapping, pattern *regexp.Regexp, su
8990
}
9091

9192
if substitution == "" {
92-
err = &InvalidTemplateError{Template: template}
93+
outerErr = &InvalidTemplateError{Template: template}
9394
return ""
9495
}
9596

9697
if braced {
97-
for _, f := range subsFuncs {
98-
var (
99-
value string
100-
applied bool
101-
)
102-
value, applied, err = f(substitution, mapping)
103-
if err != nil {
104-
return ""
105-
}
106-
if !applied {
107-
continue
108-
}
109-
interpolatedNested, err := SubstituteWith(rest, mapping, pattern, subsFuncs...)
98+
var (
99+
value string
100+
applied bool
101+
)
102+
value, applied, outerErr = subsFunc(substitution, mapping)
103+
if outerErr != nil {
104+
return ""
105+
}
106+
if applied {
107+
interpolatedNested, err := SubstituteWith(rest, mapping, pattern)
110108
if err != nil {
111109
return ""
112110
}
@@ -121,7 +119,7 @@ func SubstituteWith(template string, mapping Mapping, pattern *regexp.Regexp, su
121119
return value
122120
})
123121

124-
return result, err
122+
return result, outerErr
125123
}
126124

127125
func getSubstitutionFunctionForTemplate(template string) (string, SubstituteFunc) {

template/template_test.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,63 @@ func TestNonAlphanumericDefault(t *testing.T) {
155155
assert.Check(t, is.Equal("ok /non:-alphanumeric", result))
156156
}
157157

158+
func TestInterpolationExternalInterference(t *testing.T) {
159+
testCases := []struct {
160+
name string
161+
template string
162+
expected string
163+
}{
164+
{
165+
template: "-ok ${BAR:-defaultValue}",
166+
expected: "-ok defaultValue",
167+
},
168+
{
169+
template: "+ok ${UNSET:-${BAR-defaultValue}}",
170+
expected: "+ok ",
171+
},
172+
{
173+
template: "-ok ${FOO:-defaultValue}",
174+
expected: "-ok first",
175+
},
176+
{
177+
template: ":-ok ${UNSET-defaultValue}",
178+
expected: ":-ok defaultValue",
179+
},
180+
{
181+
template: ":-ok ${BAR-defaultValue}",
182+
expected: ":-ok ",
183+
},
184+
{
185+
template: ":?ok ${BAR-defaultValue}",
186+
expected: ":?ok ",
187+
},
188+
{
189+
template: ":?ok ${BAR:-defaultValue}",
190+
expected: ":?ok defaultValue",
191+
},
192+
{
193+
template: ":+ok ${BAR:-defaultValue}",
194+
expected: ":+ok defaultValue",
195+
},
196+
{
197+
template: "+ok ${BAR-defaultValue}",
198+
expected: "+ok ",
199+
},
200+
{
201+
template: "?ok ${BAR:-defaultValue}",
202+
expected: "?ok defaultValue",
203+
},
204+
}
205+
for i, tc := range testCases {
206+
tc := tc
207+
t.Run(fmt.Sprintf("Interpolation Should not be impacted by outer text: %d", i), func(t *testing.T) {
208+
result, err := Substitute(tc.template, defaultMapping)
209+
assert.NilError(t, err)
210+
assert.Check(t, is.Equal(tc.expected, result))
211+
})
212+
}
213+
}
214+
158215
func TestDefaultsWithNestedExpansion(t *testing.T) {
159216
testCases := []struct {
160217
template string

0 commit comments

Comments
 (0)