Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 25 additions & 9 deletions libregexp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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;
Expand Down Expand Up @@ -2501,6 +2507,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;
Expand All @@ -2527,8 +2534,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);
}
Comment on lines +2540 to +2543
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.

Unsafe/unsound when the pointer is unaligned. Something like this is sound (assuming it's not readying before the start of the buffer, of course):

Suggested change
const uint16_t *p = (const uint16_t *)cptr;
if (is_lo_surrogate(*p) && is_hi_surrogate(p[-1])) {
cptr = (const uint8_t *)(p - 1);
}
uint16_t c[2];
memcpy(c, &cptr[-2], sizeof(c));
if (is_lo_surrogate(c[1]) && is_hi_surrogate(c[0])) {
cptr -= 2;
}

The high/low surrogate checks look inverted though.

}

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;
}
Expand Down
7 changes: 1 addition & 6 deletions quickjs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand Down
Loading