Skip to content

Commit c716d15

Browse files
committed
Fixing parsing of escaped characters in strenv #2506
1 parent e49e588 commit c716d15

File tree

4 files changed

+90
-10
lines changed

4 files changed

+90
-10
lines changed

pkg/yqlib/lexer_participle.go

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -379,15 +379,7 @@ func stringValue() yqAction {
379379
log.Debug("rawTokenvalue: %v", rawToken.Value)
380380
value := unwrap(rawToken.Value)
381381
log.Debug("unwrapped: %v", value)
382-
value = strings.ReplaceAll(value, "\\\"", "\"")
383-
value = strings.ReplaceAll(value, "\\n", "\n")
384-
value = strings.ReplaceAll(value, "\\t", "\t")
385-
value = strings.ReplaceAll(value, "\\r", "\r")
386-
value = strings.ReplaceAll(value, "\\f", "\f")
387-
value = strings.ReplaceAll(value, "\\v", "\v")
388-
value = strings.ReplaceAll(value, "\\b", "\b")
389-
value = strings.ReplaceAll(value, "\\a", "\a")
390-
log.Debug("replaced: %v", value)
382+
value = processEscapeCharacters(value)
391383
return &token{TokenType: operationToken, Operation: &Operation{
392384
OperationType: stringInterpolationOpType,
393385
StringValue: value,

pkg/yqlib/lib.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,22 @@ func parseInt(numberString string) (int, error) {
186186
return int(parsed), err
187187
}
188188

189+
func processEscapeCharacters(original string) string {
190+
value := original
191+
value = strings.ReplaceAll(value, "\\\"", "\"")
192+
value = strings.ReplaceAll(value, "\\n", "\n")
193+
value = strings.ReplaceAll(value, "\\t", "\t")
194+
value = strings.ReplaceAll(value, "\\r", "\r")
195+
value = strings.ReplaceAll(value, "\\f", "\f")
196+
value = strings.ReplaceAll(value, "\\v", "\v")
197+
value = strings.ReplaceAll(value, "\\b", "\b")
198+
value = strings.ReplaceAll(value, "\\a", "\a")
199+
if value != original {
200+
log.Debug("processEscapeCharacters from [%v] to [%v]", original, value)
201+
}
202+
return value
203+
}
204+
189205
func headAndLineComment(node *CandidateNode) string {
190206
return headComment(node) + lineComment(node)
191207
}

pkg/yqlib/operator_env.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ func envOperator(_ *dataTreeNavigator, context Context, expressionNode *Expressi
2929
node = &CandidateNode{
3030
Kind: ScalarNode,
3131
Tag: "!!str",
32-
Value: rawValue,
32+
Value: processEscapeCharacters(rawValue),
3333
}
3434
} else if rawValue == "" {
3535
return Context{}, fmt.Errorf("value for env variable '%v' not provided in env()", envName)

pkg/yqlib/operator_env_test.go

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,78 @@ var envOperatorScenarios = []expressionScenario{
6363
"D0, P[], ()::a: \"12\"\n",
6464
},
6565
},
66+
{
67+
description: "strenv with newline escape",
68+
skipDoc: true,
69+
environmentVariables: map[string]string{"myenv": "string with a\\n"},
70+
expression: `.a = strenv(myenv)`,
71+
expected: []string{
72+
"D0, P[], ()::a: |\n string with a\n",
73+
},
74+
},
75+
{
76+
description: "strenv with tab escape",
77+
skipDoc: true,
78+
environmentVariables: map[string]string{"myenv": "string with a\\t"},
79+
expression: `.a = strenv(myenv)`,
80+
expected: []string{
81+
"D0, P[], ()::a: \"string with a\\t\"\n",
82+
},
83+
},
84+
{
85+
description: "strenv with carriage return escape",
86+
skipDoc: true,
87+
environmentVariables: map[string]string{"myenv": "string with a\\r"},
88+
expression: `.a = strenv(myenv)`,
89+
expected: []string{
90+
"D0, P[], ()::a: \"string with a\\r\"\n",
91+
},
92+
},
93+
{
94+
description: "strenv with form feed escape",
95+
skipDoc: true,
96+
environmentVariables: map[string]string{"myenv": "string with a\\f"},
97+
expression: `.a = strenv(myenv)`,
98+
expected: []string{
99+
"D0, P[], ()::a: \"string with a\\f\"\n",
100+
},
101+
},
102+
{
103+
description: "strenv with vertical tab escape",
104+
skipDoc: true,
105+
environmentVariables: map[string]string{"myenv": "string with a\\v"},
106+
expression: `.a = strenv(myenv)`,
107+
expected: []string{
108+
"D0, P[], ()::a: \"string with a\\v\"\n",
109+
},
110+
},
111+
{
112+
description: "strenv with backspace escape",
113+
skipDoc: true,
114+
environmentVariables: map[string]string{"myenv": "string with a\\b"},
115+
expression: `.a = strenv(myenv)`,
116+
expected: []string{
117+
"D0, P[], ()::a: \"string with a\\b\"\n",
118+
},
119+
},
120+
{
121+
description: "strenv with alert/bell escape",
122+
skipDoc: true,
123+
environmentVariables: map[string]string{"myenv": "string with a\\a"},
124+
expression: `.a = strenv(myenv)`,
125+
expected: []string{
126+
"D0, P[], ()::a: \"string with a\\a\"\n",
127+
},
128+
},
129+
{
130+
description: "strenv with double quote escape",
131+
skipDoc: true,
132+
environmentVariables: map[string]string{"myenv": "string with a\\\""},
133+
expression: `.a = strenv(myenv)`,
134+
expected: []string{
135+
"D0, P[], ()::a: string with a\"\n",
136+
},
137+
},
66138
{
67139
description: "Dynamically update a path from an environment variable",
68140
subdescription: "The env variable can be any valid yq expression.",

0 commit comments

Comments
 (0)