Bug 851892 part 3. Give CSS rules a PreCreate hook so we can safely wrappercache them. r=peterv
authorBoris Zbarsky <bzbarsky@mit.edu>
Fri, 13 Jan 2017 10:41:02 -0500
changeset 464472 4f24650b72a12eddcf5b74d17c5308ca8fef7021
parent 464471 0d8f9b1c8d6138c3ad2f3f86d0f5556e2cd69929
child 464473 b2f8a7db085811d851ebe121ae2b13a2d3431368
push id42350
push usermozilla@noorenberghe.ca
push dateFri, 20 Jan 2017 23:18:04 +0000
reviewerspeterv
bugs851892
milestone53.0a1
Bug 851892 part 3. Give CSS rules a PreCreate hook so we can safely wrappercache them. r=peterv
dom/base/nsDOMClassInfo.cpp
dom/base/nsDOMClassInfo.h
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -185,24 +185,28 @@ static nsDOMClassInfoData sClassInfoData
                            nsIXPCScriptable::WANT_HASINSTANCE |
                            nsIXPCScriptable::WANT_CALL |
                            nsIXPCScriptable::WANT_CONSTRUCT |
                            nsIXPCScriptable::DONT_ENUM_QUERY_INTERFACE)
 
   // Misc Core related classes
 
   // CSS classes
-  NS_DEFINE_CLASSINFO_DATA(CSSStyleRule, nsDOMGenericSH,
-                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
-  NS_DEFINE_CLASSINFO_DATA(CSSImportRule, nsDOMGenericSH,
-                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
-  NS_DEFINE_CLASSINFO_DATA(CSSMediaRule, nsDOMGenericSH,
-                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
-  NS_DEFINE_CLASSINFO_DATA(CSSNameSpaceRule, nsDOMGenericSH,
-                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
+  NS_DEFINE_CLASSINFO_DATA(CSSStyleRule, nsCSSRuleSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS |
+                           nsIXPCScriptable::WANT_PRECREATE)
+  NS_DEFINE_CLASSINFO_DATA(CSSImportRule, nsCSSRuleSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS |
+                           nsIXPCScriptable::WANT_PRECREATE)
+  NS_DEFINE_CLASSINFO_DATA(CSSMediaRule, nsCSSRuleSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS |
+                           nsIXPCScriptable::WANT_PRECREATE)
+  NS_DEFINE_CLASSINFO_DATA(CSSNameSpaceRule, nsCSSRuleSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS |
+                           nsIXPCScriptable::WANT_PRECREATE)
 
   // XUL classes
 #ifdef MOZ_XUL
   NS_DEFINE_CHROME_XBL_CLASSINFO_DATA(XULCommandDispatcher, nsDOMGenericSH,
                                       DOM_DEFAULT_SCRIPTABLE_FLAGS)
 #endif
   NS_DEFINE_CHROME_XBL_CLASSINFO_DATA(XULControllers, nsNonDOMObjectSH,
                                       DEFAULT_SCRIPTABLE_FLAGS)
@@ -216,24 +220,27 @@ static nsDOMClassInfoData sClassInfoData
 #ifdef MOZ_XUL
   NS_DEFINE_CHROME_XBL_CLASSINFO_DATA(XULTemplateBuilder, nsDOMGenericSH,
                                       DEFAULT_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CHROME_XBL_CLASSINFO_DATA(XULTreeBuilder, nsDOMGenericSH,
                                       DEFAULT_SCRIPTABLE_FLAGS)
 #endif
 
-  NS_DEFINE_CLASSINFO_DATA(CSSMozDocumentRule, nsDOMGenericSH,
-                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
+  NS_DEFINE_CLASSINFO_DATA(CSSMozDocumentRule, nsCSSRuleSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS |
+                           nsIXPCScriptable::WANT_PRECREATE)
 
-  NS_DEFINE_CLASSINFO_DATA(CSSSupportsRule, nsDOMGenericSH,
-                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
+  NS_DEFINE_CLASSINFO_DATA(CSSSupportsRule, nsCSSRuleSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS |
+                           nsIXPCScriptable::WANT_PRECREATE)
 
-  NS_DEFINE_CLASSINFO_DATA(CSSFontFaceRule, nsDOMGenericSH,
-                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
+  NS_DEFINE_CLASSINFO_DATA(CSSFontFaceRule, nsCSSRuleSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS |
+                           nsIXPCScriptable::WANT_PRECREATE)
 
   NS_DEFINE_CHROME_ONLY_CLASSINFO_DATA(ContentFrameMessageManager,
                                        nsMessageManagerSH<nsEventTargetSH>,
                                        DOM_DEFAULT_SCRIPTABLE_FLAGS |
                                        nsIXPCScriptable::WANT_ENUMERATE |
                                        nsIXPCScriptable::IS_GLOBAL_OBJECT)
   NS_DEFINE_CHROME_ONLY_CLASSINFO_DATA(ContentProcessMessageManager,
                                        nsMessageManagerSH<nsDOMGenericSH>,
@@ -241,29 +248,34 @@ static nsDOMClassInfoData sClassInfoData
                                        nsIXPCScriptable::WANT_ENUMERATE |
                                        nsIXPCScriptable::IS_GLOBAL_OBJECT)
   NS_DEFINE_CHROME_ONLY_CLASSINFO_DATA(ChromeMessageBroadcaster, nsDOMGenericSH,
                                        DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CHROME_ONLY_CLASSINFO_DATA(ChromeMessageSender, nsDOMGenericSH,
                                        DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
 
-  NS_DEFINE_CLASSINFO_DATA(CSSKeyframeRule, nsDOMGenericSH,
-                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
-  NS_DEFINE_CLASSINFO_DATA(CSSKeyframesRule, nsDOMGenericSH,
-                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
+  NS_DEFINE_CLASSINFO_DATA(CSSKeyframeRule, nsCSSRuleSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS |
+                           nsIXPCScriptable::WANT_PRECREATE)
+  NS_DEFINE_CLASSINFO_DATA(CSSKeyframesRule, nsCSSRuleSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS |
+                           nsIXPCScriptable::WANT_PRECREATE)
 
-  NS_DEFINE_CLASSINFO_DATA(CSSCounterStyleRule, nsDOMGenericSH,
-                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
+  NS_DEFINE_CLASSINFO_DATA(CSSCounterStyleRule, nsCSSRuleSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS |
+                           nsIXPCScriptable::WANT_PRECREATE)
 
-  NS_DEFINE_CLASSINFO_DATA(CSSPageRule, nsDOMGenericSH,
-                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
+  NS_DEFINE_CLASSINFO_DATA(CSSPageRule, nsCSSRuleSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS |
+                           nsIXPCScriptable::WANT_PRECREATE)
 
-  NS_DEFINE_CLASSINFO_DATA(CSSFontFeatureValuesRule, nsDOMGenericSH,
-                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
+  NS_DEFINE_CLASSINFO_DATA(CSSFontFeatureValuesRule, nsCSSRuleSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS |
+                           nsIXPCScriptable::WANT_PRECREATE)
 
   NS_DEFINE_CHROME_XBL_CLASSINFO_DATA(XULControlElement, nsDOMGenericSH,
                                       DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CHROME_XBL_CLASSINFO_DATA(XULLabeledControlElement, nsDOMGenericSH,
                                       DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CHROME_XBL_CLASSINFO_DATA(XULButtonElement, nsDOMGenericSH,
                                       DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CHROME_XBL_CLASSINFO_DATA(XULCheckboxElement, nsDOMGenericSH,
@@ -1979,16 +1991,49 @@ nsEventTargetSH::PreCreate(nsISupports *
 
 void
 nsEventTargetSH::PreserveWrapper(nsISupports *aNative)
 {
   DOMEventTargetHelper* target = DOMEventTargetHelper::FromSupports(aNative);
   target->PreserveWrapper(aNative);
 }
 
+// CSS rule helper
+NS_IMETHODIMP
+nsCSSRuleSH::PreCreate(nsISupports *nativeObj, JSContext *cx,
+                       JSObject *aGlobalObj, JSObject **parentObj)
+{
+  JS::Rooted<JSObject*> globalObj(cx, aGlobalObj);
+  nsCOMPtr<nsIDOMCSSRule> rule = do_QueryInterface(nativeObj);
+  if (!rule) {
+    return NS_ERROR_UNEXPECTED;
+  }
+  css::Rule* cssRule = rule->GetCSSRule();
+  if (!cssRule) {
+    // A DOMCSSStyleRule whose actual underlying rule has gone away.  There
+    // isn't much a caller can do with this thing anyway, and only chrome code
+    // can get its hands on it to start with, so just wrap in the current
+    // global.
+    *parentObj = globalObj;
+    return NS_OK;
+  }
+  nsIDocument* doc = cssRule->GetDocument();
+  if (!doc) {
+    *parentObj = globalObj;
+    return NS_OK;
+  }
+
+  nsIGlobalObject* global = doc->GetScopeObject();
+  if (!global) {
+    return NS_ERROR_UNEXPECTED;
+  }
+  *parentObj = global->GetGlobalJSObject();
+  return *parentObj ? NS_OK : NS_ERROR_FAILURE;
+}
+
 // nsIDOMEventListener::HandleEvent() 'this' converter helper
 
 NS_INTERFACE_MAP_BEGIN(nsEventListenerThisTranslator)
   NS_INTERFACE_MAP_ENTRY(nsIXPCFunctionThisTranslator)
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
 
--- a/dom/base/nsDOMClassInfo.h
+++ b/dom/base/nsDOMClassInfo.h
@@ -177,16 +177,38 @@ protected:
   }
 public:
   NS_IMETHOD PreCreate(nsISupports *nativeObj, JSContext *cx,
                        JSObject *globalObj, JSObject **parentObj) override;
 
   virtual void PreserveWrapper(nsISupports *aNative) override;
 };
 
+// Makes sure that we always create our wrapper in the right global, so we won't
+// cache one from the wrong global.
+class nsCSSRuleSH : public nsDOMGenericSH
+{
+protected:
+  explicit nsCSSRuleSH(nsDOMClassInfoData* aData) : nsDOMGenericSH(aData)
+  {
+  }
+
+  virtual ~nsCSSRuleSH()
+  {
+  }
+public:
+  NS_IMETHOD PreCreate(nsISupports *nativeObj, JSContext *cx,
+                       JSObject *globalObj, JSObject **parentObj) override;
+
+  static nsIClassInfo *doCreate(nsDOMClassInfoData* aData)
+  {
+    return new nsCSSRuleSH(aData);
+  }
+};
+
 // A place to hang some static methods that we should really consider
 // moving to be nsGlobalWindow member methods.  See bug 1062418.
 class nsWindowSH
 {
 protected:
   static nsresult GlobalResolve(nsGlobalWindow *aWin, JSContext *cx,
                                 JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
                                 JS::MutableHandle<JS::PropertyDescriptor> desc);