From f17ffc2b177463e8b70a07893874420cc3c6aa04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sa=C3=BAl=20Ibarra=20Corretg=C3=A9?= Date: Sat, 14 Mar 2026 12:29:25 +0100 Subject: [PATCH 1/4] Fix RegExp.prototype[Symbol.split] to not coerce captures to strings Ref: https://github.com/bellard/quickjs/commit/b32cccb --- quickjs.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/quickjs.c b/quickjs.c index 991f0a638..a67ae4019 100644 --- a/quickjs.c +++ b/quickjs.c @@ -48588,11 +48588,6 @@ static JSValue js_regexp_Symbol_split(JSContext *ctx, JSValueConst this_val, sub = JS_GetPropertyInt64(ctx, z, i); if (JS_IsException(sub)) goto exception; - if (!JS_IsUndefined(sub)) { - sub = JS_ToStringFree(ctx, sub); - if (JS_IsException(sub)) - goto exception; - } if (JS_DefinePropertyValueInt64(ctx, A, lengthA++, sub, JS_PROP_C_W_E | JS_PROP_THROW) < 0) goto exception; if (lengthA == lim) From e226db057d548bd7681fe0da80fb89f85627c2bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sa=C3=BAl=20Ibarra=20Corretg=C3=A9?= Date: Sat, 14 Mar 2026 12:29:49 +0100 Subject: [PATCH 2/4] Fix Regexp.prototype[Symbol.match] to use CreateDataPropertyOrThrow Ref: https://github.com/bellard/quickjs/commit/8b2a124 --- quickjs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quickjs.c b/quickjs.c index a67ae4019..808d98e2c 100644 --- a/quickjs.c +++ b/quickjs.c @@ -47979,7 +47979,7 @@ static JSValue js_regexp_Symbol_match(JSContext *ctx, JSValueConst this_val, if (JS_IsException(matchStr)) goto exception; isEmpty = JS_IsEmptyString(matchStr); - if (JS_SetPropertyInt64(ctx, A, n++, matchStr) < 0) + if (JS_DefinePropertyValueInt64(ctx, A, n++, matchStr, JS_PROP_C_W_E | JS_PROP_THROW) < 0) goto exception; if (isEmpty) { int64_t thisIndex, nextIndex; From 9555bfaa1840ed88242394fe09caf18a6e266e7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sa=C3=BAl=20Ibarra=20Corretg=C3=A9?= Date: Sat, 14 Mar 2026 12:30:29 +0100 Subject: [PATCH 3/4] Adjust lastIndex to leading surrogate in unicode RegExp Ref: https://github.com/bellard/quickjs/commit/a4ac84d Ref: https://github.com/bellard/quickjs/commit/5689f30 --- libregexp.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/libregexp.c b/libregexp.c index ec558a41f..b9896254f 100644 --- a/libregexp.c +++ b/libregexp.c @@ -2501,6 +2501,7 @@ int lre_exec(uint8_t **capture, REExecContext s_s, *s = &s_s; int re_flags, i, alloca_size, ret; StackInt *stack_buf; + const uint8_t *cptr; re_flags = lre_get_flags(bc_buf); s->multi_line = (re_flags & LRE_FLAG_MULTILINE) != 0; @@ -2527,8 +2528,17 @@ int lre_exec(uint8_t **capture, capture[i] = NULL; alloca_size = s->stack_size_max * sizeof(stack_buf[0]); stack_buf = alloca(alloca_size); + + cptr = cbuf + (cindex << cbuf_type); + if (0 < cindex && cindex < clen && s->cbuf_type == 2) { + const uint16_t *p = (const uint16_t *)cptr; + if (is_lo_surrogate(*p) && is_hi_surrogate(p[-1])) { + cptr = (const uint8_t *)(p - 1); + } + } + ret = lre_exec_backtrack(s, capture, stack_buf, 0, bc_buf + RE_HEADER_LEN, - cbuf + (cindex << cbuf_type), false); + cptr, false); lre_realloc(s->opaque, s->state_stack, 0); return ret; } From 1de61dc9d165d369a7d1fad68c7cccc8c766bce0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sa=C3=BAl=20Ibarra=20Corretg=C3=A9?= Date: Sat, 14 Mar 2026 12:31:11 +0100 Subject: [PATCH 4/4] Make \x{N} a syntax error in escape sequences Ref: https://github.com/bellard/quickjs/commit/7bd1ae2 --- libregexp.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/libregexp.c b/libregexp.c index b9896254f..4e1d9d231 100644 --- a/libregexp.c +++ b/libregexp.c @@ -477,9 +477,21 @@ int lre_parse_escape(const uint8_t **pp, int allow_utf16) c = '\v'; break; case 'x': + { + int h0, h1; + + h0 = from_hex(*p++); + if (h0 < 0) + return -1; + h1 = from_hex(*p++); + if (h1 < 0) + return -1; + c = (h0 << 4) | h1; + } + break; case 'u': { - int h, n, i; + int h, i; uint32_t c1; if (*p == '{' && allow_utf16) { @@ -497,14 +509,8 @@ int lre_parse_escape(const uint8_t **pp, int allow_utf16) } p++; } else { - if (c == 'x') { - n = 2; - } else { - n = 4; - } - c = 0; - for(i = 0; i < n; i++) { + for(i = 0; i < 4; i++) { h = from_hex(*p++); if (h < 0) { return -1;