this repo has no description
0
fork

Configure Feed

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

cue/scanner: reject __# as an invalid identifier

The fuzzer found that "__#" was accepted as a single identifier token,
but the spec grammar only allows "#" or "_#" as identifier prefixes:

identifier = [ "#" | "_#" ] letter { letter | unicode_digit } .

"__#foobar" does not match this grammar: the "#" cannot appear after "__"
since it is only valid at the start as part of the "#" or "_#" prefix.

The root cause was scanFieldIdentifier consuming an optional "_" before
an optional "#", allowing both to be consumed together. This created
the "__#" pattern when combined with the initial "_" from the caller.

Fix by removing the separate "_" consumption in scanFieldIdentifier,
since "_" is already handled by the main identifier character loop.
The scanner now reports "__#..." as an illegal token, matching how
"_|" without a trailing "_" is already reported as illegal.

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

+9 -4
+6 -3
cue/scanner/scanner.go
··· 190 190 191 191 func (s *Scanner) scanFieldIdentifier() string { 192 192 offs := s.offset 193 - if s.ch == '_' { 194 - s.next() 195 - } 196 193 if s.ch == '#' { 197 194 s.next() 198 195 // TODO: remove this block to allow #<num> ··· 760 757 } else { 761 758 tok = token.IDENT 762 759 lit = "_" + s.scanFieldIdentifier() 760 + if lit == "__" && s.ch == '#' { 761 + s.next() // consume '#' 762 + lit += "#" + s.scanIdentifier() 763 + s.errf(s.file.Offset(pos), "illegal token %q", lit) 764 + tok = token.ILLEGAL 765 + } 763 766 } 764 767 insertEOL = true 765 768
+1 -1
cue/scanner/scanner_test.go
··· 81 81 {token.IDENT, "__foobar", literal}, 82 82 {token.IDENT, "#_foobar", literal}, 83 83 {token.IDENT, "_#foobar", literal}, 84 - {token.IDENT, "__#foobar", literal}, 85 84 {token.IDENT, "a۰۱۸", literal}, 86 85 {token.IDENT, "foo६४", literal}, 87 86 {token.IDENT, "bar9876", literal}, ··· 682 681 {`^`, token.ILLEGAL, 0, "", "illegal character U+005E '^'"}, 683 682 {`…`, token.ILLEGAL, 0, "", "illegal character U+2026 '…'"}, 684 683 {`_|`, token.ILLEGAL, 0, "", "illegal token '_|'; expected '_'"}, 684 + {`__#foobar`, token.ILLEGAL, 0, "", `illegal token "__#foobar"`}, 685 685 686 686 {`@`, token.ATTRIBUTE, 1, `@`, "invalid attribute: expected '('"}, 687 687 {`@foo`, token.ATTRIBUTE, 4, `@foo`, "invalid attribute: expected '('"},
+2
cue/testdata/fuzz/FuzzStandaloneCUE/ed58d3678860c299
··· 1 + go test fuzz v1 2 + string("__#")