OK, coming back around to this - I&#39;m looking at the automatically generated constructors. As an example, let&#39;s look at something simple like EventException.<div><br></div><div><div>    JSEventExceptionConstructor(ExecState* exec)</div>

<div>        : DOMObject(JSEventExceptionConstructor::createStructure(exec-&gt;lexicalGlobalObject()-&gt;objectPrototype()))</div><div>    {</div><div>        putDirect(exec-&gt;propertyNames().prototype, JSEventExceptionPrototype::self(exec, <b>exec-&gt;lexicalGlobalObject()</b>), None);</div>

<div>    }</div><div><br></div><div>It looks like this uses the current lexicalGlobalObject when constructing the event exceptions prototype chain. Furthermore, JSDOMGlobalObject::getDOMConstructor() and JSDOMBinding.cpp both use the lexical global object to cache constructors. </div>

<div><br></div><div>So in the case the Maciej describes below, it *looks* like for auto-generated constructors, the window you grab the constructor from is immaterial - it always looks up/caches the constructor object in lexical global scope (i.e. referencing window.EventExecutor returns the same value for a given lexical scope, no matter what &quot;window&quot; refers to) so his bug won&#39;t actually happen for his case.</div>
<div><br></div><div>I guess this behavior might be a bug, given this bugzilla entry: <a href="https://bugs.webkit.org/show_bug.cgi?id=21138">https://bugs.webkit.org/show_bug.cgi?id=21138</a>, but I&#39;m somewhat uncertain about that conclusion as it would mean that 95% of our constructors are buggy. Anyone want to confirm this?</div>
<div><br></div><div>The other place where problems happen are for custom constructors that are passed a reference to a JSDOMGlobalObject - in these situations we cache the constructor on the passed-in JSDOMGlobalObject itself rather than on the lexicalGlobalObject. So it seems incorrect to do this:</div>
<div><br></div><div><div>JSMessageChannelConstructor::JSMessageChannelConstructor(ExecState* exec, JSDOMGlobalObject* globalObject)</div><div>    : DOMObject(JSMessageChannelConstructor::createStructure(<b>exec-&gt;lexicalGlobalObject()</b>-&gt;objectPrototype()))</div>
<div>    , m_globalObject(globalObject)</div><div>{</div><div>    putDirect(exec-&gt;propertyNames().prototype, JSMessageChannelPrototype::self(exec, <b>exec-&gt;lexicalGlobalObject()</b>), None);</div><div>}</div><div><br>
</div></div></div><div>Note that the constructor prototype is being generated using lexicalGlobalObject, but then the result is being cached in the passed-in globalObject, leaving you with a reference in &quot;globalObject&quot; to a constructor with a prototype chain that might be from a foreign context (maciej&#39;s bug he described previously).</div>
<div><br></div><div>So it seems like we should never reference lexicalGlobalObject in our constructor/prototype creation code at all. if I invoke &quot;new otherWindow.MessageChannel()&quot;, I should get a MessageChannel object whose prototype chain == otherWindow.MessageChannel.prototype. So the constructor should look like this instead:</div>
<div><br></div><div><div>JSMessageChannelConstructor::JSMessageChannelConstructor(ExecState* exec, JSDOMGlobalObject* globalObject)</div><div>    : DOMObject(JSMessageChannelConstructor::createStructure(<b>globalObject</b>-&gt;objectPrototype()))</div>
<div>    , m_globalObject(globalObject)</div><div>{</div><div>    putDirect(exec-&gt;propertyNames().prototype, JSMessageChannelPrototype::self(exec, <b>globalObject</b>), None);</div><div>}</div></div><div><br></div><div>
Sorry to belabor the point, but I want to make sure I don&#39;t propagate invalid behavior in new code I&#39;m writing, but I&#39;m having trouble finding *any* constructors that are doing the right thing currently, so I figure I must be missing something :)</div>
<div><br></div><div>-atw</div><div><br><div class="gmail_quote">On Tue, Jun 23, 2009 at 5:14 PM, Adam Barth <span dir="ltr">&lt;<a href="mailto:abarth@webkit.org" target="_blank">abarth@webkit.org</a>&gt;</span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">[+sam]<br>
<div><br>
On Tue, Jun 23, 2009 at 5:11 PM, Drew Wilson&lt;<a href="mailto:atwilson@google.com" target="_blank">atwilson@google.com</a>&gt; wrote:<br>
&gt; On Tue, Jun 23, 2009 at 4:53 PM, Maciej Stachowiak &lt;<a href="mailto:mjs@apple.com" target="_blank">mjs@apple.com</a>&gt; wrote:<br>
</div><div>&gt;&gt; Also, there might be a subtle bug in the above code: what if window.Worker<br>
&gt;&gt; is first accessed from a different frame? Then the prototype of the Worker<br>
&gt;&gt; constructor itself will use the other frame&#39;s Object prototype as its<br>
&gt;&gt; prototype. I&#39;m not sure if that is right. I think maybe JSWorkerConstructor<br>
&gt;&gt; should be passed the global object from which it is retrieved as a property,<br>
&gt;&gt; instead of using the lexical global object.<br>
&gt;<br>
&gt; Good catch. This bug seems to be in all our custom generated constructors.<br>
<br>
</div>Yes.  This has caused us headaches (e.g., security bugs) in the past.<br>
<font color="#888888"><br>
Adam<br>
</font></blockquote></div><br></div>