Closed Bug 453776 Opened 16 years ago Closed 13 years ago

Strange behavior with replace, unshift

Categories

(Core :: JavaScript Engine, enhancement)

x86
macOS
enhancement
Not set
normal

Tracking

()

RESOLVED FIXED

People

(Reporter: jruderman, Unassigned)

Details

(Keywords: testcase)

./js

print("fa".replace(/f/g, [].unshift));
for (var i = 0; [][i] != undefined; ++i)
  print(uneval([][i]));

Prints
3a
"f"
0
"fa"

Seems like the first line causes [].unshift to be called with |this| not the global, but instead Object.prototype??  If I replace [].unshift with a user-defined function, its |this| is the global...
Igor explains in bug 452913 comment 9:

> string.replace(regex, f) will use the parent of f as its "this" to call the
> function f. In SpiderMonkey Array's natives have Array.prototype as their
> parent. The latter is not specified in EcmaScript and implementations are
> free to do what ever suits them since.
Severity: normal → enhancement
I'm nominating this early on for blocking1.9.2, this is common in jsfunfuzz by producing false-positive hangs involving .replace and .unshift behaviour. Reducing hangs take much longer than crashes or assertions so when I painfully reduce a hang testcase only to find it's this bug, it's much time wasted.
Flags: blocking1.9.2?
Flags: wanted-next+
Flags: blocking1.9.2?
Flags: blocking1.9.2-
With a current js shell, I get "TypeError: can't convert undefined to object" when I try the testcase in comment 0 now.
Bug 514570 changed behavior to not pass the parent but rather to pass |undefined| as this, which -- while not as explicitly specified by ES5 as I would desire -- is the right thing to pass.  And when that flows into a builtin function, it causes a TypeError to be thrown.  These are the right semantics; if fuzzers still have problems with this, they're going to have to cope.
Status: NEW → RESOLVED
Closed: 13 years ago
Resolution: --- → FIXED
You need to log in before you can comment on or make changes to this bug.