You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 475db1e
Browse filesBrowse the repository at this point in the historyBrowse files
Copy file name to clipboardExpand all lines: internal/cbm/vendored/grammars/MANIFEST.md
+1Lines changed: 1 addition & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -111,6 +111,7 @@ row instead.
111
111
| purescript |`purescript/scanner.c`, serialize | guard `memcpy(buffer, indents->data, to_copy)` with `if (to_copy > 0)`| UBSan: zero-length `memcpy` with a NULL/0-size source when the indent vector is empty (formal UB, harmless) |
112
112
| plsql |`plsql/parser.c`, include |`#include <tree_sitter/parser.h>` → `#include "tree_sitter/parser.h"`| The older ABI-14 generator emits angle brackets; every other vendored grammar uses the quoted form, which resolves the per-grammar `tree_sitter/` header from the including file's directory |
113
113
| properties | `properties/scanner.c`, whole file | move the `reached_eof` flag out of a file-scope `static bool` and into a per-parser payload allocated by `..._external_scanner_create()` | **Data race, and the only one of its kind in 103 vendored scanners.** That flag is how the scanner refuses to emit a second end-of-input `FAKE_EOL`, and upstream keeps it in ONE process-wide object. With several worker threads indexing `.properties` files at once, whichever reached EOF first set the flag, so another thread's `!reached_eof` was false and its parse never received the `FAKE_EOL` it needed to finish — it sat at end-of-input asking for a token that would never arrive. Measured 2026-09-19: ~106 M parse operations on a 253-byte file before the per-file budget stopped it, after which the file was dropped from the graph and java/kotlin indexes differed run to run. Interleaved A/B under identical load, 40 runs each: unpatched 6 stalls, patched 0. The serialize/deserialize wire format is unchanged (the state is still the returned length). Upstream `6310671b24d4` still carries the static, so a re-vendor must re-apply this |
114
+
| wit |`wit/scanner.c`, `..._external_scanner_create`|`{}` → `{ return NULL; }`|**Uninitialized read (MSan).** The function returns `void *` but had no `return`, and tree-sitter's runtime stores the result as the scanner payload, so every WIT parse used an indeterminate value (C11 6.9.1p12 makes that undefined). The scanner never reads its payload, so ordinary builds were unaffected, and the vendored build's `-w` hid `-Wreturn-type`. Under MSan the report of this read crashed and posed as a "stack-overflow", which is why five grammar/pipeline suites were excluded from the MSan lane. Upstream bytecodealliance/tree-sitter-wit still carries it at `059bfdd1af72` (2025-06-23, the last change to `src/scanner.c`) |
114
115
| swift |`swift/scanner.c`, `OP_SYMBOL_SUPPRESSOR` + `eat_operators`|`1UL <<` / `1 <<` → `1ULL <<`| UBSan: `1 << suppressor` shifts an `int` by up to `TOKEN_COUNT` bits, undefined once the index reaches 31, while the mask it feeds is `uint64_t`. `1UL << FAKE_TRY_BANG` is the same defect on Windows, where `unsigned long` is 32 bits and `FAKE_TRY_BANG` is 32; the CLANGARM64 leg runs UBSan in trap mode, so there it is an illegal instruction rather than a log line. Upstream already carries both changes: `fb63a7004f07` (2026-04-06, upstream #558) for `eat_operators`, `6ab8d1d74ebd` (2026-08-10) for the `OP_SYMBOL_SUPPRESSOR` entry. Our pin `8abb3e8b3325` (2026-03-20) predates both, so this is a backport rather than a local invention — a re-vendor past 2026-08-10 should delete this row, not re-apply it |
0 commit comments