Skip to content

Commit

Permalink
parser/keyvalue: handle escaped quotes when parsing
Browse files Browse the repository at this point in the history
Currently, the keyvalue parser does handle escaped quotes and instead
will parse this as independent '\', '"' characters. This results in
unexpected breakages between fields for strings like:
> <key>="...\" ..."
Here, the backslash will be appended to the result pair, while the
(now un-)escaped quotation will result in the pair being terminated early.

Add handling of escaped quotation marks (for both ", ') in the
keyvalue parser along with a testcase to exercise this functionality.

Signed-off-by: Ethan Adams <eadams@netflix.com>
  • Loading branch information
jadams41 committed Nov 4, 2024
1 parent b3d6a93 commit 0a3e582
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 7 deletions.
21 changes: 14 additions & 7 deletions internal/coreinternal/parseutils/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ func SplitString(input, delimiter string) ([]string, error) {
current := ""
delimiterLength := len(delimiter)
quoteChar := "" // "" means we are not in quotes
escaped := false

for i := 0; i < len(input); i++ {
if quoteChar == "" && i+delimiterLength <= len(input) && input[i:i+delimiterLength] == delimiter { // delimiter
Expand All @@ -31,13 +32,19 @@ func SplitString(input, delimiter string) ([]string, error) {
continue
}

if quoteChar == "" && (input[i] == '"' || input[i] == '\'') { // start of quote
quoteChar = string(input[i])
continue
}
if string(input[i]) == quoteChar { // end of quote
quoteChar = ""
continue
if !escaped { // consider quote termination so long as previous character wasn't backslash
if quoteChar == "" && (input[i] == '"' || input[i] == '\'') { // start of quote
quoteChar = string(input[i])
continue
}
if string(input[i]) == quoteChar { // end of quote
quoteChar = ""
continue
}
// Only if we weren't escaped could the next character result in escaped state
escaped = input[i] == '\\' // potentially escaping next character
} else {
escaped = false
}

current += string(input[i])
Expand Down
18 changes: 18 additions & 0 deletions pkg/stanza/operator/parser/keyvalue/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -688,6 +688,24 @@ key=value`,
true,
false,
},
{
"containerd output",
func(_ *Config) {},
&entry.Entry{
Body: `time="2024-11-01T12:38:17.992190505Z" level=warning msg="cleanup warnings time='2024-11-01T12:38:17Z' level=debug msg=\"starting signal loop\" namespace=moby-10000.10000 pid=1608080 runtime=io.containerd.runc.v2" namespace=moby-10000.10000`,
},
&entry.Entry{
Attributes: map[string]any{
"time": "2024-11-01T12:38:17.992190505Z",
"level": "warning",
"msg": `cleanup warnings time='2024-11-01T12:38:17Z' level=debug msg=\"starting signal loop\" namespace=moby-10000.10000 pid=1608080 runtime=io.containerd.runc.v2`,
"namespace": "moby-10000.10000",
},
Body: `time="2024-11-01T12:38:17.992190505Z" level=warning msg="cleanup warnings time='2024-11-01T12:38:17Z' level=debug msg=\"starting signal loop\" namespace=moby-10000.10000 pid=1608080 runtime=io.containerd.runc.v2" namespace=moby-10000.10000`,
},
false,
false,
},
}

for _, tc := range cases {
Expand Down

0 comments on commit 0a3e582

Please sign in to comment.