Closed
Bug 1168257
Opened 10 years ago
Closed 10 years ago
String.prototype.replace fails with frozen RegExp param
Categories
(Core :: JavaScript Engine, defect)
Tracking
()
RESOLVED
INVALID
People
(Reporter: adamsmith, Unassigned)
References
Details
Attachments
(1 file)
7.12 KB,
application/x-zip-compressed
|
Details |
User Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.65 Safari/537.36
Steps to reproduce:
The steps to reproduce this bug are simple:
1) Write a script that creates a RegExp, freezes it, and runs string.replace(frozenRegExp, string).
2) Open Firefox (34, 38, 41, ...) any way you desire.
3) Run the script written for step 1.
Note: The attached files will quickly reproduce the error without any difficulty. Plus it contains much greater detail of the problem than provided here.
Actual results:
TypeError: string.replace(...) is read-only
Expected results:
returned new string with replacements
It doesn't work after bug 501739. I'd say it's an issue in your code.
Comment 2•10 years ago
|
||
The testcase is basically this:
var regex = /0/g;
Object.freeze(regex);
var str = "abc000";
str.replace(regex, "o");
Per spec this calls http://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.prototype.replace which then gets @@replace from the regex and calls that method.
That means that we're calling http://people.mozilla.org/~jorendorff/es6-draft.html#sec-regexp.prototype-@@replace which in step 10 sees that the global flag on the regex is true and hence does step 10c, which attempts to set the lastIndex property of the regex to 0. It does so by invoking http://people.mozilla.org/~jorendorff/es6-draft.html#sec-set-o-p-v-throw with the "Throw" argument set to true. The call to [[Set]] in step 4 there returns false (because the property is readonly), so Set() throws an exception. This is then propagated out.
So the observed behavior is correct: an exception should be thrown here.
Status: UNCONFIRMED → RESOLVED
Closed: 10 years ago
Resolution: --- → INVALID
Comment 3•10 years ago
|
||
I filed https://code.google.com/p/v8/issues/detail?id=4146 on Chrome here.
Also filed https://code.google.com/p/v8/issues/detail?id=4147 and bug 1168416 on a somewhat related testcase that both SpiderMonkey and V8 get wrong (in slightly different ways).
Comment 4•10 years ago
|
||
http://people.mozilla.org/~jorendorff/es6-draft.html#sec-validateandapplypropertydescriptor
Step 4.
Since lastIndex is being set to the exactly the same value no error is thrown.
Status: RESOLVED → REOPENED
Ever confirmed: true
Resolution: INVALID → ---
Updated•10 years ago
|
Flags: needinfo?(jwalden+bmo)
Comment 6•10 years ago
|
||
(In reply to Erik Arvidsson from comment #4)
> http://people.mozilla.org/~jorendorff/es6-draft.html#sec-
> validateandapplypropertydescriptor
>
> Step 4.
>
> Since lastIndex is being set to the exactly the same value no error is
> thrown.
21.2.5.8 RegExp.prototype [ @@replace ], step 10.c calls [[Set]] (through the Set() abstract operation). And [[Set]], step 5.a returns false which will then lead to Set() throwing the TypeError.
Comment 7•10 years ago
|
||
Yes, exactly. This is not ending up in ValidateAndApplyPropertyDescriptor at all, nor even ending up in DefineOwnProperty. It bails out directly from [[Set]].
Status: REOPENED → RESOLVED
Closed: 10 years ago → 10 years ago
Flags: needinfo?(jwalden+bmo)
Resolution: --- → INVALID
This is just something that is unfortunately **** in the standard. The problem is understandable when the regular expression has the global flag set, but unfortunately basically all RegExp operations throw on match failure regardless of the flags due to a mistake in "21.2.5.2.2 Runtime Semantics: RegExpBuiltinExec" step 12.a.i which always sets lastIndex to 0 with a throw on failure if the regular expression doesn't successfully match before the end of the string.
The RegExpBuiltinExec step is pointless because if the RegExp is non-global/non-sticky the lastIndex can never have a non-0 value. In fact that step is one of the only places where lastIndex is touched without gating by global or sticky. The only other place is in "21.2.5.9 RegExp.prototype [ @@search ]" where it blindly saves and restores the lastIndex around a call to RegExpBuiltinExec (also pointless if non-global/non-sticky and so should be gated).
Comment 9•9 years ago
|
||
Please send spec feedback to es-discuss@mozilla.org....
You need to log in
before you can comment on or make changes to this bug.
Description
•