Bug 874158 - Crash in GetNativeForGlobal. r=bholley
authorGabor Krizsanits <gkrizsanits@mozilla.com>
Tue, 16 Jul 2013 15:04:28 +0200
changeset 138667 a4eeeaa1eefdd910c2d2b482bb991fb7a4cffb89
parent 138666 8a658a424d35800d5df146fab0d89dcf8c149a41
child 138668 e9c5b7db433bc83a5ce4d7117759fcccbb1238d6
push id24964
push userryanvm@gmail.com
push dateTue, 16 Jul 2013 20:04:09 +0000
treeherderautoland@fd10ead17ace [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbholley
bugs874158
milestone25.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 874158 - Crash in GetNativeForGlobal. r=bholley
content/base/src/nsDOMFileReader.cpp
content/base/src/nsDocument.cpp
content/base/src/nsXMLHttpRequest.cpp
js/xpconnect/src/XPCJSRuntime.cpp
js/xpconnect/src/xpcpublic.h
--- a/content/base/src/nsDOMFileReader.cpp
+++ b/content/base/src/nsDOMFileReader.cpp
@@ -127,19 +127,21 @@ nsDOMFileReader::Init()
   nsCOMPtr<nsIPrincipal> principal;
   if (secMan) {
     secMan->GetSystemPrincipal(getter_AddRefs(principal));
   }
   NS_ENSURE_STATE(principal);
   mPrincipal.swap(principal);
 
   // Instead of grabbing some random global from the context stack,
-  // let's use the default one (junk drawer) for now.
+  // let's use the default one (junk scope) for now.
   // We should move away from this Init...
-  BindToOwner(xpc::GetNativeForGlobal(xpc::GetJunkScope()));
+  nsCOMPtr<nsIGlobalObject> global = xpc::GetJunkScopeGlobal();
+  NS_ENSURE_TRUE(global, NS_ERROR_FAILURE);
+  BindToOwner(global);
   return NS_OK;
 }
 
 /* static */ already_AddRefed<nsDOMFileReader>
 nsDOMFileReader::Constructor(const GlobalObject& aGlobal, ErrorResult& aRv)
 {
   nsRefPtr<nsDOMFileReader> fileReader = new nsDOMFileReader();
 
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -1949,17 +1949,19 @@ nsDocument::Init()
   mStyledLinks.Init();
   mRadioGroups.Init();
   mCustomPrototypes.Init();
 
   // If after creation the owner js global is not set for a document
   // we use the default compartment for this document, instead of creating
   // wrapper in some random compartment when the document is exposed to js
   // via some events.
-  mScopeObject = do_GetWeakReference(xpc::GetNativeForGlobal(xpc::GetJunkScope()));
+  nsCOMPtr<nsIGlobalObject> global = xpc::GetJunkScopeGlobal();
+  NS_ENSURE_TRUE(global, NS_ERROR_FAILURE);
+  mScopeObject = do_GetWeakReference(global);
   MOZ_ASSERT(mScopeObject);
 
   // Force initialization.
   nsINode::nsSlots* slots = Slots();
 
   // Prepend self as mutation-observer whether we need it or not (some
   // subclasses currently do, other don't). This is because the code in
   // nsNodeUtils always notifies the first observer first, expecting the
--- a/content/base/src/nsXMLHttpRequest.cpp
+++ b/content/base/src/nsXMLHttpRequest.cpp
@@ -351,19 +351,21 @@ nsXMLHttpRequest::Init()
   nsIScriptSecurityManager* secMan = nsContentUtils::GetSecurityManager();
   nsCOMPtr<nsIPrincipal> subjectPrincipal;
   if (secMan) {
     secMan->GetSystemPrincipal(getter_AddRefs(subjectPrincipal));
   }
   NS_ENSURE_STATE(subjectPrincipal);
 
   // Instead of grabbing some random global from the context stack,
-  // let's use the default one (junk drawer) for now.
+  // let's use the default one (junk scope) for now.
   // We should move away from this Init...
-  Construct(subjectPrincipal, xpc::GetNativeForGlobal(xpc::GetJunkScope()));
+  nsCOMPtr<nsIGlobalObject> global = xpc::GetJunkScopeGlobal();
+  NS_ENSURE_TRUE(global, NS_ERROR_FAILURE);
+  Construct(subjectPrincipal, global);
   return NS_OK;
 }
 
 /**
  * This Init method should only be called by C++ consumers.
  */
 NS_IMETHODIMP
 nsXMLHttpRequest::Init(nsIPrincipal* aPrincipal,
--- a/js/xpconnect/src/XPCJSRuntime.cpp
+++ b/js/xpconnect/src/XPCJSRuntime.cpp
@@ -391,16 +391,27 @@ EnableUniversalXPConnect(JSContext *cx)
 JSObject *
 GetJunkScope()
 {
     XPCJSRuntime *self = nsXPConnect::GetRuntimeInstance();
     NS_ENSURE_TRUE(self, nullptr);
     return self->GetJunkScope();
 }
 
+nsIGlobalObject *
+GetJunkScopeGlobal()
+{
+    JSObject *junkScope = GetJunkScope();
+    // GetJunkScope would ideally never fail, currently it is not yet the case
+    // unfortunately...(see Bug 874158)
+    if (!junkScope)
+        return nullptr;
+    return GetNativeForGlobal(junkScope);
+}
+
 }
 
 static void
 CompartmentDestroyedCallback(JSFreeOp *fop, JSCompartment *compartment)
 {
     XPCJSRuntime* self = nsXPConnect::GetRuntimeInstance();
     if (!self)
         return;
--- a/js/xpconnect/src/xpcpublic.h
+++ b/js/xpconnect/src/xpcpublic.h
@@ -408,16 +408,23 @@ GetNativeForGlobal(JSObject *global);
  * we did previously) a default compartment is used. This function returns that
  * compartment's global. It is a singleton on the runtime.
  * If you find yourself wanting to use this compartment, you're probably doing
  * something wrong. Callers MUST consult with the XPConnect module owner before
  * using this compartment. If you don't, bholley will hunt you down.
  */
 JSObject *
 GetJunkScope();
+
+/**
+ * Returns the native global of the junk scope. See comment of GetJunkScope
+ * about the conditions of using it.
+ */
+nsIGlobalObject *
+GetJunkScopeGlobal();
 } // namespace xpc
 
 namespace mozilla {
 namespace dom {
 
 extern int HandlerFamily;
 inline void* ProxyFamily() { return &HandlerFamily; }