this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

cue/literal: allow triple quotes inside multiline string content

The spec says that a multiline string is closed by a matching triple
quote "which must be by itself on a new line, preceded by optional
whitespace". The scanner already enforces this rule, only treating
triple quotes as a closing delimiter when they follow a newline
and optional whitespace.

However, literal.Unquote rejected any triple quote sequence found
in the middle of the string content, even when it clearly wasn't
a closing delimiter (e.g. preceded by non-whitespace characters).
For example, the following valid multiline string was rejected:

"""
0"""
"""

Fix unquoteChar to treat triple quotes as literal quote characters
when they appear in the middle of multiline string content, matching
the scanner's behavior and the spec's grammar.

Found via fuzzing.

Signed-off-by: Daniel Martí <mvdan@mvdan.cc>
Change-Id: I116a1528680cc9b750dec37de2e278f9fb3ec2ab
Reviewed-on: https://cue.gerrithub.io/c/cue-lang/cue/+/1235173
Unity-Result: CUE porcuepine <cue.porcuepine@gmail.com>
TryBot-Result: CUEcueckoo <cueckoo@cuelang.org>
Reviewed-by: Matthew Sackman <matthew@cue.works>

+8 -1
+6 -1
cue/literal/string.go
··· 332 332 } 333 333 } 334 334 if ln := int(info.numChar) + info.numHash; len(s) != ln { 335 - // TODO: terminating quote in middle of string 335 + // For multiline strings, three quotes in the middle of a line 336 + // are literal quote characters, not a closing delimiter. 337 + // The closing delimiter must be on its own line per the spec. 338 + if info.numChar == 3 { 339 + return rune(info.char), false, s[1:], nil 340 + } 336 341 return 0, false, s[ln:], errSyntax 337 342 } 338 343 return terminatedByQuote, false, "", nil
+2
cue/literal/string_test.go
··· 91 91 {`#"This is a "dog""#`, `This is a "dog"`, nil}, 92 92 {"#\"\"\"\n\"\n\"\"\"#", `"`, nil}, 93 93 {"#\"\"\"\n\"\"\"\n\"\"\"#", `"""`, nil}, 94 + {"\"\"\"\n0\"\"\"\n\"\"\"", `0"""`, nil}, 95 + {"'''\n0'''\n'''", `0'''`, nil}, 94 96 {"#\"\"\"\n\na\n\n\"\"\"#", "\na\n", nil}, 95 97 // Gobble extra \r 96 98 {"#\"\"\"\n\ra\n\r\"\"\"#", `a`, nil},