Skip to content

Commit 90dd4de

Browse files
fix(grammar): stop the Swift scanner shifting past the width of an int
The Swift scanner keeps a 64-bit mask of the symbols that suppress a match -- the rule that stops `try!` emitting its `!` as a separate token. It tests one bit per candidate: uint64_t suppressing_symbols = OP_SYMBOL_SUPPRESSOR[full_match]; for (uint64_t suppressor = 0; suppressor < TOKEN_COUNT; suppressor++) { if (!(suppressing_symbols & 1 << suppressor)) { The mask is uint64_t but the literal `1` is an int, so the shift is an int shift. TOKEN_COUNT is larger than 32, so once suppressor reaches 31 the shift runs past the width of the type. That is undefined behavior, and every bit above 31 is tested against a value the standard does not define. Nothing caught it because no test reached the suppressor path until this branch added one: a Swift URL is force-unwrapped, `URL(string: "...")!`, and the trailing `!` is exactly the case the suppressor list exists for. UBSan reports it as: scanner.c:514:47: runtime error: left shift of 1 by 31 places cannot be represented in type 'int' The Windows CLANGARM64 leg runs UBSan in trap mode, which turns the same shift into an illegal-instruction trap rather than a message, so the new test would take that leg down. `1ULL` makes the literal as wide as the mask it is tested against. Refs #1892 Signed-off-by: Joshua Richter <jrichter5781@gmail.com>
1 parent 1f5ecb5 commit 90dd4de

1 file changed

Lines changed: 1 addition & 1 deletion

File tree

  • internal/cbm/vendored/grammars/swift

internal/cbm/vendored/grammars/swift/scanner.c

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)