Bug 1103375 - Fix some crashes triggered from about:memory. r=mrbkap, a=sledru
authorNicholas Nethercote <nnethercote@mozilla.com>
Mon, 18 May 2015 23:06:01 -0700
changeset 260549 b90caf52b6e2
parent 260548 013da2859c88
child 260550 17169e355c59
push id815
push userryanvm@gmail.com
push date2015-05-21 17:19 +0000
treeherdermozilla-release@3ef925962765 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmrbkap, sledru
bugs1103375
milestone38.0.5
Bug 1103375 - Fix some crashes triggered from about:memory. r=mrbkap, a=sledru We can't call JS code while iterating over the JS heap in the JS memory reporter. The Yandex Elements add-on is causing this in two cases. - The add-on implements some nsIURI objects. This one's easy to work around, because GetLocation() can just skip any JS-implemented nsIURI objects. - The add-on implements some nsIProtocolHandler objects in order to implement a custom "xb://" scheme. This one is harder to workaround because the call to the JS object's method occurs deep within NS_NewURI(), well beyond the JS reporter code. So we just skip "xb://" URLs.
js/xpconnect/src/XPCJSRuntime.cpp
js/xpconnect/src/xpcprivate.h
--- a/js/xpconnect/src/XPCJSRuntime.cpp
+++ b/js/xpconnect/src/XPCJSRuntime.cpp
@@ -272,16 +272,26 @@ TryParseLocationURICandidate(const nsACS
     static NS_NAMED_LITERAL_CSTRING(kBrowser, "chrome://browser/");
 
     if (aLocationHint == CompartmentPrivate::LocationHintAddon) {
         // Blacklist some known locations which are clearly not add-on related.
         if (StringBeginsWith(uristr, kGRE) ||
             StringBeginsWith(uristr, kToolkit) ||
             StringBeginsWith(uristr, kBrowser))
             return false;
+
+        // -- GROSS HACK ALERT --
+        // The Yandex Elements 8.10.2 extension implements its own "xb://" URL
+        // scheme. If we call NS_NewURI() on an "xb://..." URL, we'll end up
+        // calling into the extension's own JS-implemented nsIProtocolHandler
+        // object, which we can't allow while we're iterating over the JS heap.
+        // So just skip any such URL.
+        // -- GROSS HACK ALERT --
+        if (StringBeginsWith(uristr, NS_LITERAL_CSTRING("xb")))
+            return false;
     }
 
     nsCOMPtr<nsIURI> uri;
     if (NS_FAILED(NS_NewURI(getter_AddRefs(uri), uristr)))
         return false;
 
     nsAutoCString scheme;
     if (NS_FAILED(uri->GetScheme(scheme)))
--- a/js/xpconnect/src/xpcprivate.h
+++ b/js/xpconnect/src/xpcprivate.h
@@ -3693,18 +3693,27 @@ public:
     Scriptability scriptability;
 
     // Our XPCWrappedNativeScope. This is non-null if and only if this is an
     // XPConnect compartment.
     XPCWrappedNativeScope* scope;
 
     const nsACString& GetLocation() {
         if (location.IsEmpty() && locationURI) {
-            if (NS_FAILED(locationURI->GetSpec(location)))
+
+            nsCOMPtr<nsIXPConnectWrappedJS> jsLocationURI =
+                 do_QueryInterface(locationURI);
+            if (jsLocationURI) {
+                // We cannot call into JS-implemented nsIURI objects, because
+                // we are iterating over the JS heap at this point.
+                location =
+                    NS_LITERAL_CSTRING("<JS-implemented nsIURI location>");
+            } else if (NS_FAILED(locationURI->GetSpec(location))) {
                 location = NS_LITERAL_CSTRING("<unknown location>");
+            }
         }
         return location;
     }
     bool GetLocationURI(nsIURI** aURI) {
         return GetLocationURI(LocationHintRegular, aURI);
     }
     bool GetLocationURI(LocationHint aLocationHint, nsIURI** aURI) {
         if (locationURI) {