Bug 637214: Add scriptblockers around all callers of AddToIdTable/RemoveFromIdTable. r=bz a=blocker
authorJonas Sicking <jonas@sicking.cc>
Tue, 01 Mar 2011 21:33:56 -0800
changeset 63249 af9c212658df7e670cdab922cd8246a151709f63
parent 63248 82aabe4f0c3b869feca2f6b303a49cb48ced75ec
child 63250 65db1504a456cb1810fa607a3485777e178d8a45
push id1
push userroot
push dateTue, 10 Dec 2013 15:46:25 +0000
reviewersbz, blocker
bugs637214
milestone2.0b13pre
Bug 637214: Add scriptblockers around all callers of AddToIdTable/RemoveFromIdTable. r=bz a=blocker
content/base/src/nsDocument.cpp
content/base/src/nsGenericElement.cpp
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -341,16 +341,19 @@ FireChangeEnumerator(nsIdentifierMapEntr
       ? PL_DHASH_NEXT : PL_DHASH_REMOVE;
 }
 
 void
 nsIdentifierMapEntry::FireChangeCallbacks(Element* aOldElement,
                                           Element* aNewElement,
                                           PRBool aImageOnly)
 {
+  NS_ASSERTION(!nsContentUtils::IsSafeToRunScript(),
+               "Missing script blockers around code that modifies id-hash");
+
   if (!mChangeCallbacks)
     return;
 
   FireChangeArgs args = { aOldElement, aNewElement, aImageOnly, !!mImageElement };
   mChangeCallbacks->EnumerateEntries(FireChangeEnumerator, &args);
 }
 
 PRBool
@@ -4098,16 +4101,20 @@ nsDocument::RemoveIDTargetObserver(nsIAt
 
 NS_IMETHODIMP
 nsDocument::MozSetImageElement(const nsAString& aImageElementId,
                                nsIDOMElement* aImageElement)
 {
   if (aImageElementId.IsEmpty())
     return NS_OK;
 
+  // Hold a script blocker while calling SetImageElement since that can call
+  // out to id-observers
+  nsAutoScriptBlocker scriptBlocker;
+
   nsCOMPtr<nsIContent> content = do_QueryInterface(aImageElement);
   nsIdentifierMapEntry *entry = mIdentifierMap.PutEntry(aImageElementId);
   if (entry) {
     entry->SetImageElement(content ? content->AsElement() : nsnull);
     if (entry->IsEmpty()) {
       mIdentifierMap.RemoveEntry(aImageElementId);
     }
   }
--- a/content/base/src/nsGenericElement.cpp
+++ b/content/base/src/nsGenericElement.cpp
@@ -2231,16 +2231,18 @@ nsGenericElement::SetPrefix(const nsAStr
     NS_ENSURE_TRUE(prefix, NS_ERROR_OUT_OF_MEMORY);
   }
 
   if (!nsContentUtils::IsValidNodeName(mNodeInfo->NameAtom(), prefix,
                                        mNodeInfo->NamespaceID())) {
     return NS_ERROR_DOM_NAMESPACE_ERR;
   }
 
+  nsAutoScriptBlocker scriptBlocker;
+
   nsCOMPtr<nsINodeInfo> newNodeInfo;
   nsresult rv = nsContentUtils::PrefixChanged(mNodeInfo, prefix,
                                               getter_AddRefs(newNodeInfo));
   NS_ENSURE_SUCCESS(rv, rv);
 
   mNodeInfo.swap(newNodeInfo);
   NodeInfoChanged(newNodeInfo);
 
@@ -4652,24 +4654,30 @@ nsGenericElement::SetAttr(PRInt32 aNames
 
   nsresult rv = BeforeSetAttr(aNamespaceID, aName, &aValue, aNotify);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (aNotify) {
     nsNodeUtils::AttributeWillChange(this, aNamespaceID, aName, modType);
   }
 
+  // Hold a script blocker while calling ParseAttribute since that can call
+  // out to id-observers
+  nsContentUtils::AddRemovableScriptBlocker();
+
   nsAttrValue attrValue;
   if (!ParseAttribute(aNamespaceID, aName, aValue, attrValue)) {
     attrValue.SetTo(aValue);
   }
 
-  return SetAttrAndNotify(aNamespaceID, aName, aPrefix, oldValue,
-                          attrValue, modType, hasListeners, aNotify,
-                          &aValue);
+  rv = SetAttrAndNotify(aNamespaceID, aName, aPrefix, oldValue,
+                        attrValue, modType, hasListeners, aNotify,
+                        &aValue);
+  nsContentUtils::RemoveRemovableScriptBlocker();
+  return rv;
 }
 
 nsresult
 nsGenericElement::SetParsedAttr(PRInt32 aNamespaceID, nsIAtom* aName,
                                 nsIAtom* aPrefix, nsAttrValue& aParsedValue,
                                 PRBool aNotify)
 {
   // Keep this in sync with SetAttr above