Bug 27169

Summary: typing "document.__proto__" in inspector throws exception
Product: WebKit Reporter: Eric Seidel (no email) <eric>
Component: Web Inspector (Deprecated)Assignee: Nobody <webkit-unassigned>
Status: RESOLVED FIXED    
Severity: Normal CC: abarth, joepeck, keishi, timothy
Priority: P2    
Version: 528+ (Nightly build)   
Hardware: PC   
OS: OS X 10.5   
Bug Depends on:    
Bug Blocks: 60014    
Attachments:
Description Flags
Javascript Workaround timothy: review+

Description Eric Seidel (no email) 2009-07-10 18:12:10 PDT
typing "document.__proto__" in inspector throws exception

> document.__proto__
file:///Users/eseidel/Projects/build/Debug/WebCore.framework/Resources/inspector/utilities.js:843TypeError: Result of expression 'this.nodeName' [undefined] is not an object.
Comment 1 Joseph Pecoraro 2009-07-22 23:48:47 PDT
After some digging it appears this is a rather weird edge case that can be reduced to this:

> typeof document.__proto__
object

> document.__proto__ instanceof window.Node
true

> document.__proto__.nodeName
undefined

> document.__proto__.nodeType
undefined


So when the formatter actually gets down to formating as a node, jumps into utilities.js's nodeTitleInfo(), does a switch on obj.nodeType (undefined) which hits the default case and tries obj.nodeName and throws the error.

The Javascript workaround that I feel is the most responsible would be to treat "document.__proto__" as the type it returns via "typeof", which is "object", instead of "node".  To be more general, if something is an "instanceof Node" then to really be sure its a node it should have a "nodeType" property.  Otherwise its lieing!

Maybe the solution is to change something in the Document C++ implementation so document.__proto__ instanceof "Node" returns false instead of true.
Comment 2 Joseph Pecoraro 2009-07-22 23:53:16 PDT
Created attachment 33317 [details]
Javascript Workaround

This would be the javascript workaround.  I looked into what Firefox does and they don't report document.__proto__ as an instanceof Node!  So maybe that would be the better route.

WebKit via Web Inspector:
> document.__proto__ instanceof window.Node
true

Firefox via Firebug:
> document.__proto__ instanceof window.Node
false
Comment 3 Keishi Hattori 2009-07-23 04:54:27 PDT
(In reply to comment #2)
> This would be the javascript workaround.  I looked into what Firefox does and
> they don't report document.__proto__ as an instanceof Node!  So maybe that
> would be the better route.

Opera returns false too.

But I can't figure out why.

From my understanding, the implementation of
    FOO instanceof BAR
should be something like this
function instanceof(FOO, BAR) {
    var o = FOO;
    while (o = o.__proto__) {
        if (o === BAR.prototype)
            return true;
    }
    return false;
}
And I think this is written in JSObject::hasInstance which implements [[hasInstance]] from the spec.

WebCore's prototype chain looks like this
document.__proto__ = HTMLDocumentPrototype
document.__proto__. __proto__ = DocumentPrototype
document.__proto__. __proto__. __proto__ = NodePrototype
document.__proto__. __proto__. __proto__.__proto__ = Object

And 
(Node.prototype === document.__proto__. __proto__. __proto__) is true

So (document.__proto__ instanceof window.Node) returns true.

In Firefox (Node.prototype === document.__proto__. __proto__. __proto__) is also true so I don't understand why Firefox is returning false for (document.__proto__ instanceof window.Node).

Which is correct?
Comment 4 Timothy Hatcher 2009-07-23 11:37:42 PDT
obj.nodeType === undefined

would be best written as:

typeof obj.nodeType === "undefined"
Comment 5 Eric Seidel (no email) 2009-07-23 11:40:32 PDT
Did we decide there was a real bug here in either WebKit or Firefox?  If so, we should file it...
Comment 6 Joseph Pecoraro 2009-07-23 11:49:42 PDT
(In reply to comment #5)
> Did we decide there was a real bug here in either WebKit or Firefox?  If so, we
> should file it...

Filed.
https://bugs.webkit.org/show_bug.cgi?id=27611
Comment 7 Adam Barth 2009-07-24 02:14:53 PDT
Committing to http://svn.webkit.org/repository/webkit/trunk ...
	M	WebCore/ChangeLog
	M	WebCore/inspector/front-end/utilities.js
Committed r46345
	M	WebCore/ChangeLog
	M	WebCore/inspector/front-end/utilities.js
r46345 = 1203ffee2d3ca9a82f4ecd7eecf5061b5a6091e0 (trunk)
No changes between current HEAD and refs/remotes/trunk
Resetting to the latest refs/remotes/trunk
http://trac.webkit.org/changeset/46345