author | Tooru Fujisawa <arai_a@mac.com> |
Sun, 22 May 2016 00:42:10 +0900 | |
changeset 298323 | 458743bb901f19cf830b7133a128d1ff561d7ef0 |
parent 298322 | 4f1a4d674b7487785d4d8153d9714bc329dbe8b1 |
child 298324 | ac5e8c0b9ec28e485a10ba84e2627106ea87cc87 |
push id | 77117 |
push user | arai_a@mac.com |
push date | Sat, 21 May 2016 15:43:58 +0000 |
treeherder | mozilla-inbound@458743bb901f [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | till |
bugs | 1274393 |
milestone | 49.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
js/src/builtin/RegExp.cpp | file | annotate | diff | comparison | revisions | |
js/src/tests/ecma_6/RegExp/constructor-regexp-unicode.js | file | annotate | diff | comparison | revisions |
--- a/js/src/builtin/RegExp.cpp +++ b/js/src/builtin/RegExp.cpp @@ -166,16 +166,25 @@ js::ExecuteRegExpLegacy(JSContext* cx, R /* Forbid an array, as an optimization. */ rval.setBoolean(true); return true; } return CreateRegExpMatchResult(cx, input, matches, rval); } +static bool +CheckPatternSyntax(JSContext* cx, HandleAtom pattern, RegExpFlag flags) +{ + CompileOptions options(cx); + frontend::TokenStream dummyTokenStream(cx, options, nullptr, 0, nullptr); + return irregexp::ParsePatternSyntax(dummyTokenStream, cx->tempLifoAlloc(), pattern, + flags & UnicodeFlag); +} + enum RegExpSharedUse { UseRegExpShared, DontUseRegExpShared }; /* * ES 2016 draft Mar 25, 2016 21.2.3.2.2. * Because this function only ever returns |obj| in the spec, provided by the @@ -217,23 +226,18 @@ RegExpInitializeIgnoringLastIndex(JSCont return false; /* Steps 9-12. */ obj->initIgnoringLastIndex(pattern, flags); obj->setShared(*re); } else { /* Steps 7-8. */ - CompileOptions options(cx); - frontend::TokenStream dummyTokenStream(cx, options, nullptr, 0, nullptr); - if (!irregexp::ParsePatternSyntax(dummyTokenStream, cx->tempLifoAlloc(), pattern, - flags & UnicodeFlag)) - { + if (!CheckPatternSyntax(cx, pattern, flags)) return false; - } /* Steps 9-12. */ obj->initIgnoringLastIndex(pattern, flags); } return true; } @@ -414,40 +418,49 @@ js::regexp_construct(JSContext* cx, unsi RegExpFlag flags; { // Step 4.a. RegExpGuard g(cx); if (!RegExpToShared(cx, patternObj, &g)) return false; sourceAtom = g->getSource(); - if (!args.hasDefined(1)) { - // Step 4.b. - flags = g->getFlags(); - } + // Step 4.b. + // Get original flags in all cases, to compare with passed flags. + flags = g->getFlags(); } // Step 7. RootedObject proto(cx); if (!GetPrototypeFromCallableConstructor(cx, args, &proto)) return false; Rooted<RegExpObject*> regexp(cx, RegExpAlloc(cx, proto)); if (!regexp) return false; // Step 8. if (args.hasDefined(1)) { // Step 4.c / 21.2.3.2.2 RegExpInitialize step 4. - flags = RegExpFlag(0); + RegExpFlag flagsArg = RegExpFlag(0); RootedString flagStr(cx, ToString<CanGC>(cx, args[1])); if (!flagStr) return false; - if (!ParseRegExpFlags(cx, flagStr, &flags)) + if (!ParseRegExpFlags(cx, flagStr, &flagsArg)) return false; + + if (!(flags & UnicodeFlag) && flagsArg & UnicodeFlag) { + // Have to check syntax again when adding 'u' flag. + + // ES 2017 draft rev 9b49a888e9dfe2667008a01b2754c3662059ae56 + // 21.2.3.2.2 step 7. + if (!CheckPatternSyntax(cx, sourceAtom, flagsArg)) + return false; + } + flags = flagsArg; } regexp->initAndZeroLastIndex(sourceAtom, flags, cx); args.rval().setObject(*regexp); return true; }
new file mode 100644 --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/constructor-regexp-unicode.js @@ -0,0 +1,9 @@ +var BUGNUMBER = 1274393; +var summary = "RegExp constructor should check the pattern syntax again when adding unicode flag."; + +print(BUGNUMBER + ": " + summary); + +assertThrowsInstanceOf(() => RegExp(/\-/, "u"), SyntaxError); + +if (typeof reportCompare === "function") + reportCompare(true, true);