fix(reliability): preflight clipboard size and traversal budget - #359
fix(reliability): preflight clipboard size and traversal budget#359cursor[bot] wants to merge 19 commits into
Conversation
Add exact RED regressions for oversized UTF-8 encoding and broad-source child materialization on current protected main. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Reject oversized UTF-16 clipboard HTML before UTF-8 allocation and reject broad source trees before child materialization, preserving existing redacted error codes on current protected main. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
There was a problem hiding this comment.
Assessment
This is a current-main successor for clipboard UTF-8 and maxNodes preflight (#163 / #327). The production change is the right shape:
sourceHtml.length > maxHtmlBytesshort-circuits beforeTextEncoder.prototype.encode.assertTraversalCapacity(visited + queued + enqueueable)runs beforeNodeList.item().- Closed-
detailsuses the same queue invariant. - Redacted codes/messages are unchanged.
- Doctoring uses APA 7th citations (Unicode 16.0 §3.9, ECMA-262 string length, WHATWG DOM, CWE-770, Clipboard API WD) and tells the host to raise only the matching ceiling.
Writer conflict
Issue #327 still names Draft #164 as the sole SafeClipboard writer. #164’s live base is stale (50ac98c, not current main@e8109ec) and also carries hostile-throw branding plus release-workflow convergence. Draft #351 remains the current-main writer for clipboard throw-value containment (#349).
Prefer this PR for the resource-preflight product change on current main. Keep #164 unmerged. Do not fold throw-value or release-workflow work into this branch.
Next action
- Keep Draft/unmerged while #118 owns
v0.6.0. - Re-verify exact-head CI/Security/SAST on the unchanged head before any Ready decision.
- If a paste is rejected with
input_too_largeornode_limit_exceeded, measure a trusted source and raise only that ceiling.
Sent by Cursor Automation: Fix Issues
|
Exact-head local validation for 9ab6980: seven clipboard preflight, guidance, adapter, and documentation contract files reached 28/30 tests passed. Two failures are stale expectations in SafeClipboardPreflightSize.test.ts and SafeClipboardTraversalBudget.test.ts: the implementation returns the current actionable messages for input_too_large and node_limit_exceeded, while those tests still expect the former generic messages. The PR is dirty and this validation did not modify its branch. |
… into clipboard-preflight-local # Conflicts: # CHANGELOG.md # docs/TRACEABILITY.md
|
Restacked onto exact parent #351 head Integration repair:
Fresh verification:
This remains draft and dependency-gated by #351/#118. @codex review |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
Adopt the parent single-writer repair without rewriting the child history. The clipboard resource preflight delta remains isolated above the updated parent. Signed-off-by: Seongho Bae <seonghobae@users.noreply.github.com> Commit-Message-Assisted-by: Claude (via Claude Code)
Signed-off-by: Seongho Bae <me@seonghobae.me>
Signed-off-by: Seongho Bae <me@seonghobae.me>
Signed-off-by: Seongho Bae <me@seonghobae.me>
Signed-off-by: Seongho Bae <me@seonghobae.me>
Native follow-up to the jsdom capacity profileUnchanged head The existing 3,000-paragraph synthetic unit fixture was executed once per engine, serially in fresh contexts through the public packed browser harness:
All acquisitions retained the 20-second network-idle guard and checked 3,000 document paragraphs, 3,000 output paragraphs/strong elements, first/last text, no class/style attributes, no sanitizer error, and zero external HTTP requests. Command exit 0; owned server stopped afterward. This interval includes editor construction, clipboard transformation, document parsing, JSON extraction, and destruction. It is not sanitizer-only time, not the canonical 800-paragraph browser fixture, and not a customer workload or p95 measurement. Host contention is uncontrolled. These three observations do not reproduce the 5-second unit timeout in native engines and do not establish its cause or a speedup. The failed canonical full coverage and browser acquisitions above remain failed. Retained protocol, runnable probe and all three results: |


Closes #163.
Closes #327.
Scope and stack ownership
This Draft is the canonical SafeClipboard resource-preflight owner: reject obviously oversized strings before UTF-8 allocation and enforce visited+queued+enqueueable node capacity before child materialization. It preserves deterministic allowlist reconstruction, source order, hidden-subtree rules, fail-closed errors and actionable redacted customer guidance. Hostile thrown-value containment remains with prerequisite #351; its source is inherited through the existing stack, not duplicated.
Protected implementation authority remains main@
0b88c16f14f51b54a87eb7164f0edfb06dd60902. The live base isfix/clipboard-hostile-throw-349atcff066f0c3a0b61d7d0964b7d5642402b732420f(Draft #351). Candidate36037015e3715d9c1590438bafde888d62487f86normally descends from remote predecessorbb3187ce98f0769d1d6b08ceebb7e829d9f1f951. No force/amend/reset, ownership change, dependency change, new public API, altered limits, or weakened deadlines/coverage thresholds.Accepted-child list reuse — 2026-09-07
Test-first
9061addbfec9d3880f6e5daac31fc1364cbf57cfreproduced4 childNodes getter reads for a three-child fragment (1failed/1passed, exact output unchanged).ea65e3bf0776646f83aaf7c27b156cd6697174beadds one local reference in the shared enqueue function, preserving the existing capacity check before item reads and reverse-order stack traversal. The regression now requires1 getter read.1ca6ed3crecords the Proposed result and limitations in the existing doctoring record.The DOM Standard defines childNodes as a SameObject NodeList attribute; reusing its live native reference does not make a copied document snapshot or a new cache. WHATWG DOM. This proves reduced property access, not a measured buyer-latency improvement or the cause of earlier Word-capacity timeouts.
Expanded clipboard coverage at ea65e3b retained 50 passed / 1 failed / 51 tests in 15 files, 27.09s. The failure is the existing 5000ms Word-capacity timeout; the chained TypeScript command did not run. Independent TypeScript then passed, and the getter/preflight plus unchanged full 3000-paragraph capacity diagnostic passed 4 tests in 3.97s. This focused result does not erase the failed broader acquisition. Full unchanged default coverage at1ca6ed3c terminated exit1: 861 passed / 32 failed / 893 tests, 162 files, 793.78s. All 32 failures are existing 5000ms timeouts across multiple editor/collaboration/autosave/clipboard cases; no cause is inferred and no deadlines are relaxed. Internal read-only review through1ca6ed3c found no actionable defect, but is not GitHub approval.
Final36037015 only renames the regression's local binding to sourceChildren; runtime, documents and manifests are unchanged. Its two regression tests, independent TypeScript and complete package verification passed. The fresh archive is byte-identical to the successful1ca6ed3c build, SHA-256
77b60ab6903a6124f167dc8f55567ae530db5ee2bbcccf481d698193ae5be4aa. A public packed synthetic unit probe passed: one accepted fragment-list read, zero child-item reads on capacity rejection, exact output order retained. That probe uses installed peers; independent consumer proof comes from complete package verification. Normal push and independent remote SHA check confirm36037015. Current-head full-suite, browser, Office, hosted and release acceptance remain unproven. Evidence and failed attempts:/private/tmp/inkspan-pr359-child-list.2yBMyH.Preserved earlier test-first history
Current36037015 full configured coverage is now terminal and failed (exit1): 890 passed / 3 failed / 893 tests, 162 files, 339.21s. Toolbar affordance invocation, autosave schema-evidence value-count traversal, and Word capacity each exceeded the unchanged5000ms timeout. All inputs and assertions remain; the smaller failure count versus the predecessor does not establish causality or a performance gain. No full coverage/browser/Office/hosted/release acceptance is claimed. The internal reviewer also checked the exact test-only1ca6ed3c..3603701 follow-up and found no actionable defect; this is not formal GitHub approval.
51f9edfdff7de9072cafa8cebaf068dc39f92208: oversized ASCII still reached TextEncoder; broad fragment exceeded traversal budget only after excess child-item reads.71654a8e59eecd72f2a23ebec173e4e537c927d9; original doctoring58f004e5053e2a9b686814b4b9c724ab389a83ec.37105d712c774b7ef638315d7d691311fd52c1adand repaird0255ecb05e77b3c98f365c51fc3a15c630c736apreserve stable machine-readable rejection codes while giving customers bounded next actions.4cfa7eff674c8d66dd1e10b61beba6324ca307a7,8185d86a413c216335b4f9a10521ef5beead8d3f,47032a59c2cd2fc040c00793dcf819f44577acd3and the later ordinary stack synchronization remain retained. Old head/base/workflow snapshots are historical, not current evidence.Remaining gates
Current36037015 canonical packed-browser gate failed (exit1):49passed/1failed/20notrun/70total,0flaky,113.593014s. Firefox active-script timed out in the unchanged20s afterEach networkidle wait; missing Firefox/consensus receipts remain non-passing. Chromium/WebKit receipts and all logs are retained. Three workers, zero retries, fixtures, assertions and startup/test limits were unchanged. Built CSS matched the exact77b60ab6 packed stylesheet. Shared browser-teardown diagnosis stays with #380; no bypass is copied into this sanitizer lane.
Keep Draft pending the canonical prerequisite order and applicable exact-head independent review/check/security/package/browser/release evidence. Missing, pending, skipped, stale and predecessor checks are non-passing. Internal read-only agent review does not provide GitHub approval. No self-approval, CODEOWNERS gate re-enablement, admin bypass or fabricated status is authorized. #118 remains the version-neutral next-stable release/publication authority; no current package is declared published. No transport, credentials, authentication, tenancy, durable persistence/audit, model or deployment authority is added.
Clipboard capacity profiling — 2026-09-07
At unchanged36037015, the exact two-case Word-capacity unit file printed2passing cases (3000paragraph case1372ms), but the overall CPU-profile command required cleanup of two confirmed-owned idle worker processes and terminated exit1 with a Node/tinypool cleanup exception. It is not an unassisted passing gate. The completed worker profile retained479sanitizer-subtree samples, including58own CSSStyleDeclaration-constructor samples with parsing and output-element construction ancestors. This identifies jsdom construction cost in that acquisition, not a proved native-browser bottleneck or the cause of prior capacity timeouts. Existing thresholds, fixtures, guards, source and dependencies remain unchanged. Full failures are retained; no speed improvement or acceptance upgrade is claimed. Protocol, exact command, terminal log and read-only profile summarizer:
/private/tmp/inkspan-clipboard-profile.Cxmh7O.