Bug 830614. Wrapping a wrappercached WebIDL object should watch out for reentry via WrapNativeParent. r=peterv
authorBoris Zbarsky <bzbarsky@mit.edu>
Tue, 15 Jan 2013 14:04:24 -0500
changeset 118926 e8efa257d99bcf6013ca044ca3eeabb49f72b67e
parent 118925 bb16e053e620443bb490ab19cb656ecdec91527e
child 118927 609b32dec10dd2120787e0c54c293865aa828ff2
push id21355
push userbzbarsky@mozilla.com
push dateTue, 15 Jan 2013 19:04:51 +0000
treeherdermozilla-inbound@609b32dec10d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspeterv
bugs830614
milestone21.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 830614. Wrapping a wrappercached WebIDL object should watch out for reentry via WrapNativeParent. r=peterv
content/xbl/crashtests/830614-1.xul
content/xbl/crashtests/crashtests.list
dom/bindings/Codegen.py
new file mode 100644
--- /dev/null
+++ b/content/xbl/crashtests/830614-1.xul
@@ -0,0 +1,24 @@
+<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+        onload="document.getElementById('trigger');">
+  <box style="display: none">
+    <bindings xmlns="http://www.mozilla.org/xbl">
+      <binding id="crash">
+        <implementation>
+          <constructor>
+            // Fetch it
+            var obj = this.getElementsByTagName("box")[0];
+            // And make it preserve its wrapper.  Note that this will happen
+            // while we're wrapping our box as the parent for id="trigger",
+            // so then we'll unwind and things will be bad.
+            if (obj) obj.expando = 5;
+          </constructor>
+        </implementation>
+      </binding>
+    </bindings>
+    <box style="-moz-binding:url(#crash);">
+      <box id="trigger"/>
+    </box>
+  </box>
+  <!-- Make sure we load our XBL before we try to run our test -->
+  <box style="-moz-binding:url(#crash);"/>
+</window>
--- a/content/xbl/crashtests/crashtests.list
+++ b/content/xbl/crashtests/crashtests.list
@@ -31,8 +31,9 @@ load 464863-1.xhtml
 load 472260-1.xhtml
 load 477878-1.html
 load 492978-1.xul
 asserts-if(Android,2) load 493123-1.xhtml
 load 495354-1.xhtml
 load 507628-1.xhtml
 load 507991-1.xhtml
 load set-field-bad-this.xhtml
+load 830614-1.xul
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -1784,16 +1784,26 @@ class CGWrapWithCacheMethod(CGAbstractMe
 
         return """  *aTriedToWrap = true;
 
   JSObject* parent = WrapNativeParent(aCx, aScope, aObject->GetParentObject());
   if (!parent) {
     return NULL;
   }
 
+  // That might have ended up wrapping us already, due to the wonders
+  // of XBL.  Check for that, and bail out as needed.  Scope so we don't
+  // collide with the "obj" we declare in CreateBindingJSObject.
+  {
+    JSObject* obj = aCache->GetWrapper();
+    if (obj) {
+      return obj;
+    }
+  }
+
   JSAutoCompartment ac(aCx, parent);
   JSObject* global = JS_GetGlobalForObject(aCx, parent);
 %s
   JSObject* proto = GetProtoObject(aCx, global);
   if (!proto) {
     return NULL;
   }