Closed
Bug 224956
Opened 21 years ago
Closed 21 years ago
crash if implied multiplication used in javascript statement
Categories
(Core :: JavaScript Engine, defect, P1)
Tracking
()
VERIFIED
FIXED
mozilla1.6beta
People
(Reporter: sharkey9x, Assigned: brendan)
References
()
Details
(Keywords: js1.5)
Attachments
(2 files)
3.64 KB,
patch
|
shaver
:
superreview+
|
Details | Diff | Splinter Review |
1.04 KB,
patch
|
Details | Diff | Splinter Review |
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.6a) Gecko/20031028 Firebird/0.7+ (aebrahim) Build Identifier: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.6a) Gecko/20031028 Firebird/0.7+ (aebrahim) If FB comes to a javascript statement using implied multipication, two terms enclosed in parenthesis that are next to eachother without a *, it crashes. I came across this when I mistyped and forgot the *. It should return an error of "number is not a function". Mozilla 1.5 returns the error. I'v heard that Firebird 0.7 returns the error as well. I don't have a nightly of the suite to test, but the latest nightly of FB crashes. Reproducible: Always Steps to Reproduce: 1.Load a page using implied multiplication, such as http://sharkshack.digitalmob.com/bugzilla/crashes.html Actual Results: Browser crashed. Expected Results: Throw an error of "number is not a function" From the Windows Report: AppName: mozillafirebird.exe AppVer: 1.6.20031.2810 ModName: js3250.dll ModVer: 4.0.0.0 Offset: 00026646
Comment 1•21 years ago
|
||
Confirming. Not Firebird-specific.
Component: General → JavaScript Engine
Product: Firebird → Browser
Version: unspecified → Trunk
This bug has still the wrong owners. CC'ing Phil and Brendan to get it on the radar. And these crash too: ""() true() null() (void 0)()
This regressed at 2003-10-21 between 12:00 and 24:00. So it must be caused by the checkin for bug 196097.
Assignee | ||
Comment 5•21 years ago
|
||
mine. /be
Assignee: blake → brendan
Status: UNCONFIRMED → NEW
Ever confirmed: true
Assignee | ||
Comment 6•21 years ago
|
||
Hoping zack can review. /be
Assignee | ||
Updated•21 years ago
|
Attachment #135061 -
Flags: superreview?(shaver)
Attachment #135061 -
Flags: review?(zack-weg)
Assignee | ||
Comment 7•21 years ago
|
||
Why this regressed: bug 196097 reordered code in js_Invoke so that null() and other invalid call expressions no longer failed due to an early error check for primitive (non-object) callee. This meant that code in js_Interpret that pushed primitive types (to wit: JSOP_NULL, JSOP_FALSE, JSOP_TRUE, JSOP_ZERO, JSOP_ONE, JSOP_JSOP_UINT16, JSOP_NUMBER, JSOP_STRING) could no longer refrain from setting the |obj| interpreter register (pushed by JSOP_PUSHOBJ after the callee expr is evaluated and pushed, in the code sequence leading up to JSOP_CALL). These ops must all set obj = NULL. I also spiffed up js_DecompileValueGenerator to avoid saying "object is not function" for null(). Any minor footprint growth here will be made up for by the patch in bug 224306. /be
Assignee | ||
Comment 8•21 years ago
|
||
I made this tweak to ComputeThis: +++ jsinterp.c 8 Nov 2003 18:15:39 -0000 @@ -601,18 +601,18 @@ ComputeThis(JSContext *cx, JSObject *thi * * // in window w2 * var h = w1.g() * alert(h() == w1) * * The alert should display "true". */ JS_ASSERT(!(fp->flags & JSFRAME_CONSTRUCTING)); - parent = OBJ_GET_PARENT(cx, JSVAL_TO_OBJECT(fp->argv[-2])); - if (!parent) { + if (JSVAL_IS_PRIMITIVE(fp->argv[-2]) || + !(parent = OBJ_GET_PARENT(cx, JSVAL_TO_OBJECT(fp->argv[-2])))) { thisp = cx->globalObject; } else { The ?: expression in the attached patch conditionally sets parent = NULL so if (!parent) can succeed for both the non-primitive callee and the object-callee-but-with-null-parent cases, but it wastes source space and maybe a branch-around-else-expression in the ternary. /be
Comment 9•21 years ago
|
||
Testcase added to JS testsuite: mozilla/js/tests/js1_5/Regress/regress-224956.js Currently passing in the Rhino shell, but crashing in SpiderMonkey (both debug and optimized).
QA Contact: PhilSchwartau
Assignee | ||
Comment 10•21 years ago
|
||
Testcase worksforme with the patch applied. Zack, can you review? /be
Comment on attachment 135061 [details] [diff] [review] proposed fix Aye. Why XXX the comment in js_DVG? It seems like a legit choice, and not in need of future fixage.
Attachment #135061 -
Flags: superreview?(shaver) → superreview+
Assignee | ||
Comment 12•21 years ago
|
||
shaver: I regret special cases per opcode when more general schemes come to mind. Ideally, there would be come format flag that js_DVG could use to index into a sub-table of atom pointers (for false, true, null, 0, 1, etc. -- all the literal JOF_BYTE bytecodes: JSOP_FALSE, etc.). /be
Assignee | ||
Comment 13•21 years ago
|
||
Fixed (one review is enough for SpiderMonkey changes, but zack, feel free to review post-checkin). /be
Status: ASSIGNED → RESOLVED
Closed: 21 years ago
Resolution: --- → FIXED
Comment 14•21 years ago
|
||
I feel not qualified to review this, but it seems to work. I looked at the code too and am wondering how __noSuchMethod__ is supposed to work. It has sometimes quite unexpected behavior (not changed by the patch): js> __noSuchMethod__= function ( id ) { return "ID: <" + id + ">" } function (id) { return "ID: <" + id + ">"; } js> x() 2: ReferenceError: x is not defined js> this.x() ID: <x> js> this["x"]() ID: <x> js> this["x"+""]() 5: TypeError: this["x"] is not a function js> y= "x" x js> this[y]() 7: TypeError: this[y] is not a function js> var x js> x() ID: <x> js> with ( {} ) { x() } ID: <x> js> x= 1 1 js> x() ID: <x> js> x= {} [object Object] js> x() 14: TypeError: x is not a function js> NaN() ID: <NaN> js> undefined() ID: <undefined> js> __noSuchMethod__= {} [object Object] js> undefined() Assertion failure: -depth <= spindex && spindex < 0, at jsopcode.c:2583 Aborted Is it intended that a defined variable invoked as function triggers __noSuchMethod__? If not, this patch may be better (but I may be totally wrong because I understand the code only in fragments): Index: jsinterp.c =================================================================== RCS file: /cvsroot/mozilla/js/src/jsinterp.c,v retrieving revision 3.130 diff -u -5 -r3.130 jsinterp.c --- jsinterp.c 3 Nov 2003 20:23:23 -0000 3.130 +++ jsinterp.c 9 Nov 2003 10:00:42 -0000 @@ -658,10 +658,14 @@ * return false, causing a goto out2 with ok set to false. Also set * frame.flags and frame.argv so that ComputeThis can use them. */ vp = sp - (2 + argc); v = *vp; + + if (JSVAL_IS_PRIMITIVE(v) && (!JSVAL_IS_VOID(v) || JSVAL_IS_NULL(vp[1]))) + goto bad; + frame.rval = JSVAL_VOID; frame.flags = flags; frame.argv = sp - argc; /*
Assignee | ||
Comment 15•21 years ago
|
||
See bug 196097, which wanted something like Smalltalk's doesNotUnderstand message. The furthest I was willing to go was an extension for named methods only (JSOP_NAME, JSOP_GETPROP), not for computed method names (this[y](), which emits JSOP_GETELEM to evaluate this[y]). It did not matter to me whether the named property was defined. Your patch: + + if (JSVAL_IS_PRIMITIVE(v) && (!JSVAL_IS_VOID(v) || JSVAL_IS_NULL(vp[1]))) + goto bad; + would still allow __noSuchMethod__ to be called for o = {m:undefined}; o.m(), because v would be primitive (42), void, and the |this| parameter (vp[1]) would be o, which is not null. Since there's no easy way for js_Invoke to tell whether m was defined, with void value, or not defined (therefore resulting in the void value |undefined| from the evaluation of o.m), it didn't seem any better to me to make the other primitive cases different. (BTW, I regret deciding long ago, in 1995, when designing JS, to make o.m return undefined when !('m' in o). It's way too late to change that, although the strict option, especially combined with werror, can make partial amends.) It's actually possible for __noSuchMethod__ to access the named property and use its primitive non-void value, other than by calling it. That could be useful, e.g. for call-as-getter and call-as-filtered-getter, and since extra code is required to remove the potential usefulness, I kept it both simple and more useful. I don't propose __noSuchMethod__ as an extension to the standard. It's really for the TIBET guys (see http://www.technicalpursuit.com/). The assertion botch in js_DecompileValueGenerator you found is harmless in a release build, but I'm gonna fix it anyway. Thanks for pointing it out. Feel free to report other issues in bug 196097 or a new bug. /be
Comment 16•21 years ago
|
||
Marking Verified Fixed. The above testcase now passes in both the debug and optimized JS shell on WinNT and Linux. Furthermore no regressions have been introduced, according to the JS testsuite.
Status: RESOLVED → VERIFIED
Assignee | ||
Comment 17•21 years ago
|
||
I've tested that we get consistent results from js_DecompileValueGenerator, irrespective of caller stack depth (the sink function call generated below forces depth > 4), with this script: function sink() {} __noSuchMethod__ = {}; t = ["undefined", "null", "false", "true", "0", "1", "65536", "3.14", "'hi'"]; for (i = 0; i < t.length; i++) { try { eval(t[i] + "()"); } catch (e) { print("oops("+i+"): " + e); } try { Function("a", "b", "c", "d", "sink((a+b)*(c+d)); "+t[i]+"();")(1,2,3,4); } catch (e) { print("oop2("+i+"): " + e); } } which produces this output, as expected: oops(0): TypeError: undefined is not a function oop2(0): TypeError: undefined is not a function oops(1): TypeError: null is not a function oop2(1): TypeError: null is not a function oops(2): TypeError: boolean is not a function oop2(2): TypeError: boolean is not a function oops(3): TypeError: boolean is not a function oop2(3): TypeError: boolean is not a function oops(4): TypeError: number is not a function oop2(4): TypeError: number is not a function oops(5): TypeError: number is not a function oop2(5): TypeError: number is not a function oops(6): TypeError: number is not a function oop2(6): TypeError: number is not a function oops(7): TypeError: number is not a function oop2(7): TypeError: number is not a function oops(8): TypeError: string is not a function oop2(8): TypeError: string is not a function /be
Comment 18•21 years ago
|
||
> (BTW, I regret deciding long ago, in 1995, when designing JS, to make o.m return
> undefined when !('m' in o). It's way too late to change that, although the
> strict option, especially combined with werror, can make partial amends.)
I like the behavior and hate the strict warnings for it. Most time it doesn't
matter if something doesn't exist, is undefined or null. The additional test for
existence can hurt performance badly.
Comment 19•21 years ago
|
||
*** Bug 225537 has been marked as a duplicate of this bug. ***
Comment 20•20 years ago
|
||
Comment on attachment 135061 [details] [diff] [review] proposed fix removing obsolete review request
Attachment #135061 -
Flags: review?(zack-weg)
Updated•19 years ago
|
Flags: testcase+
You need to log in
before you can comment on or make changes to this bug.
Description
•