From 3acba8ad146c4ded9b1bc0fd88e69ec35ae91f65 Mon Sep 17 00:00:00 2001 From: robobun <117481402+robobun@users.noreply.github.com> Date: Tue, 25 Aug 2026 10:17:41 +0000 Subject: [PATCH] Bump WebKit: reject non-ASCII identity escapes in unicode RegExp patterns MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- scripts/build/deps/webkit.ts | 2 +- .../bun/jsc/webkit-upgrade-f390a25a.test.ts | 37 +++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 test/js/bun/jsc/webkit-upgrade-f390a25a.test.ts diff --git a/scripts/build/deps/webkit.ts b/scripts/build/deps/webkit.ts index c2c7d88938ec..48f7325694dc 100644 --- a/scripts/build/deps/webkit.ts +++ b/scripts/build/deps/webkit.ts @@ -3,7 +3,7 @@ * for local mode. Override via `--webkit-version=` to test a branch. * From https://github.com/oven-sh/WebKit releases. */ -export const WEBKIT_VERSION = "c4ddc0cf5255ec9cc209e6369292739b78e3ca80"; +export const WEBKIT_VERSION = "autobuild-preview-pr-517-f390a25a"; /** * WebKit (JavaScriptCore) — the JS engine. diff --git a/test/js/bun/jsc/webkit-upgrade-f390a25a.test.ts b/test/js/bun/jsc/webkit-upgrade-f390a25a.test.ts new file mode 100644 index 000000000000..a52cba4c7c28 --- /dev/null +++ b/test/js/bun/jsc/webkit-upgrade-f390a25a.test.ts @@ -0,0 +1,37 @@ +import { describe, expect, test } from "bun:test"; + +// Coverage for the WebKit f390a25a sync (oven-sh/WebKit#517): under the u and +// v flags, an identity escape of a non-ASCII character must be a SyntaxError. +// Yarr only validated ASCII escapes, so /\Ç/u compiled and matched with the +// Annex B meaning. Fixes oven-sh/bun#40441. + +describe.concurrent("WebKit f390a25a upgrade", () => { + test("non-ASCII identity escapes throw under the u and v flags", () => { + expect(() => new RegExp("\\Ç", "u")).toThrow(SyntaxError); + expect(() => new RegExp("\\Ç", "v")).toThrow(SyntaxError); + expect(() => new RegExp("\\é", "u")).toThrow(SyntaxError); + expect(() => new RegExp("\\字", "u")).toThrow(SyntaxError); + expect(() => new RegExp("\\𝒳", "u")).toThrow(SyntaxError); + expect(() => new RegExp("\\𝒳", "v")).toThrow(SyntaxError); + expect(() => new RegExp("[\\Ç]", "u")).toThrow(SyntaxError); + expect(() => new RegExp("[\\Ç]", "v")).toThrow(SyntaxError); + expect(() => new RegExp("[\\q{\\Ç}]", "v")).toThrow(SyntaxError); + }); + + test("ASCII identity escapes keep their behavior", () => { + // Still invalid under u: not a SyntaxCharacter or '/'. + expect(() => new RegExp("\\q", "u")).toThrow(SyntaxError); + expect(() => new RegExp("\\\u0000", "u")).toThrow(SyntaxError); + // Still valid. + expect(new RegExp("\\$", "u").test("$")).toBe(true); + expect(new RegExp("\\/", "u").test("/")).toBe(true); + expect(new RegExp("[\\-]", "u").test("-")).toBe(true); + expect(new RegExp("[\\&]", "v").test("&")).toBe(true); + }); + + test("non-unicode patterns and escaped code points are unchanged", () => { + expect(new RegExp("\\Ç").test("Ç")).toBe(true); + expect(new RegExp("Ç", "u").test("Ç")).toBe(true); + expect(new RegExp("\\u00C7", "u").test("Ç")).toBe(true); + }); +});