mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-24 02:35:41 +00:00
Bug 834989 - Use of RegExp in self-hosted code can be observed through RegExp statics. r=jwalden
This commit is contained in:
parent
168b162725
commit
7968ef59e4
@ -528,7 +528,8 @@ js_InitRegExpClass(JSContext *cx, HandleObject obj)
|
||||
}
|
||||
|
||||
RegExpRunStatus
|
||||
js::ExecuteRegExp(JSContext *cx, HandleObject regexp, HandleString string, MatchConduit &matches)
|
||||
js::ExecuteRegExp(JSContext *cx, HandleObject regexp, HandleString string,
|
||||
MatchConduit &matches, RegExpStaticsUpdate staticsUpdate)
|
||||
{
|
||||
/* Step 1 (b) was performed by CallNonGenericMethod. */
|
||||
Rooted<RegExpObject*> reobj(cx, ®exp->as<RegExpObject>());
|
||||
@ -537,7 +538,7 @@ js::ExecuteRegExp(JSContext *cx, HandleObject regexp, HandleString string, Match
|
||||
if (!reobj->getShared(cx, &re))
|
||||
return RegExpRunStatus_Error;
|
||||
|
||||
RegExpStatics *res = cx->regExpStatics();
|
||||
RegExpStatics *res = (staticsUpdate == UpdateRegExpStatics) ? cx->regExpStatics() : NULL;
|
||||
|
||||
/* Step 3. */
|
||||
Rooted<JSLinearString*> input(cx, string->ensureLinear(cx));
|
||||
@ -607,27 +608,19 @@ ExecuteRegExp(JSContext *cx, CallArgs args, MatchConduit &matches)
|
||||
if (!string)
|
||||
return RegExpRunStatus_Error;
|
||||
|
||||
return ExecuteRegExp(cx, regexp, string, matches);
|
||||
return ExecuteRegExp(cx, regexp, string, matches, UpdateRegExpStatics);
|
||||
}
|
||||
|
||||
/* ES5 15.10.6.2. */
|
||||
static bool
|
||||
regexp_exec_impl(JSContext *cx, CallArgs args)
|
||||
regexp_exec_impl(JSContext *cx, CallArgs args, HandleObject regexp, HandleString string,
|
||||
RegExpStaticsUpdate staticsUpdate)
|
||||
{
|
||||
/* Execute regular expression and gather matches. */
|
||||
ScopedMatchPairs matches(&cx->tempLifoAlloc());
|
||||
MatchConduit conduit(&matches);
|
||||
|
||||
/*
|
||||
* Extract arguments to share between ExecuteRegExp()
|
||||
* and CreateRegExpMatchResult().
|
||||
*/
|
||||
RootedObject regexp(cx, &args.thisv().toObject());
|
||||
RootedString string(cx, ToString<CanGC>(cx, args.handleOrUndefinedAt(0)));
|
||||
if (!string)
|
||||
return false;
|
||||
|
||||
RegExpRunStatus status = ExecuteRegExp(cx, regexp, string, conduit);
|
||||
RegExpRunStatus status = ExecuteRegExp(cx, regexp, string, conduit, staticsUpdate);
|
||||
|
||||
if (status == RegExpRunStatus_Error)
|
||||
return false;
|
||||
@ -640,6 +633,17 @@ regexp_exec_impl(JSContext *cx, CallArgs args)
|
||||
return CreateRegExpMatchResult(cx, string, matches, args.rval());
|
||||
}
|
||||
|
||||
static bool
|
||||
regexp_exec_impl(JSContext *cx, CallArgs args)
|
||||
{
|
||||
RootedObject regexp(cx, &args.thisv().toObject());
|
||||
RootedString string(cx, ToString<CanGC>(cx, args.handleOrUndefinedAt(0)));
|
||||
if (!string)
|
||||
return false;
|
||||
|
||||
return regexp_exec_impl(cx, args, regexp, string, UpdateRegExpStatics);
|
||||
}
|
||||
|
||||
JSBool
|
||||
js::regexp_exec(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
@ -647,6 +651,20 @@ js::regexp_exec(JSContext *cx, unsigned argc, Value *vp)
|
||||
return CallNonGenericMethod(cx, IsRegExp, regexp_exec_impl, args);
|
||||
}
|
||||
|
||||
JSBool
|
||||
js::regexp_exec_no_statics(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
JS_ASSERT(args.length() == 2);
|
||||
JS_ASSERT(IsRegExp(args[0]));
|
||||
JS_ASSERT(args[1].isString());
|
||||
|
||||
RootedObject regexp(cx, &args[0].toObject());
|
||||
RootedString string(cx, args[1].toString());
|
||||
|
||||
return regexp_exec_impl(cx, args, regexp, string, DontUpdateRegExpStatics);
|
||||
}
|
||||
|
||||
/* ES5 15.10.6.3. */
|
||||
static bool
|
||||
regexp_test_impl(JSContext *cx, CallArgs args)
|
||||
@ -664,7 +682,7 @@ js::regexp_test_raw(JSContext *cx, HandleObject regexp, HandleString input, JSBo
|
||||
{
|
||||
MatchPair match;
|
||||
MatchConduit conduit(&match);
|
||||
RegExpRunStatus status = ExecuteRegExp(cx, regexp, input, conduit);
|
||||
RegExpRunStatus status = ExecuteRegExp(cx, regexp, input, conduit, UpdateRegExpStatics);
|
||||
*result = (status == RegExpRunStatus_Success);
|
||||
return (status != RegExpRunStatus_Error);
|
||||
}
|
||||
@ -675,3 +693,21 @@ js::regexp_test(JSContext *cx, unsigned argc, Value *vp)
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
return CallNonGenericMethod(cx, IsRegExp, regexp_test_impl, args);
|
||||
}
|
||||
|
||||
JSBool
|
||||
js::regexp_test_no_statics(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
JS_ASSERT(args.length() == 2);
|
||||
JS_ASSERT(IsRegExp(args[0]));
|
||||
JS_ASSERT(args[1].isString());
|
||||
|
||||
RootedObject regexp(cx, &args[0].toObject());
|
||||
RootedString string(cx, args[1].toString());
|
||||
|
||||
MatchPair match;
|
||||
MatchConduit conduit(&match);
|
||||
RegExpRunStatus status = ExecuteRegExp(cx, regexp, string, conduit, DontUpdateRegExpStatics);
|
||||
args.rval().setBoolean(status == RegExpRunStatus_Success);
|
||||
return (status != RegExpRunStatus_Error);
|
||||
}
|
||||
|
@ -22,9 +22,13 @@ js_InitRegExpClass(JSContext *cx, js::HandleObject obj);
|
||||
|
||||
namespace js {
|
||||
|
||||
// Whether RegExp statics should be updated with the input and results of a
|
||||
// regular expression execution.
|
||||
enum RegExpStaticsUpdate { UpdateRegExpStatics, DontUpdateRegExpStatics };
|
||||
|
||||
RegExpRunStatus
|
||||
ExecuteRegExp(JSContext *cx, HandleObject regexp, HandleString string,
|
||||
MatchConduit &matches);
|
||||
MatchConduit &matches, RegExpStaticsUpdate staticsUpdate);
|
||||
|
||||
/*
|
||||
* Legacy behavior of ExecuteRegExp(), which is baked into the JSAPI.
|
||||
@ -56,6 +60,26 @@ regexp_test_raw(JSContext *cx, HandleObject regexp, HandleString input, JSBool *
|
||||
extern JSBool
|
||||
regexp_test(JSContext *cx, unsigned argc, Value *vp);
|
||||
|
||||
/*
|
||||
* The following functions are for use by self-hosted code.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Behaves like regexp.exec(string), but doesn't set RegExp statics.
|
||||
*
|
||||
* Usage: match = regexp_exec_no_statics(regexp, string)
|
||||
*/
|
||||
extern JSBool
|
||||
regexp_exec_no_statics(JSContext *cx, unsigned argc, Value *vp);
|
||||
|
||||
/*
|
||||
* Behaves like regexp.test(string), but doesn't set RegExp statics.
|
||||
*
|
||||
* Usage: does_match = regexp_test_no_statics(regexp, string)
|
||||
*/
|
||||
extern JSBool
|
||||
regexp_test_no_statics(JSContext *cx, unsigned argc, Value *vp);
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
#endif /* builtin_RegExp_h */
|
||||
|
@ -655,6 +655,10 @@ const JSFunctionSpec intrinsic_functions[] = {
|
||||
JS_FN("intl_numberingSystem", intl_numberingSystem, 1,0),
|
||||
JS_FN("intl_patternForSkeleton", intl_patternForSkeleton, 2,0),
|
||||
|
||||
// See builtin/RegExp.h for descriptions of the regexp_* functions.
|
||||
JS_FN("regexp_exec_no_statics", regexp_exec_no_statics, 2,0),
|
||||
JS_FN("regexp_test_no_statics", regexp_test_no_statics, 2,0),
|
||||
|
||||
#ifdef DEBUG
|
||||
JS_FN("Dump", intrinsic_Dump, 1,0),
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user