Skip to content

Bump WebKit: reject non-ASCII identity escapes in unicode RegExp patterns - #40459

Closed
robobun wants to merge 1 commit into
mainfrom
farm/0643fce0/regexp-unicode-identity-escape
Closed

robobun wants to merge 1 commit into
mainfrom
farm/0643fce0/regexp-unicode-identity-escape

Conversation

@robobun

@robobun robobun commented Aug 25, 2026 •

Copy link
Copy Markdown
Collaborator

Problem

  • new RegExp("\\Ç", "u") compiles, and /\Ç/u matches Ç with the Annex B meaning. ECMA-262 requires a SyntaxError: IdentityEscape under the u or v flag allows only SyntaxCharacter or /, plus ClassSetReservedPunctuator inside v-mode class sets. All of those are ASCII. V8 and SpiderMonkey throw. Fixes u/v-mode identity-escape validation is ASCII-only #40441.
  • The cause is isIdentityEscapeAnError in Yarr (Source/JavaScriptCore/yarr/YarrParser.h:860 in oven-sh/WebKit). The error condition is gated on isASCII(ch) because strchr only handles bytes, so any non-ASCII escape skips validation.

Fix

  • The engine fix is Yarr: reject non-ASCII identity escapes in unicode patterns WebKit#517: treat any non-ASCII character as an invalid identity escape in unicode and unicode-sets patterns. One condition changes, non-unicode patterns are untouched.
  • This PR bumps WEBKIT_VERSION to that PR's preview build (autobuild-preview-pr-517-f390a25a) and adds test/js/bun/jsc/webkit-upgrade-f390a25a.test.ts. After Yarr: reject non-ASCII identity escapes in unicode patterns WebKit#517 merges, the pin should move to the merged sha.
  • Verified: the new test fails on bun 1.4.1 (\Ç, \é, \字, astral escapes, in and out of classes, with u and v) and passes with the bump. Also ran test/js/bun/jsc/ and the regexp jsc-stress fixtures.

Background

  • Yarr is JavaScriptCore's regex engine. Bun vendors JSC through the oven-sh/WebKit fork and downloads prebuilt libraries pinned by WEBKIT_VERSION in scripts/build/deps/webkit.ts.
  • An identity escape is \ followed by a character that stands for itself. Annex B lets non-unicode patterns escape almost anything. The u and v flags removed that laxness so escapes stay forward-compatible.
  • The engine PR includes a JSTests stress test (regexp-unicode-identity-escape-non-ascii.js) that covers the same matrix inside the fork's own test suite.
Notes
  • Gate note: the fix lives in the WebKit prebuilt, selected by scripts/build/deps/webkit.ts. A src/-only stash keeps the bump, so a mechanical fail-before run of the test still passes. The fail-before proof is: USE_SYSTEM_BUN=1 bun test test/js/bun/jsc/webkit-upgrade-f390a25a.test.ts fails 1 of 3 on 1.4.1, and the same file passes under bun bd with this branch.
  • Verified the fix directly against a local JSCOnly debug build of the fork: 24 checks covering throw and no-throw cases pass; the same script fails on the unfixed engine.
  • test/js/bun/jsc/domjit.test.ts shows 10 timeout failures locally in the debug ASAN build on a capped-core container (the same tests pass earlier in the same file in 1 to 4 s, the JIT-warmup repeat pass exceeds the 5 s budget). The Yarr change only runs at RegExp compile time and does not touch those paths.
  • Every other call site of isIdentityEscapeAnError passes an ASCII literal, so only the IdentityEscape default case in parseEscape changes behavior. \- inside a class is special-cased before the check and stays valid.

[decide:webkit] gate passed · iteration 6 · 2 files touched

passes on PR (with fix)
Test-only change.

Debug/ASAN (expected pass):
$ bun bd test 'test/js/bun/jsc/webkit-upgrade-f390a25a.test.ts'
$ BUN_DEBUG_QUIET_LOGS=1 bun scripts/build.ts --profile=debug --quiet test "test/js/bun/jsc/webkit-upgrade-f390a25a.test.ts"
bun test v1.4.1 (65362b53b)

test/js/bun/jsc/webkit-upgrade-f390a25a.test.ts:
(pass) WebKit f390a25a upgrade > non-ASCII identity escapes throw under the u and v flags [39.09ms]
(pass) WebKit f390a25a upgrade > ASCII identity escapes keep their behavior [9.36ms]
(pass) WebKit f390a25a upgrade > non-unicode patterns and escaped code points are unchanged [4.01ms]

 3 pass
 0 fail
 18 expect() calls
Ran 3 tests across 1 file. [2.29s]
Exit: 0
diff hotspot
scripts/build/deps/webkit.ts                    |  2 +-
 test/js/bun/jsc/webkit-upgrade-f390a25a.test.ts | 37 +++++++++++++++++++++++++
 2 files changed, 38 insertions(+), 1 deletion(-)

gate history · 8 passed · 0 rejected · iteration 6

evidence per changed file
file                                             reads  edits  tests
scripts/build/deps/webkit.ts                         8      8      0
test/js/bun/jsc/webkit-upgrade-f390a25a.test.ts      0      0      0

root cause · written by the author bot

In Yarr's regular expression parser, the unicode-mode check that rejects invalid identity escapes was gated behind an ASCII test, so any non-ASCII character following a backslash bypassed validation and fell through to the lenient Annex B behavior where the escaped character matches itself. The fix removes the ASCII gate so the validation applies to all code points, meaning an identity escape under the u or v flag is only accepted for the syntax characters the specification permits and anything else raises a SyntaxError at compile time. This brings behavior in line with ECMA-262 and with V8…

@coderabbitai

coderabbitai Bot commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

  • Run on-demand review

On-demand reviews are free for the next 26 days. After that, they cost $0.25 per reviewed file.

Or wait 13 minutes for your next included review.

View limit details

Limit details: You’ve used all 5 included reviews currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 0f836166-3dfd-4591-90f2-8b0ad64b03c2

📥 Commits

Reviewing files that changed from the base of the PR and between adc354d and c9b4c72.

📒 Files selected for processing (2)
  • scripts/build/deps/webkit.ts
  • test/js/bun/jsc/webkit-upgrade-73543b07.test.ts

Comment @coderabbitai help to get the list of available commands.

Comment thread scripts/build/deps/webkit.ts Outdated
* From https://github.com/oven-sh/WebKit releases.
*/
export const WEBKIT_VERSION = "cb61607f1a4bae79d7701965062634dee9efb349";
export const WEBKIT_VERSION = "autobuild-preview-pr-517-73543b07";

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 WEBKIT_VERSION is pinned to autobuild-preview-pr-517-73543b07, an ephemeral preview build for an unmerged WebKit PR. Per the repo's dependency rules (.claude/docs/landing-prs.md § Dependencies & vendoring: "Never merge a pin to an ephemeral artifact (preview tags, unmerged-PR builds) — swap to the merged upstream SHA"), this must not merge as-is — once oven-sh/WebKit#517 lands, swap this to the merged SHA and verify prebuilt artifacts exist for every platform × flavor.

Extended reasoning...

What the issue is

WEBKIT_VERSION is changed from a 40-hex commit SHA to autobuild-preview-pr-517-73543b07 — a preview-build tag that oven-sh/WebKit's CI publishes for an open, unmerged PR (oven-sh/WebKit#517). The PR description acknowledges this is temporary ("After oven-sh/WebKit#517 merges, the pin should move to the merged sha"), but as written the PR would land the ephemeral pin.

Why this is merge-blocking

The repo's own review rules are explicit on this. REVIEW.md directs dependency bumps to .claude/docs/landing-prs.md § Dependencies & vendoring, which states verbatim at line 47:

Version bumps are repo-wide, verified operations. Never merge a pin to an ephemeral artifact (preview tags, unmerged-PR builds) — swap to the merged upstream SHA and verify prebuilt artifacts exist for every platform × flavor before merge.

autobuild-preview-pr-517-73543b07 is precisely the case that rule names: a preview tag for an unmerged-PR build. Repository-specific instructions can raise severity, and here they explicitly say "never merge" — so this is blocking, not a nit.

Concrete failure mode (step-by-step)

  1. This PR merges to main with WEBKIT_VERSION = "autobuild-preview-pr-517-73543b07".
  2. prebuiltUrl() in scripts/build/deps/webkit.ts:76 sees the value already starts with autobuild- and constructs https://github.com/oven-sh/WebKit/releases/download/autobuild-preview-pr-517-73543b07/bun-webkit-<os>-<arch><suffix>.tar.gz.
  3. Yarr: reject non-ASCII identity escapes in unicode patterns WebKit#517 is merged (or closed, or force-pushed). The fork's CI garbage-collects the autobuild-preview-pr-517-* release, or never published every platform × flavor combination in the first place.
  4. Any fresh clone of Bun at this commit — a new contributor, a clean CI runner, a bisect landing here — runs bun bd. The prebuilt fetch 404s and the build fails. There is no fallback SHA to try.

Nothing in the existing code prevents this: prebuiltUrl() and prebuiltDestDir() were both updated (in a prior PR) to accept autobuild--prefixed tags specifically so branches can test preview builds via --webkit-version=<tag>, but that mechanism is for local overrides, not for the checked-in default.

How to fix

Wait for oven-sh/WebKit#517 to merge, then replace this line with the resulting 40-hex commit SHA on oven-sh/WebKit main (e.g. the merge commit or squashed SHA), and confirm the corresponding autobuild-<sha> release has artifacts for every {linux,macos,windows,freebsd} × {amd64,arm64} × {debug,lto,asan,musl,android} combination prebuiltSuffix() can produce. Until then this PR should stay open (or in draft).

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Acknowledged. The preview pin is deliberate so CI can exercise the engine fix, and it must not merge. I will swap to the merged oven-sh/WebKit sha once oven-sh/WebKit#517 lands, and keep this thread open until then.

@robobun

robobun commented Aug 25, 2026

Copy link
Copy Markdown
Collaborator Author

Correct, the preview pin is temporary and this PR must not merge as-is. The pin points at the preview build of oven-sh/WebKit#517 so CI can exercise the engine fix on every platform. When that PR merges, I will move WEBKIT_VERSION to the merged sha on oven-sh/WebKit main, confirm the autobuild-<sha> release has all artifacts, and rename the test file to match. I will also convert this PR to draft until then.

@robobun
robobun marked this pull request as draft August 25, 2026 22:58
@robobun
robobun force-pushed the farm/0643fce0/regexp-unicode-identity-escape branch from c9b4c72 to eec7cf6 Compare August 25, 2026 23:35
@robobun

robobun commented Aug 25, 2026

Copy link
Copy Markdown
Collaborator Author

Rebased on main. Main moved the WebKit pin to 1cb96a7b (#40417), so I rebased the engine branch in oven-sh/WebKit#517 onto that commit and repointed the pin at its new preview build (autobuild-preview-pr-517-5be0654b). The preview engine is now exactly main's WebKit plus the one-line Yarr fix. The test file moved to test/js/bun/jsc/webkit-upgrade-5be0654b.test.ts and passes against the new build. The PR stays in draft until oven-sh/WebKit#517 merges and the pin moves to the merged sha.

@robobun
robobun force-pushed the farm/0643fce0/regexp-unicode-identity-escape branch from eec7cf6 to adb983c Compare August 26, 2026 06:00
@robobun

robobun commented Aug 26, 2026

Copy link
Copy Markdown
Collaborator Author

Rebased on main again. Main's WebKit pin moved to 76882271, so the engine branch in oven-sh/WebKit#517 was rebased onto that commit and the pin here now points at its preview build (autobuild-preview-pr-517-1c7c53da). The test file moved to test/js/bun/jsc/webkit-upgrade-1c7c53da.test.ts and passes against the new build. Still draft until oven-sh/WebKit#517 merges.

@robobun

robobun commented Aug 26, 2026 •

Copy link
Copy Markdown
Collaborator Author
Updated 6:45 AM PT - Aug 28th, 2026

❌ @robobun, your commit 3acba8a has 1 failures in Build #107706 (All Failures):


🧪   To try this PR locally:

bunx bun-pr 40459

That installs a local version of the PR into your bun-40459 executable, so you can run:

bun-40459 --bun

@robobun
robobun force-pushed the farm/0643fce0/regexp-unicode-identity-escape branch from adb983c to 6fa4ff8 Compare August 26, 2026 22:42
@robobun

robobun commented Aug 26, 2026

Copy link
Copy Markdown
Collaborator Author

Rebased on main. Main's WebKit pin moved to 2da33d53 (#40570), so the engine branch in oven-sh/WebKit#517 was rebased onto it and the pin here now points at the new preview build (autobuild-preview-pr-517-77467a7a). The test file moved to test/js/bun/jsc/webkit-upgrade-77467a7a.test.ts and passes against the new build. Still draft until oven-sh/WebKit#517 merges.

@robobun

robobun commented Aug 27, 2026

Copy link
Copy Markdown
Collaborator Author

Rebased on main. Main's WebKit pin moved to 72597399, so the engine branch in oven-sh/WebKit#517 was rebased onto it and the pin here points at the new preview build (autobuild-preview-pr-517-3f6828a5). The test file moved to test/js/bun/jsc/webkit-upgrade-3f6828a5.test.ts and passes against the new build.

The engine PR also picked up a CI fix: the windows-11-arm preview lane was failing fork-wide because the scoop installer aborts without an error on the 20260823 runner image. The lane now uses the preinstalled ninja and 7-Zip instead of scoop. Still draft until oven-sh/WebKit#517 merges.

@robobun
robobun force-pushed the farm/0643fce0/regexp-unicode-identity-escape branch from 7f38225 to 54dcc85 Compare August 28, 2026 00:51
@robobun

robobun commented Aug 28, 2026

Copy link
Copy Markdown
Collaborator Author

Rebased on main. Main's WebKit pin moved to 0bb01ed5, so the engine branch in oven-sh/WebKit#517 was rebased onto it and the pin here points at the new preview build (autobuild-preview-pr-517-65909ba6). The engine branch is back to the single Yarr commit: main picked up its own fix for the windows-11-arm scoop breakage, so the CI workaround commit was dropped. The test file moved to test/js/bun/jsc/webkit-upgrade-65909ba6.test.ts and passes against the new build. Still draft until oven-sh/WebKit#517 merges.

@robobun
robobun force-pushed the farm/0643fce0/regexp-unicode-identity-escape branch from 54dcc85 to 08fbdf7 Compare August 28, 2026 00:53
@robobun

robobun commented Aug 28, 2026

Copy link
Copy Markdown
Collaborator Author

Rebased on main. No conflicts this time: the pin and diff are unchanged (autobuild-preview-pr-517-65909ba6), and the upgrade test still passes under the debug build. Still draft until oven-sh/WebKit#517 merges.

@robobun
robobun force-pushed the farm/0643fce0/regexp-unicode-identity-escape branch from 08fbdf7 to 09829e7 Compare August 28, 2026 07:27
@robobun

robobun commented Aug 28, 2026

Copy link
Copy Markdown
Collaborator Author

Rebased on main. Main moved the WebKit pin to 1817c3c3, so the engine branch in oven-sh/WebKit#517 was rebased onto it and the pin here points at the new preview build (autobuild-preview-pr-517-9bf30130). The test file moved to test/js/bun/jsc/webkit-upgrade-9bf30130.test.ts and passes against the new build. Still draft until oven-sh/WebKit#517 merges.

…erns

Under the u and v flags, an identity escape of a non-ASCII character
must be a SyntaxError, but Yarr only validated ASCII escapes. /\Ç/u
compiled and matched with the Annex B meaning. The fix is in
oven-sh/WebKit#517. This bumps WEBKIT_VERSION to its preview build and
adds coverage.

Fixes #40441.
@robobun
robobun force-pushed the farm/0643fce0/regexp-unicode-identity-escape branch from 09829e7 to 3acba8a Compare August 28, 2026 13:27
@robobun

robobun commented Aug 28, 2026

Copy link
Copy Markdown
Collaborator Author

Rebased on main. Main moved the WebKit pin to c4ddc0cf, so the engine branch in oven-sh/WebKit#517 was rebased onto it and the pin here points at the new preview build (autobuild-preview-pr-517-f390a25a). The test file moved to test/js/bun/jsc/webkit-upgrade-f390a25a.test.ts and passes against the new build. Still draft until oven-sh/WebKit#517 merges.

@robobun

robobun commented Sep 24, 2026

Copy link
Copy Markdown
Collaborator Author

Closing in favour of #41767. Both PRs fix the same check in YarrParser.h (isIdentityEscapeAnError). #41767 does it through oven-sh/WebKit#577, also covers supplementary characters and lone surrogates after the backslash, and now carries the test cases from this PR. #41767 closes #40441.

@robobun robobun closed this Sep 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

u/v-mode identity-escape validation is ASCII-only

1 participant