diff --git a/src/main/java/com/github/anba/es6draft/runtime/objects/text/RegExpPrototype.java b/src/main/java/com/github/anba/es6draft/runtime/objects/text/RegExpPrototype.java index 3fe2c8046..3613f8fd9 100644 --- a/src/main/java/com/github/anba/es6draft/runtime/objects/text/RegExpPrototype.java +++ b/src/main/java/com/github/anba/es6draft/runtime/objects/text/RegExpPrototype.java @@ -853,10 +853,9 @@ private static MatchResult matchResultOrNull(ExecutionContext cx, RegExpObject r /* steps 2-3 (not applicable) */ /* steps 4-5 */ int lastIndex = (int) Math.min(ToLength(cx, Get(cx, r, "lastIndex")), Integer.MAX_VALUE); - /* steps 6-7 */ - boolean global = ToBoolean(Get(cx, r, "global")); - /* steps 8-9 */ - boolean sticky = ToBoolean(Get(cx, r, "sticky")); + /* ES2016 steps 5-7 */ + boolean global = r.isSet(RegExpObject.Flags.Global); + boolean sticky = r.isSet(RegExpObject.Flags.Sticky); /* steps 10-15 */ MatchState m = matchOrNull(r, s, lastIndex, global, sticky); /* step 15.a, 15.c */ diff --git a/src/test/scripts/suite/regress/bug2625.js b/src/test/scripts/suite/regress/bug2625.js index d530ab31d..88caae66d 100644 --- a/src/test/scripts/suite/regress/bug2625.js +++ b/src/test/scripts/suite/regress/bug2625.js @@ -10,25 +10,35 @@ const { // 21.2.5.7 RegExp.prototype.replace, 21.2.5.2.1 RegExpExec: Dynamic flags retrieval is unsafe // https://bugs.ecmascript.org/show_bug.cgi?id=2625 +/** + * ES2015 section 21.2.5.8 ("RegExp.prototype [ @@replace ]"), step 16.p.i + * reads: + * + * > NOTE position should not normally move backwards. If it does, it is an + * > indication of an ill-behaving RegExp subclass or use of an access + * > triggered side-effect to change the global flag or other characteristics + * > of rx. In such cases, the corresponding substitution is ignored. + */ { - let re = /test/; - let glob = true; + let re = /test/g; let c = 0; - Object.defineProperty(re, "global", { - get() { - c += 1; - if (c == 3) { - re.compile(/pre/); - } - if (c == 4) { - re.compile(/kaboom/); - } - let g = glob; - glob = false; - return g; + re.exec = function() { + let result; + c += 1; + if (c == 1) { + this.lastIndex = 8; + let val = ["test"]; + val.index = 4; + return val; + } + if (c == 2) { + result = ["pre"]; + result.index = 0; + return result; } - }); + return null; + }; let s = "pre-test".replace(re, () => {}); assertSame("pre-undefined", s); }