mirror of
https://github.com/mikefarah/yq.git
synced 2024-11-12 05:38:04 +00:00
handle escaped backslashes (#1997)
This commit is contained in:
parent
db6f2dc6a2
commit
b54d7eb21c
@ -54,40 +54,52 @@ func interpolate(d *dataTreeNavigator, context Context, str string) (string, err
|
||||
for i := 0; i < len(runes); i++ {
|
||||
char := runes[i]
|
||||
if !inExpression {
|
||||
if char == '\\' && i != len(runes)-1 && runes[i+1] == '(' {
|
||||
if char == '\\' && i < len(runes)-1 {
|
||||
switch runes[i+1] {
|
||||
case '(':
|
||||
inExpression = true
|
||||
i = i + 1 // skip over the next open bracket
|
||||
// skip the lparen
|
||||
i++
|
||||
continue
|
||||
case '\\':
|
||||
// skip the escaped backslash
|
||||
i++
|
||||
default:
|
||||
log.Debugf("Ignoring non-escaping backslash @ %v[%d]", str, i)
|
||||
}
|
||||
}
|
||||
sb.WriteRune(char)
|
||||
} else { // we are in an expression
|
||||
if char == ')' && nestedBracketsCounter == 0 {
|
||||
if char == ')' {
|
||||
if nestedBracketsCounter == 0 {
|
||||
// finished the expression!
|
||||
log.Debugf("Expression is :%v", expSb.String())
|
||||
value, err := evaluate(d, context, expSb.String())
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
inExpression = false
|
||||
expSb = strings.Builder{} // reset this
|
||||
|
||||
sb.WriteString(value)
|
||||
continue
|
||||
}
|
||||
nestedBracketsCounter--
|
||||
} else if char == '(' {
|
||||
nestedBracketsCounter++
|
||||
} else if char == '\\' && i != len(runes)-1 && runes[i+1] == ')' {
|
||||
// close brackets is escaped, skip over it
|
||||
expSb.WriteRune(char)
|
||||
expSb.WriteRune(runes[i+1])
|
||||
i = i + 1
|
||||
} else if char == '\\' && i < len(runes)-1 {
|
||||
switch esc := runes[i+1]; esc {
|
||||
case ')', '\\':
|
||||
// write escaped character
|
||||
expSb.WriteRune(esc)
|
||||
i++
|
||||
continue
|
||||
} else if char == ')' {
|
||||
nestedBracketsCounter--
|
||||
default:
|
||||
log.Debugf("Ignoring non-escaping backslash @ %v[%d]", str, i)
|
||||
}
|
||||
}
|
||||
expSb.WriteRune(char)
|
||||
}
|
||||
|
||||
}
|
||||
if inExpression {
|
||||
return "", fmt.Errorf("unclosed interpolation string \\(")
|
||||
|
@ -26,7 +26,7 @@ var stringsOperatorScenarios = []expressionScenario{
|
||||
description: "Interpolation - just escape",
|
||||
expression: `"\\"`,
|
||||
expected: []string{
|
||||
"D0, P[], (!!str)::\\\\\n",
|
||||
"D0, P[], (!!str)::\\\n",
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -47,6 +47,15 @@ var stringsOperatorScenarios = []expressionScenario{
|
||||
"D0, P[], (!!str)::Hi (.value)\n",
|
||||
},
|
||||
},
|
||||
{
|
||||
skipDoc: true,
|
||||
description: "Interpolation - don't!",
|
||||
document: `value: things`,
|
||||
expression: `"Hi \\(.value)"`,
|
||||
expected: []string{
|
||||
"D0, P[], (!!str)::Hi \\(.value)\n",
|
||||
},
|
||||
},
|
||||
{
|
||||
skipDoc: true,
|
||||
description: "Interpolation - random close bracket",
|
||||
@ -63,6 +72,13 @@ var stringsOperatorScenarios = []expressionScenario{
|
||||
expression: `"Hi \("`,
|
||||
expectedError: "unclosed interpolation string \\(",
|
||||
},
|
||||
{
|
||||
skipDoc: true,
|
||||
description: "Interpolation - unclosed interpolation string due to escape",
|
||||
document: `value: things`,
|
||||
expression: `"Hi \(\)"`,
|
||||
expectedError: "unclosed interpolation string \\(",
|
||||
},
|
||||
{
|
||||
description: "To up (upper) case",
|
||||
subdescription: "Works with unicode characters",
|
||||
|
Loading…
Reference in New Issue
Block a user