Repository navigation
fix(typescript): vendor ZapCode on every target and cap padStart/padEnd - #2909
Conversation
zapcode-core 1.5.1 collects padStart/padEnd padding with no size check, so 'a'.padStart(2**40) reserves ~1 TiB and the failed allocation aborts the host process with every tenant (security audit F5). Native builds now use the in-tree ZapCode copy the browser build already used (renamed zapcode_browser -> zapcode_vendor) and drop the registry crate; the copy carries a marked fork edit capping the target length at 10,000,000 like upstream repeat. The drift check lists fork edits and rejects unlisted markers. TM-TS-025.
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
bashkit | 7277537 | Commit Preview URL Branch Preview URL |
Nov 10 2026, 08:56 PM |
There was a problem hiding this comment.
Review of the vendored-ZapCode + padStart/padEnd cap change. The security goal holds: a huge length now returns AllocationLimitExceeded (exit 1, clean stderr) instead of aborting the host, the vendor inventory is hash-pinned with license retained and no host FS/net/process access, and the threat-model test covers both methods plus the happy path. Two worth-considering unit inconsistencies below; nothing blocking.
Review summary (head
|
Requested by Михайло · project thread
What changed
ts/nodepadStart/padEndwith a target length above 10,000,000 now fail the run with an allocation-limit error (exit != 0) instead of aborting the whole host process. Same cap upstream already applies torepeat.zapcode_browser→zapcode_vendor). The registryzapcode-coredependency is gone. The fix is a markedbashkit fork:edit in that copy.scripts/check_zapcode_vendor.py, CI) lists fork edits explicitly and fails on any unlisted marker or drifted edit, on top of the existing upstream hash check.Why
Security audit run-1 F5 (High), re-confirmed on main during the pre-release check: zapcode-core 1.5.1, which is still the latest on crates.io, collects
pad.chars().cycle().take(target_len)unchecked. Because of that,'a'.padStart(2**40)reserves about 1 TiB, and the failed allocation aborts the process along with every tenant in it. The only way to fix it is to patch ZapCode, and a crates.io fork (likebashkit-monty) isn't needed because the copy ships insidebashkit.Before / After
Before, with a wheel built from main (
BashTool(typescript=True)):New test
threat_ts_pad_huge_length_fails_cleanlybefore the fix:process didn't exit successfully ... (signal: 6, SIGABRT).After: the test passes. Both methods fail cleanly with empty stdout, and normal padding (
'7'.padStart(3,'0'), multi-char pad) still prints007|abxyx.Local runs:
cargo clippy -p bashkit --features typescript --all-targets -D warningsis clean, the typescript/ts/zapcode lib and integration tests pass (348 + 337), thetypescript_external_functionsexample runs, and the drift check passes (it fails when the fork edit is altered). Cargo.lock only loseszapcode-core.Risk
std::timeon native. Wasm targets are covered by CI.ZapcodeValueis now the vendored type on every target. It's the same shape, only the crate path differs.Checklist
🤖 Generated with Claude Code