fix(shared): return "" from sliceUtf16Safe when end <= start, matching native .slice#100014
fix(shared): return "" from sliceUtf16Safe when end <= start, matching native .slice#100014Simon-XYDT wants to merge 1 commit into
Conversation
|
Codex review: needs maintainer review before merge. Reviewed July 5, 2026, 7:58 AM ET / 11:58 UTC. Summary PR surface: Source -2, Tests 0. Total -2 across 2 files. Reproducibility: yes. A direct current-main Node import reproduced Review metrics: 1 noteworthy metric.
Root-cause cluster Members:
Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything. Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Risk before merge
Maintainer options:
Next step before merge
Maintainer decision needed
Security Review detailsBest possible solution: Land the narrow helper and test change after maintainer acceptance that this exported helper should follow native Do we have a high-confidence way to reproduce the issue? Yes. A direct current-main Node import reproduced Is this the best way to solve the issue? Yes, with maintainer compatibility sign-off. Returning before surrogate-boundary adjustment when AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 0fc29969d960. Label changesLabel justifications:
Evidence reviewedPR surface: Source -2, Tests 0. Total -2 across 2 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
|
…g native .slice sliceUtf16Safe silently swapped reversed bounds (to < from) instead of returning "" like String.prototype.slice, creating a subtle footgun for callers with dynamic start/end pairs. Caller scan across src/, extensions/, and packages/ confirmed no production code relies on the old swap behavior — all callers use (text, 0, N) or (text, -N) forms only. Co-Authored-By: Claude Opus 4.6 <[email protected]>
65849dd to
dcd4589
Compare
Summary
sliceUtf16Safesilently swaps reversed slice bounds instead of returning""likeString.prototype.slice, creating a subtle logic-corruption footgun for callers that compute dynamic start/end pairs. Removed the swap branch and madeto <= fromreturn""to match native.slicesemantics.sliceUtf16Safe("hello", 4, 1)returns"ell"while"hello".slice(4, 1)returns""return ""when normalized end <= startsrc/shared/utf16-slice.ts(remove swap, add early return),src/shared/utf16-slice.test.ts(update reversed-bounds expectation)Change Type (select all)
Scope (select all)
Linked Issue/PR
Motivation
sliceUtf16Safeis documented as a surrogate-safe drop-in substitute forString.prototype.sliceand is widely re-exported throughsrc/utils.tsand plugin SDK surfaces. When end < start after normalization it swaps the bounds and returns a non-empty substring, whereas native.slicereturns"". This violates the documented drop-in contract and can cause subtle data corruption for any caller that computes dynamic start/end pairs where the end can land before the start.Real behavior proof
sliceUtf16Safenow returns""for reversed normalized bounds, matchingString.prototype.slicefix/utf16-slice-reversed-bounds-99980sliceUtf16Safe("hello", 4, 1)now returns"", matching native.sliceRoot Cause (if applicable)
Original implementation at
src/shared/utf16-slice.ts:22used a silent swap (if (to < from) { const tmp = from; from = to; to = tmp; }) instead of returning an empty string. This was inconsistent withString.prototype.slicesemantics and created a footgun for callers with computed bounds.Regression Test Plan (if applicable)
N/A — existing 18-test suite covers all surrogate-safe edge cases. The only expectation change is the reversed-bounds test.
User-visible / Behavior Changes
None. No production caller passes reversed normalized bounds (
end < start). All callers use(text, 0, N)or(text, -N)forms.Security Impact
Human Verification (required)
Compatibility / Migration
Best-fix Verdict
""whento <= from, which is exactly how nativeString.prototype.sliceworks.AI Assistance 🤖
Risks and Mitigations
(text, 0, N)or(text, -N)forms only; no caller passes reversed bounds.src/,extensions/, andpackages/verified no production code relies on the old swap behavior.Fixes #99980