Last Comment Bug 453776 - Strange behavior with replace, unshift
: Strange behavior with replace, unshift
Status: RESOLVED FIXED
: testcase
Product: Core
Classification: Components
Component: JavaScript Engine (show other bugs)
: Trunk
: x86 Mac OS X
: -- enhancement (vote)
: ---
Assigned To: general
:
Mentors:
Depends on:
Blocks: jsfunfuzz
  Show dependency treegraph
 
Reported: 2008-09-04 23:45 PDT by Jesse Ruderman
Modified: 2011-11-17 18:18 PST (History)
5 users (show)
sayrer: wanted‑next+
sayrer: blocking1.9.2-
See Also:
Crash Signature:
(edit)
QA Whiteboard:
Iteration: ---
Points: ---
Has Regression Range: ---
Has STR: ---


Attachments

Description Jesse Ruderman 2008-09-04 23:45:34 PDT
./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...
Comment 1 Jesse Ruderman 2008-10-31 12:42:19 PDT
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.
Comment 2 Gary Kwong [:gkw] [:nth10sd] 2009-04-16 09:28:19 PDT
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.
Comment 3 Ryan VanderMeulen [:RyanVM] 2011-11-17 17:33:24 PST
With a current js shell, I get "TypeError: can't convert undefined to object" when I try the testcase in comment 0 now.
Comment 4 Jeff Walden [:Waldo] (remove +bmo to email) 2011-11-17 18:18:45 PST
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.

Note You need to log in before you can comment on or make changes to this bug.