Closed Bug 166420 Opened 23 years ago Closed 23 years ago

Objects with a toString method returning a String instance on stack cause Error instance creation to fail

Categories

(Core :: JavaScript Engine, defect)

x86
Windows 2000
defect
Not set
normal

Tracking

()

VERIFIED FIXED

People

(Reporter: mj, Assigned: khanson)

References

Details

Attachments

(3 files)

When 'new Error()' is called, a stack trace is produced and stored in the errors' stack property. The stack lists all functions called with all their arguments, where toString() is called on each such argument. If one of these arguments happens to be an object with a toString() function that returns a String instance (instead of a string literal), the creation of the stack trace fails, and execution stops completely. No errors are shown on the javascript console. test case will follow.
Attached file Testcase
Testcase illustrates problem. Expected behaviour is an alert box showing the created stack trace for clicking either button.
It isn't clear to me wether or not toString() is always expected to return a string literal, or if a String instance should be permitted as well. If a String instance is permitted, the stack trace should include it's toString() value, otherwise an exception should be raised stating that a string literal was expected.
I think we can illustrate the problem this way. In the current JS shell: js> function testObj(label) {this.toString = function() {return label;}} -------------- CREATE AN OBJECT WITH |label| = A STRING LITERAL -------------- js> var obj1 = new testObj('Hello') js> obj1.toString() Hello js> obj1 Hello -------------- CREATE AN OBJECT WITH |label| = A STRING OBJECT ---------------- js> var obj2 = new testObj(new String('Hello')) js> obj2.toString() Hello js> obj2 <----------------- NO RETURN VALUE !!! Notice in BOTH cases the toString() method returns the correct value if called EXPLICITLY. The failure seems to occur only when toString() is invoked implicity. And I think that's what's happening during the formation of |Error.stack|
Assignee: rogerl → khanson
Attached file Testcase (version 2)
The standalone JS testcase is just this: var obj1 = new testObject('[String Literal Test Object]'); var obj2 = new testObject(new String('[String Instance Test Object]')); test(obj1); test(obj2); function test(obj) { e = new Error('CUSTOM ERROR'); print("Created Error, stack trace:\n\n" + e.stack); } function testObject(label) { this.toString = function() {return label;}; } When I run this in the JS shell, this is the output. Notice that |test(obj1)| gives the desired result, but |test(obj2)| errors: Created Error, stack trace: Error(CUSTOM ERROR)@:0 test([String Literal Test Object])@../../tests/166420.js:9 @../../tests/166420.js:4 ../../tests/166420.js:9: can't convert Object to string However, when we run the HTML version in the browser, we do NOT get this or any other error in the JavaScript Console. I wonder why not?
An invalid toString method must generate an error, per ECMA-262 Edition 3 8.6.2.6, where you'll end up at step 9 given a non-primitive value returned from toString and no valueOf (or a valueOf that returns a non-primitive value). I'm marking this bug as being blocked by bug 166743, which has a patch. That patch may not go far enough: it seems to me that all errors incurred while computing the stack property of an error object need to be suppressed. More in bug 166743. /be
Depends on: 166743
Fixed by fixing bug 166743. Maybe this should have been dup'd -- I'll leave that to pschwartau. /be
Status: NEW → RESOLVED
Closed: 23 years ago
Resolution: --- → FIXED
Marking Verified Fixed. ---------------- RECALL TEST OUTPUT BEFORE THE FIX ---------------------- (|test(obj1)| gave a desired result, but |test(obj2)| errored): Created Error, stack trace: Error(CUSTOM ERROR)@:0 test([String Literal Test Object])@../../tests/166420.js:9 @../../tests/166420.js:4 ../../tests/166420.js:9: can't convert Object to string ---------------------------------------------------------------------------- -------------------- TEST OUTPUT AFTER THE FIX ----------------------------- Created Error, stack trace: Error("CUSTOM ERROR")@:0 test([object Object])@../../tests/166420.js:9 @../../tests/166420.js:4 Created Error, stack trace: Error("CUSTOM ERROR")@:0 test([object Object])@../../tests/166420.js:9 @../../tests/166420.js:5 ---------------------------------------------------------------------------- --------------------------- SUMMARY ----------------------------------- In the above testcase, we see that: |test(obj2)| is no longer erroring. At the same time, however, note that: |test(obj1)| no longer outputs "test([String Literal Test Object])@...etc." but rather: "test([object Object])@...etc." This shows the effect of the fix to bug 166743, where it was decided: > Calling toString on arbitrary objects in an error condition > just doesn't seem like a good thing. I'd suggest that the best > we can do is append the string [Object] (or something like that) > wherever we find an object parameter. Martijn: this fix should be available in Mozilla builds dated tomorrow, 2002-09-06. Please reopen this bug if you still are seeing the problem; thanks -
Status: RESOLVED → VERIFIED
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: