Commit e199ef3
feat(assail): word-boundary detector for UnboundedAllocation (Task #25)
Core refactor: substring `contains(...)` -> word-boundary regex for
the keyword-based part of the UnboundedAllocation heuristic.
Problems solved:
1. FP closed — the detector tripped on its own variable names
(`has_unbounded_allocations`, `unbounded_vec_patterns`) and on
legitimate `tokio::sync::mpsc::unbounded_channel` usage. Word-
boundary regex (`\bunbounded\b`) does not match when the word
sits inside a longer identifier (trailing `_` is a word char).
2. FN closed — `code_only.contains("limit")` disarmed the read_to_*
check for any file containing `value_delimiter`, `delimiter`, or
any other unrelated token with `limit` as a substring. Observed
on src/main.rs (5 unbounded fs::read_to_string calls that the
old check silently disarmed). Switched to `(?i)\blimit` — matches
`limit`, `Limit`, `LIMIT`, `READ_LIMIT`, `limit_bytes`, and other
word-starting-with-limit forms, does NOT match interior-substring
`delimiter`/`sublimit`/etc.
Helpers added (all OnceLock-initialised regex, compiled once per scan):
has_unbounded_keyword — \b(unbounded|no_bound|no_limit|
boundless|unlimited|unconstrained)\b
has_infinite_word — \binfinite\b
has_recursion_word — \brecursion\b
has_limit_word — (?i)\blimit
Also: added `read_report_bounded()` helper in main.rs and routed the
5 previously-FN-disarmed fs::read_to_string sites through it (64 MiB
cap on report JSON reads).
Self-scan numbers:
Before refactor: UnboundedAllocation 1 critical (analyzer.rs
self-reference FP) + FN'd main.rs
After refactor: UnboundedAllocation 0.
Total critical: 2 -> 1 (remaining 1 is tests/fixtures/example.py
pickle.load — an intentional vulnerability fixture).
Total findings: 11 -> 10.
Regression tests added (4 new, all passing, 190/190 lib tests pass):
analyze_rust_unbounded_as_identifier_substring_does_not_fire
analyze_rust_unbounded_as_bare_identifier_still_fires
analyze_rust_unlimited_does_not_disarm_limit_check
analyze_rust_uppercase_limit_const_disarms_read_check
This is Task #25 step 1 of the plan — detector refinement on assail
before scaling out with Chapel. The substring -> regex move is the
first structural narrowing; AST-level pattern detection (actual
`Vec::with_capacity(n)` with n-from-input, loop-push without break)
remains the target for zero-FN on a curated reference corpus.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>1 parent 804a25d commit e199ef3
2 files changed
Lines changed: 210 additions & 21 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
41 | 41 | | |
42 | 42 | | |
43 | 43 | | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
44 | 108 | | |
45 | 109 | | |
46 | 110 | | |
| |||
889 | 953 | | |
890 | 954 | | |
891 | 955 | | |
892 | | - | |
| 956 | + | |
| 957 | + | |
893 | 958 | | |
894 | 959 | | |
895 | | - | |
896 | | - | |
897 | | - | |
898 | | - | |
899 | | - | |
900 | | - | |
901 | | - | |
902 | | - | |
903 | | - | |
| 960 | + | |
| 961 | + | |
| 962 | + | |
| 963 | + | |
| 964 | + | |
| 965 | + | |
| 966 | + | |
| 967 | + | |
904 | 968 | | |
905 | 969 | | |
906 | | - | |
| 970 | + | |
907 | 971 | | |
908 | | - | |
| 972 | + | |
909 | 973 | | |
910 | 974 | | |
911 | 975 | | |
| |||
6401 | 6465 | | |
6402 | 6466 | | |
6403 | 6467 | | |
| 6468 | + | |
| 6469 | + | |
| 6470 | + | |
| 6471 | + | |
| 6472 | + | |
| 6473 | + | |
| 6474 | + | |
| 6475 | + | |
| 6476 | + | |
| 6477 | + | |
| 6478 | + | |
| 6479 | + | |
| 6480 | + | |
| 6481 | + | |
| 6482 | + | |
| 6483 | + | |
| 6484 | + | |
| 6485 | + | |
| 6486 | + | |
| 6487 | + | |
| 6488 | + | |
| 6489 | + | |
| 6490 | + | |
| 6491 | + | |
| 6492 | + | |
| 6493 | + | |
| 6494 | + | |
| 6495 | + | |
| 6496 | + | |
| 6497 | + | |
| 6498 | + | |
| 6499 | + | |
| 6500 | + | |
| 6501 | + | |
| 6502 | + | |
| 6503 | + | |
| 6504 | + | |
| 6505 | + | |
| 6506 | + | |
| 6507 | + | |
| 6508 | + | |
| 6509 | + | |
| 6510 | + | |
| 6511 | + | |
| 6512 | + | |
| 6513 | + | |
| 6514 | + | |
| 6515 | + | |
| 6516 | + | |
| 6517 | + | |
| 6518 | + | |
| 6519 | + | |
| 6520 | + | |
| 6521 | + | |
| 6522 | + | |
| 6523 | + | |
| 6524 | + | |
| 6525 | + | |
| 6526 | + | |
| 6527 | + | |
| 6528 | + | |
| 6529 | + | |
| 6530 | + | |
| 6531 | + | |
| 6532 | + | |
| 6533 | + | |
| 6534 | + | |
| 6535 | + | |
| 6536 | + | |
| 6537 | + | |
| 6538 | + | |
| 6539 | + | |
| 6540 | + | |
| 6541 | + | |
| 6542 | + | |
| 6543 | + | |
| 6544 | + | |
| 6545 | + | |
| 6546 | + | |
| 6547 | + | |
| 6548 | + | |
| 6549 | + | |
| 6550 | + | |
| 6551 | + | |
| 6552 | + | |
| 6553 | + | |
| 6554 | + | |
| 6555 | + | |
| 6556 | + | |
| 6557 | + | |
| 6558 | + | |
| 6559 | + | |
| 6560 | + | |
| 6561 | + | |
| 6562 | + | |
| 6563 | + | |
| 6564 | + | |
| 6565 | + | |
| 6566 | + | |
| 6567 | + | |
| 6568 | + | |
| 6569 | + | |
| 6570 | + | |
| 6571 | + | |
| 6572 | + | |
| 6573 | + | |
| 6574 | + | |
| 6575 | + | |
| 6576 | + | |
| 6577 | + | |
6404 | 6578 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
49 | 49 | | |
50 | 50 | | |
51 | 51 | | |
52 | | - | |
53 | | - | |
| 52 | + | |
| 53 | + | |
54 | 54 | | |
55 | 55 | | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
56 | 73 | | |
57 | 74 | | |
58 | 75 | | |
| |||
1609 | 1626 | | |
1610 | 1627 | | |
1611 | 1628 | | |
1612 | | - | |
| 1629 | + | |
1613 | 1630 | | |
1614 | 1631 | | |
1615 | 1632 | | |
| |||
1633 | 1650 | | |
1634 | 1651 | | |
1635 | 1652 | | |
1636 | | - | |
| 1653 | + | |
1637 | 1654 | | |
1638 | 1655 | | |
1639 | 1656 | | |
| |||
1646 | 1663 | | |
1647 | 1664 | | |
1648 | 1665 | | |
1649 | | - | |
| 1666 | + | |
1650 | 1667 | | |
1651 | 1668 | | |
1652 | 1669 | | |
1653 | 1670 | | |
1654 | 1671 | | |
1655 | | - | |
| 1672 | + | |
1656 | 1673 | | |
1657 | 1674 | | |
1658 | 1675 | | |
| |||
1865 | 1882 | | |
1866 | 1883 | | |
1867 | 1884 | | |
1868 | | - | |
1869 | | - | |
1870 | | - | |
| 1885 | + | |
1871 | 1886 | | |
1872 | 1887 | | |
1873 | 1888 | | |
| |||
0 commit comments