From 9414a7fd024dba6c70c3c204e7a98dd807572f4a Mon Sep 17 00:00:00 2001 From: Rose Hogenson Date: Mon, 1 Dec 2025 11:20:16 -0800 Subject: Allow octal and hex escapes to take fewer digits --- ccl.go | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) (limited to 'ccl.go') diff --git a/ccl.go b/ccl.go index 17cb5e9..5d37310 100644 --- a/ccl.go +++ b/ccl.go @@ -60,7 +60,7 @@ // // Backslash characters inside a string are interpreted as an escape sequence. // Any escape sequence not described below is an error. The escape sequences -// are identical to C11, with the exception that \x always takes exactly 2 +// are identical to C11, with the exception that \x takes at most 2 // hex characters. // // \' single quote 0x27 @@ -409,14 +409,17 @@ func (p *parser) unescape(rawStr []byte) ([]byte, error) { } case 'x': i++ - if i+2 > len(rawStr) { - return nil, p.error("invalid hex escape %q", rawStr[i-2:min(i+2, len(rawStr))]) + end := i + for ; end < i+2 && end < len(rawStr) && ('0' <= rawStr[end] && rawStr[end] <= '9' || 'a' <= rawStr[end] && rawStr[end] <= 'f' || 'A' <= rawStr[end] && rawStr[end] <= 'F'); end++ { } - n, err := strconv.ParseUint(string(rawStr[i:i+2]), 16, 8) + if end == i { + return nil, p.error("invalid hex escape %q", rawStr[i-2:end]) + } + n, err := strconv.ParseUint(string(rawStr[i:end]), 16, 8) if err != nil { - return nil, p.error("invalid hex escape %q: %s", rawStr[i-2:i+2], err) + return nil, p.error("invalid hex escape %q (unreachable)", rawStr[i-2:end]) } - i++ + i = end - 1 b = []byte{byte(n)} case 'u', 'U': nBytes := 4 @@ -434,14 +437,17 @@ func (p *parser) unescape(rawStr []byte) ([]byte, error) { i += nBytes - 1 b = utf8.AppendRune(nil, rune(n)) default: - if i+3 > len(rawStr) { + end := i + for ; end < i+3 && end < len(rawStr) && '0' <= rawStr[end] && rawStr[end] <= '7'; end++ { + } + if end == i { return nil, p.error("invalid string escape %q", rawStr[i-1:i+1]) } - n, err := strconv.ParseUint(string(rawStr[i:i+3]), 8, 8) + n, err := strconv.ParseUint(string(rawStr[i:end]), 8, 8) if err != nil { - return nil, p.error("invalid octal escape %q: %s", rawStr[i-1:i+3], err) + return nil, p.error("invalid octal escape %q: %s", rawStr[i-1:end], err) } - i += 2 + i = end - 1 b = []byte{byte(n)} } escaped = append(escaped, b...) -- cgit v1.3.1