mirror of
https://github.com/mikefarah/yq.git
synced 2025-01-13 11:55:38 +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++ {
|
for i := 0; i < len(runes); i++ {
|
||||||
char := runes[i]
|
char := runes[i]
|
||||||
if !inExpression {
|
if !inExpression {
|
||||||
if char == '\\' && i != len(runes)-1 && runes[i+1] == '(' {
|
if char == '\\' && i < len(runes)-1 {
|
||||||
inExpression = true
|
switch runes[i+1] {
|
||||||
i = i + 1 // skip over the next open bracket
|
case '(':
|
||||||
continue
|
inExpression = true
|
||||||
|
// 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)
|
sb.WriteRune(char)
|
||||||
} else { // we are in an expression
|
} else { // we are in an expression
|
||||||
if char == ')' && nestedBracketsCounter == 0 {
|
if char == ')' {
|
||||||
// finished the expression!
|
if nestedBracketsCounter == 0 {
|
||||||
log.Debugf("Expression is :%v", expSb.String())
|
// finished the expression!
|
||||||
value, err := evaluate(d, context, expSb.String())
|
log.Debugf("Expression is :%v", expSb.String())
|
||||||
if err != nil {
|
value, err := evaluate(d, context, expSb.String())
|
||||||
return "", err
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
inExpression = false
|
||||||
|
expSb = strings.Builder{} // reset this
|
||||||
|
|
||||||
|
sb.WriteString(value)
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
nestedBracketsCounter--
|
||||||
inExpression = false
|
|
||||||
expSb = strings.Builder{} // reset this
|
|
||||||
|
|
||||||
sb.WriteString(value)
|
|
||||||
continue
|
|
||||||
} else if char == '(' {
|
} else if char == '(' {
|
||||||
nestedBracketsCounter++
|
nestedBracketsCounter++
|
||||||
} else if char == '\\' && i != len(runes)-1 && runes[i+1] == ')' {
|
} else if char == '\\' && i < len(runes)-1 {
|
||||||
// close brackets is escaped, skip over it
|
switch esc := runes[i+1]; esc {
|
||||||
expSb.WriteRune(char)
|
case ')', '\\':
|
||||||
expSb.WriteRune(runes[i+1])
|
// write escaped character
|
||||||
i = i + 1
|
expSb.WriteRune(esc)
|
||||||
continue
|
i++
|
||||||
} else if char == ')' {
|
continue
|
||||||
nestedBracketsCounter--
|
default:
|
||||||
|
log.Debugf("Ignoring non-escaping backslash @ %v[%d]", str, i)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
expSb.WriteRune(char)
|
expSb.WriteRune(char)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if inExpression {
|
if inExpression {
|
||||||
return "", fmt.Errorf("unclosed interpolation string \\(")
|
return "", fmt.Errorf("unclosed interpolation string \\(")
|
||||||
|
@ -26,7 +26,7 @@ var stringsOperatorScenarios = []expressionScenario{
|
|||||||
description: "Interpolation - just escape",
|
description: "Interpolation - just escape",
|
||||||
expression: `"\\"`,
|
expression: `"\\"`,
|
||||||
expected: []string{
|
expected: []string{
|
||||||
"D0, P[], (!!str)::\\\\\n",
|
"D0, P[], (!!str)::\\\n",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -47,6 +47,15 @@ var stringsOperatorScenarios = []expressionScenario{
|
|||||||
"D0, P[], (!!str)::Hi (.value)\n",
|
"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,
|
skipDoc: true,
|
||||||
description: "Interpolation - random close bracket",
|
description: "Interpolation - random close bracket",
|
||||||
@ -63,6 +72,13 @@ var stringsOperatorScenarios = []expressionScenario{
|
|||||||
expression: `"Hi \("`,
|
expression: `"Hi \("`,
|
||||||
expectedError: "unclosed interpolation string \\(",
|
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",
|
description: "To up (upper) case",
|
||||||
subdescription: "Works with unicode characters",
|
subdescription: "Works with unicode characters",
|
||||||
|
Loading…
Reference in New Issue
Block a user