added regexp duplicate named groups - fixed reset of captures with quantizers

This commit is contained in:
Fabrice Bellard
2025-12-03 13:30:33 +01:00
parent b226856177
commit 24379bf53c
8 changed files with 235 additions and 111 deletions

View File

@@ -47405,7 +47405,8 @@ static JSValue js_regexp_exec(JSContext *ctx, JSValueConst this_val,
int64_t last_index;
const char *group_name_ptr;
JSObject *p_obj;
JSAtom group_name;
if (!re)
return JS_EXCEPTION;
@@ -47419,7 +47420,8 @@ static JSValue js_regexp_exec(JSContext *ctx, JSValueConst this_val,
indices = JS_UNDEFINED;
indices_groups = JS_UNDEFINED;
capture = NULL;
group_name = JS_ATOM_NULL;
if (js_regexp_get_lastIndex(ctx, &last_index, this_val))
goto fail;
@@ -47501,15 +47503,20 @@ static JSValue js_regexp_exec(JSContext *ctx, JSValueConst this_val,
goto fail;
for(i = 0; i < capture_count; i++) {
const char *name = NULL;
uint8_t **match = &capture[2 * i];
int start = -1;
int end = -1;
JSValue val;
if (group_name_ptr && i > 0) {
if (*group_name_ptr) name = group_name_ptr;
group_name_ptr += strlen(group_name_ptr) + 1;
if (*group_name_ptr) {
/* XXX: slow, should create a shape when the regexp is
compiled */
group_name = JS_NewAtom(ctx, group_name_ptr);
if (group_name == JS_ATOM_NULL)
goto fail;
}
group_name_ptr += strlen(group_name_ptr) + LRE_GROUP_NAME_TRAILER_LEN;
}
if (match[0] && match[1]) {
@@ -47536,12 +47543,15 @@ static JSValue js_regexp_exec(JSContext *ctx, JSValueConst this_val,
goto fail;
}
}
if (name && !JS_IsUndefined(indices_groups)) {
val = JS_DupValue(ctx, val);
if (JS_DefinePropertyValueStr(ctx, indices_groups,
name, val, prop_flags) < 0) {
JS_FreeValue(ctx, val);
goto fail;
if (group_name != JS_ATOM_NULL) {
/* JS_HasProperty() cannot fail here */
if (!JS_IsUndefined(val) ||
!JS_HasProperty(ctx, indices_groups, group_name)) {
if (JS_DefinePropertyValue(ctx, indices_groups,
group_name, JS_DupValue(ctx, val), prop_flags) < 0) {
JS_FreeValue(ctx, val);
goto fail;
}
}
}
if (JS_DefinePropertyValueUint32(ctx, indices, i, val,
@@ -47557,13 +47567,19 @@ static JSValue js_regexp_exec(JSContext *ctx, JSValueConst this_val,
goto fail;
}
if (name) {
if (JS_DefinePropertyValueStr(ctx, groups, name,
JS_DupValue(ctx, val),
prop_flags) < 0) {
JS_FreeValue(ctx, val);
goto fail;
if (group_name != JS_ATOM_NULL) {
/* JS_HasProperty() cannot fail here */
if (!JS_IsUndefined(val) ||
!JS_HasProperty(ctx, groups, group_name)) {
if (JS_DefinePropertyValue(ctx, groups, group_name,
JS_DupValue(ctx, val),
prop_flags) < 0) {
JS_FreeValue(ctx, val);
goto fail;
}
}
JS_FreeAtom(ctx, group_name);
group_name = JS_ATOM_NULL;
}
p_obj->u.array.u.values[p_obj->u.array.count++] = val;
}
@@ -47584,6 +47600,7 @@ static JSValue js_regexp_exec(JSContext *ctx, JSValueConst this_val,
ret = obj;
obj = JS_UNDEFINED;
fail:
JS_FreeAtom(ctx, group_name);
JS_FreeValue(ctx, indices_groups);
JS_FreeValue(ctx, indices);
JS_FreeValue(ctx, str_val);