Bug 1535661 - Fix CORS issues in Markup Panel r=pbro
authorMichael Ratcliffe <mratcliffe@mozilla.com>
Mon, 18 Mar 2019 09:22:50 +0000
changeset 464755 4641d251c20864795f672b873466c41fb5d014d9
parent 464754 51ec0da695a49736e1b25417f28c525c140d0d51
child 464756 2e3d01a1b848d074d05970dbcbdc31b9930a4834
push id112481
push userrgurzau@mozilla.com
push dateMon, 18 Mar 2019 21:51:19 +0000
treeherdermozilla-inbound@6ed5e5a3e39e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspbro
bugs1535661
milestone67.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 1535661 - Fix CORS issues in Markup Panel r=pbro One change is in `node.js::isScrollable()` so I decided to assign this to you for review. Feel free to re-assign as you feel appropriate if you don't have time. ### Try https://treeherder.mozilla.org/#/jobs?repo=try&revision=2e2f20af3f902ea65436bcfd288b3e075d6508f8 Differential Revision: https://phabricator.services.mozilla.com/D23803
devtools/server/actors/inspector/event-collector.js
devtools/server/actors/inspector/node.js
--- a/devtools/server/actors/inspector/event-collector.js
+++ b/devtools/server/actors/inspector/event-collector.js
@@ -260,17 +260,25 @@ class MainEventCollector {
         Services.els.getListenerInfoFor(node.parentNode) || [];
 
       return [...winListeners, ...docElementListeners, ...docListeners];
     }
     return Services.els.getListenerInfoFor(node) || [];
   }
 
   getJQuery(node) {
+    if (Cu.isDeadWrapper(node)) {
+      return null;
+    }
+
     const global = this.unwrap(node.ownerGlobal);
+    if (!global) {
+      return null;
+    }
+
     const hasJQuery = global.jQuery && global.jQuery.fn && global.jQuery.fn.jquery;
 
     if (hasJQuery) {
       return global.jQuery;
     }
     return null;
   }
 
@@ -385,24 +393,35 @@ class JQueryEventCollector extends MainE
         isBeforePseudoElement(node) || isAfterPseudoElement(node)) {
       if (checkOnly) {
         return false;
       }
       return handlers;
     }
 
     let eventsObj = null;
+    const data = jQuery._data || jQuery.data;
 
-    const data = jQuery._data || jQuery.data;
     if (data) {
       // jQuery 1.2+
-      eventsObj = data(node, "events");
+      try {
+        eventsObj = data(node, "events");
+      } catch (e) {
+        // We have no access to a JS object. This is probably due to a CORS
+        // violation. Using try / catch is the only way to avoid this error.
+      }
     } else {
       // JQuery 1.0 & 1.1
-      const entry = jQuery(node)[0];
+      let entry;
+      try {
+        entry = entry = jQuery(node)[0];
+      } catch (e) {
+        // We have no access to a JS object. This is probably due to a CORS
+        // violation. Using try / catch is the only way to avoid this error.
+      }
 
       if (!entry || !entry.events) {
         if (checkOnly) {
           return false;
         }
         return handlers;
       }
 
@@ -469,17 +488,24 @@ class JQueryLiveEventCollector extends M
 
     const data = jQuery._data || jQuery.data;
 
     if (data) {
       // Live events are added to the document and bubble up to all elements.
       // Any element matching the specified selector will trigger the live
       // event.
       const win = this.unwrap(node.ownerGlobal);
-      const events = data(win.document, "events");
+      let events = null;
+
+      try {
+        events = data(win.document, "events");
+      } catch (e) {
+        // We have no access to a JS object. This is probably due to a CORS
+        // violation. Using try / catch is the only way to avoid this error.
+      }
 
       if (events) {
         for (const [, eventHolder] of Object.entries(events)) {
           for (const [idx, event] of Object.entries(eventHolder)) {
             if (typeof idx !== "string" || isNaN(parseInt(idx, 10))) {
               continue;
             }
 
--- a/devtools/server/actors/inspector/node.js
+++ b/devtools/server/actors/inspector/node.js
@@ -257,19 +257,25 @@ const NodeActor = protocol.ActorClassWit
   get isScrollable() {
     // Check first if the element has an overflow area, bail out if not.
     if (this.rawNode.clientHeight === this.rawNode.scrollHeight &&
         this.rawNode.clientWidth === this.rawNode.scrollWidth) {
       return false;
     }
 
     // If it does, then check it also has scrollbars.
-    const walker = new DocumentWalker(this.rawNode, this.rawNode.ownerGlobal,
-                                      { filter: scrollbarTreeWalkerFilter });
-    return !!walker.firstChild();
+    try {
+      const walker = new DocumentWalker(this.rawNode, this.rawNode.ownerGlobal,
+                                        { filter: scrollbarTreeWalkerFilter });
+      return !!walker.firstChild();
+    } catch (e) {
+      // We have no access to a DOM object. This is probably due to a CORS
+      // violation. Using try / catch is the only way to avoid this error.
+      return false;
+    }
   },
 
   /**
    * Is the node currently displayed?
    */
   get isDisplayed() {
     const type = this.displayType;
 
@@ -335,16 +341,20 @@ const NodeActor = protocol.ActorClassWit
   /**
    * Retrieve the script location of the custom element definition for this node, when
    * relevant. To be linked to a custom element definition
    */
   getCustomElementLocation: function() {
     // Get a reference to the custom element definition function.
     const name = this.rawNode.localName;
 
+    if (!this.rawNode.ownerGlobal) {
+      return undefined;
+    }
+
     const customElementsRegistry = this.rawNode.ownerGlobal.customElements;
     const customElement = customElementsRegistry && customElementsRegistry.get(name);
     if (!customElement) {
       return undefined;
     }
     // Create debugger object for the customElement function.
     const global = Cu.getGlobalForObject(customElement);
     const dbg = this.parent().targetActor.makeDebugger();