diff --git a/pkg/expressions/parse_test.go b/pkg/expressions/parse_test.go index 25bc6e81933..c726535520f 100644 --- a/pkg/expressions/parse_test.go +++ b/pkg/expressions/parse_test.go @@ -210,6 +210,10 @@ func TestCompileEscapeTemplate(t *testing.T) { assert.Equal(t, `foo{{"{{"}}barbaz{{"{{"}}`, MustCompileTemplate(`foo{{"{{bar"}}baz{{"{{"}}`).Template()) } +func TestCompileEscapeBrace(t *testing.T) { + assert.Equal(t, `foo{{"{"}}barbaz{{"{"}}`, MustCompileTemplate(`foo{{"{bar"}}baz{{"{"}}`).Template()) +} + func TestCompileStandardLib(t *testing.T) { assert.Equal(t, `false`, MustCompile(`bool(0)`).String()) assert.Equal(t, `true`, MustCompile(`bool(500)`).String()) diff --git a/pkg/expressions/static.go b/pkg/expressions/static.go index 163db7345f2..d9d36908e7d 100644 --- a/pkg/expressions/static.go +++ b/pkg/expressions/static.go @@ -1,6 +1,7 @@ package expressions import ( + "bytes" "encoding/json" "strings" ) @@ -69,7 +70,43 @@ func (s *static) Template() string { return "" } v, _ := s.StringValue() - return strings.ReplaceAll(v, "{{", "{{\"{{\"}}") + // Escape double braces + oldValue := strings.ReplaceAll(v, "{{", "{{\"{{\"}}") + + // Escape single brace + newValue := oldValue + replacement := "{{\"{\"}}" + offset := 0 + extension := 0 + for index := strings.Index(oldValue[offset:], "{"); index != -1; index = strings.Index(oldValue[offset:], "{") { + // make sure no other brace before + if offset+index > 0 && string(oldValue[offset+index-1:offset+index]) == "{" { + offset += index + 1 + continue + } + // make sure no other brace after + if offset+index < len(oldValue)-1 && string(oldValue[offset+index+1:offset+index+2]) == "{" { + offset += index + 1 + continue + } + + var value bytes.Buffer + if index+offset+extension > 0 { + value.WriteString(newValue[:index+offset+extension]) + } + + value.WriteString(replacement) + + if index+offset+extension < len(newValue)-1 { + value.WriteString(newValue[index+offset+extension+1:]) + } + + newValue = value.String() + extension += len(replacement) - 1 + offset += index + 1 + } + + return newValue } func (s *static) SafeResolve(_ ...Machine) (Expression, bool, error) {