mirror of
https://github.com/mikefarah/yq.git
synced 2026-07-07 06:10:36 +00:00
fix(strings): don't halve backslashes in interpolated string literals
String literals in expressions have their escapes decoded once by the lexer
(processEscapeCharacters), then interpolate() decoded every backslash pair a
second time, halving runs of backslashes (\\ -> \, \\\\ -> \\). Output
from an expression diverged from the same string read as input, and from jq.
interpolate() only needs to treat a backslash pair as an escape when it guards
an interpolation paren (\\( -> literal \(); a standalone pair must pass
through unchanged. Guard the skip on a following '(' so plain backslash runs
survive, mirroring the lexer's own \\( special case.
Fixes #2561
This commit is contained in:
parent
e95bb7e472
commit
a51671c522
@ -62,8 +62,14 @@ func interpolate(d *dataTreeNavigator, context Context, str string) (string, err
|
|||||||
i++
|
i++
|
||||||
continue
|
continue
|
||||||
case '\\':
|
case '\\':
|
||||||
// skip the escaped backslash
|
// A backslash pair is only an interpolation escape when it
|
||||||
i++
|
// guards an opening paren ("\\(" -> literal "\("). The lexer
|
||||||
|
// (processEscapeCharacters) has already decoded string escapes,
|
||||||
|
// so a standalone pair must pass through unchanged rather than
|
||||||
|
// be halved a second time (#2561).
|
||||||
|
if i+2 < len(runes) && runes[i+2] == '(' {
|
||||||
|
i++ // skip the second backslash; '(' is emitted as literal text next
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
log.Debugf("Ignoring non-escaping backslash @ %v[%d]", str, i)
|
log.Debugf("Ignoring non-escaping backslash @ %v[%d]", str, i)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,6 +29,22 @@ var stringsOperatorScenarios = []expressionScenario{
|
|||||||
"D0, P[], (!!str)::\\\n",
|
"D0, P[], (!!str)::\\\n",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
skipDoc: true,
|
||||||
|
description: "Interpolation - backslashes are not halved (#2561)",
|
||||||
|
expression: `"\\\\"`,
|
||||||
|
expected: []string{
|
||||||
|
"D0, P[], (!!str)::\\\\\n",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
skipDoc: true,
|
||||||
|
description: "Interpolation - odd backslash run preserved (#2561)",
|
||||||
|
expression: `"\\\\\\"`,
|
||||||
|
expected: []string{
|
||||||
|
"D0, P[], (!!str)::\\\\\\\n",
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
skipDoc: true,
|
skipDoc: true,
|
||||||
description: "Interpolation - nested",
|
description: "Interpolation - nested",
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user