зеркало из https://github.com/mozilla/pjs.git
bug 509143 - js_CloneRegExp is missing a call to js_SetLastIndex. r=mrbkap
This commit is contained in:
Родитель
e5f7ef8a1d
Коммит
0fdc68aba3
|
@ -4982,6 +4982,34 @@ out:
|
|||
|
||||
/************************************************************************/
|
||||
|
||||
static jsdouble
|
||||
GetRegExpLastIndex(JSObject *obj)
|
||||
{
|
||||
JS_ASSERT(obj->getClass() == &js_RegExpClass);
|
||||
|
||||
jsval v = obj->fslots[JSSLOT_REGEXP_LAST_INDEX];
|
||||
if (JSVAL_IS_INT(v))
|
||||
return JSVAL_TO_INT(v);
|
||||
JS_ASSERT(JSVAL_IS_DOUBLE(v));
|
||||
return *JSVAL_TO_DOUBLE(v);
|
||||
}
|
||||
|
||||
static jsval
|
||||
GetRegExpLastIndexValue(JSObject *obj)
|
||||
{
|
||||
JS_ASSERT(obj->getClass() == &js_RegExpClass);
|
||||
return obj->fslots[JSSLOT_REGEXP_LAST_INDEX];
|
||||
}
|
||||
|
||||
static JSBool
|
||||
SetRegExpLastIndex(JSContext *cx, JSObject *obj, jsdouble lastIndex)
|
||||
{
|
||||
JS_ASSERT(obj->getClass() == &js_RegExpClass);
|
||||
|
||||
return JS_NewNumberValue(cx, lastIndex,
|
||||
&obj->fslots[JSSLOT_REGEXP_LAST_INDEX]);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
regexp_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
||||
{
|
||||
|
@ -4996,8 +5024,10 @@ regexp_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
|||
return JS_TRUE;
|
||||
}
|
||||
slot = JSVAL_TO_INT(id);
|
||||
if (slot == REGEXP_LAST_INDEX)
|
||||
return JS_GetReservedSlot(cx, obj, 0, vp);
|
||||
if (slot == REGEXP_LAST_INDEX) {
|
||||
*vp = GetRegExpLastIndexValue(obj);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JS_LOCK_OBJ(cx, obj);
|
||||
re = (JSRegExp *) obj->getPrivate();
|
||||
|
@ -5044,8 +5074,7 @@ regexp_setProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
|||
if (!JS_ValueToNumber(cx, *vp, &lastIndex))
|
||||
return JS_FALSE;
|
||||
lastIndex = js_DoubleToInteger(lastIndex);
|
||||
ok = JS_NewNumberValue(cx, lastIndex, vp) &&
|
||||
JS_SetReservedSlot(cx, obj, 0, *vp);
|
||||
ok = SetRegExpLastIndex(cx, obj, lastIndex);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
@ -5315,8 +5344,7 @@ js_XDRRegExpObject(JSXDRState *xdr, JSObject **objp)
|
|||
if (!re)
|
||||
return JS_FALSE;
|
||||
obj->setPrivate(re);
|
||||
if (!js_SetLastIndex(xdr->cx, obj, 0))
|
||||
return JS_FALSE;
|
||||
js_ClearRegExpLastIndex(obj);
|
||||
*objp = obj;
|
||||
}
|
||||
return JS_TRUE;
|
||||
|
@ -5338,7 +5366,8 @@ regexp_trace(JSTracer *trc, JSObject *obj)
|
|||
|
||||
JSClass js_RegExpClass = {
|
||||
js_RegExp_str,
|
||||
JSCLASS_HAS_PRIVATE | JSCLASS_HAS_RESERVED_SLOTS(1) |
|
||||
JSCLASS_HAS_PRIVATE |
|
||||
JSCLASS_HAS_RESERVED_SLOTS(REGEXP_CLASS_FIXED_RESERVED_SLOTS) |
|
||||
JSCLASS_MARK_IS_TRACE | JSCLASS_HAS_CACHED_PROTO(JSProto_RegExp),
|
||||
JS_PropertyStub, JS_PropertyStub,
|
||||
JS_PropertyStub, JS_PropertyStub,
|
||||
|
@ -5527,13 +5556,12 @@ created:
|
|||
JS_LOCK_OBJ(cx, obj);
|
||||
oldre = (JSRegExp *) obj->getPrivate();
|
||||
obj->setPrivate(re);
|
||||
|
||||
JSBool ok = js_SetLastIndex(cx, obj, 0);
|
||||
js_ClearRegExpLastIndex(obj);
|
||||
JS_UNLOCK_OBJ(cx, obj);
|
||||
if (oldre)
|
||||
js_DestroyRegExp(cx, oldre);
|
||||
*rval = OBJECT_TO_JSVAL(obj);
|
||||
return ok;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
|
@ -5568,14 +5596,10 @@ regexp_exec_sub(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
|||
/* NB: we must reach out: after this paragraph, in order to drop re. */
|
||||
HOLD_REGEXP(cx, re);
|
||||
sticky = (re->flags & JSREG_STICKY) != 0;
|
||||
if (re->flags & (JSREG_GLOB | JSREG_STICKY)) {
|
||||
ok = js_GetLastIndex(cx, obj, &lastIndex);
|
||||
} else {
|
||||
lastIndex = 0;
|
||||
}
|
||||
lastIndex = (re->flags & (JSREG_GLOB | JSREG_STICKY))
|
||||
? GetRegExpLastIndex(obj)
|
||||
: 0;
|
||||
JS_UNLOCK_OBJ(cx, obj);
|
||||
if (!ok)
|
||||
goto out;
|
||||
|
||||
/* Now that obj is unlocked, it's safe to (potentially) grab the GC lock. */
|
||||
if (argc == 0) {
|
||||
|
@ -5605,14 +5629,17 @@ regexp_exec_sub(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
|||
}
|
||||
|
||||
if (lastIndex < 0 || str->length() < lastIndex) {
|
||||
ok = js_SetLastIndex(cx, obj, 0);
|
||||
js_ClearRegExpLastIndex(obj);
|
||||
*rval = JSVAL_NULL;
|
||||
} else {
|
||||
i = (size_t) lastIndex;
|
||||
ok = js_ExecuteRegExp(cx, re, str, &i, test, rval);
|
||||
if (ok &&
|
||||
((re->flags & JSREG_GLOB) || (*rval != JSVAL_NULL && sticky))) {
|
||||
ok = js_SetLastIndex(cx, obj, (*rval == JSVAL_NULL) ? 0 : i);
|
||||
if (*rval == JSVAL_NULL)
|
||||
js_ClearRegExpLastIndex(obj);
|
||||
else
|
||||
ok = SetRegExpLastIndex(cx, obj, i);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5728,8 +5755,7 @@ js_NewRegExpObject(JSContext *cx, JSTokenStream *ts,
|
|||
return NULL;
|
||||
}
|
||||
obj->setPrivate(re);
|
||||
if (!js_SetLastIndex(cx, obj, 0))
|
||||
return NULL;
|
||||
js_ClearRegExpLastIndex(obj);
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
@ -5746,26 +5772,9 @@ js_CloneRegExpObject(JSContext *cx, JSObject *obj, JSObject *parent)
|
|||
re = (JSRegExp *) obj->getPrivate();
|
||||
if (re) {
|
||||
clone->setPrivate(re);
|
||||
js_ClearRegExpLastIndex(clone);
|
||||
HOLD_REGEXP(cx, re);
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
|
||||
JSBool
|
||||
js_GetLastIndex(JSContext *cx, JSObject *obj, jsdouble *lastIndex)
|
||||
{
|
||||
jsval v;
|
||||
|
||||
return JS_GetReservedSlot(cx, obj, 0, &v) &&
|
||||
JS_ValueToNumber(cx, v, lastIndex);
|
||||
}
|
||||
|
||||
JSBool
|
||||
js_SetLastIndex(JSContext *cx, JSObject *obj, jsdouble lastIndex)
|
||||
{
|
||||
jsval v;
|
||||
|
||||
return JS_NewNumberValue(cx, lastIndex, &v) &&
|
||||
JS_SetReservedSlot(cx, obj, 0, v);
|
||||
}
|
||||
|
||||
|
|
|
@ -185,14 +185,15 @@ js_XDRRegExpObject(JSXDRState *xdr, JSObject **objp);
|
|||
extern JSObject *
|
||||
js_CloneRegExpObject(JSContext *cx, JSObject *obj, JSObject *parent);
|
||||
|
||||
/*
|
||||
* Get and set the per-object (clone or clone-parent) lastIndex slot.
|
||||
*/
|
||||
extern JSBool
|
||||
js_GetLastIndex(JSContext *cx, JSObject *obj, jsdouble *lastIndex);
|
||||
const uint32 JSSLOT_REGEXP_LAST_INDEX = JSSLOT_PRIVATE + 1;
|
||||
const uint32 REGEXP_CLASS_FIXED_RESERVED_SLOTS = 1;
|
||||
|
||||
extern JSBool
|
||||
js_SetLastIndex(JSContext *cx, JSObject *obj, jsdouble lastIndex);
|
||||
static inline void
|
||||
js_ClearRegExpLastIndex(JSObject *obj)
|
||||
{
|
||||
JS_ASSERT(obj->getClass() == &js_RegExpClass);
|
||||
obj->fslots[JSSLOT_REGEXP_LAST_INDEX] = JSVAL_ZERO;
|
||||
}
|
||||
|
||||
JS_END_EXTERN_C
|
||||
|
||||
|
|
|
@ -1343,26 +1343,21 @@ match_or_replace(JSContext *cx,
|
|||
: INT_TO_JSVAL(-1);
|
||||
}
|
||||
} else if (data->flags & GLOBAL_REGEXP) {
|
||||
if (reobj) {
|
||||
/* Set the lastIndex property's reserved slot to 0. */
|
||||
ok = js_SetLastIndex(cx, reobj, 0);
|
||||
} else {
|
||||
ok = JS_TRUE;
|
||||
}
|
||||
if (ok) {
|
||||
length = str->length();
|
||||
for (count = 0; index <= length; count++) {
|
||||
ok = js_ExecuteRegExp(cx, re, str, &index, JS_TRUE, vp);
|
||||
if (!ok || *vp != JSVAL_TRUE)
|
||||
if (reobj)
|
||||
js_ClearRegExpLastIndex(reobj);
|
||||
length = str->length();
|
||||
ok = true;
|
||||
for (count = 0; index <= length; count++) {
|
||||
ok = js_ExecuteRegExp(cx, re, str, &index, JS_TRUE, vp);
|
||||
if (!ok || *vp != JSVAL_TRUE)
|
||||
break;
|
||||
ok = glob(cx, count, data);
|
||||
if (!ok)
|
||||
break;
|
||||
if (cx->regExpStatics.lastMatch.length == 0) {
|
||||
if (index == length)
|
||||
break;
|
||||
ok = glob(cx, count, data);
|
||||
if (!ok)
|
||||
break;
|
||||
if (cx->regExpStatics.lastMatch.length == 0) {
|
||||
if (index == length)
|
||||
break;
|
||||
index++;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
Загрузка…
Ссылка в новой задаче