nsXHTMLParanoidFragmentSink
author Benjamin Smedberg <benjamin@smedbergs.us>
Sat, 26 Jul 2008 22:49:39 -0400
changeset 167 a4da40849f5436e629c5732f4368c6c48189637f
parent 82 ba505859ba00a5a9298ad653bb5e124cb263c5f4
permissions -rw-r--r--
State as of now

diff --git a/content/xml/document/src/nsXMLFragmentContentSink.cpp b/content/xml/document/src/nsXMLFragmentContentSink.cpp
--- a/content/xml/document/src/nsXMLFragmentContentSink.cpp
+++ b/content/xml/document/src/nsXMLFragmentContentSink.cpp
@@ -461,7 +461,6 @@ public:
   nsXHTMLParanoidFragmentSink();
 
   static nsresult Init();
-  static void Cleanup();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
@@ -489,13 +488,20 @@ public:
                                  PRUint32 aLength);
 protected:
   PRUint32 mSkipLevel; // used when we descend into <style> or <script>
-  // Use nsTHashTable as a hash set for our whitelists
-  static nsTHashtable<nsISupportsHashKey>* sAllowedTags;
-  static nsTHashtable<nsISupportsHashKey>* sAllowedAttributes;
+
+  struct StaticRoot : XPCOMGCFinalizedObject, MMgc::GCFinalizable
+  {
+    // Use nsTHashTable as a hash set for our whitelists
+    nsTHashtable<nsISupportsHashKey, GCAllocator> allowedTags;
+    nsTHashtable<nsISupportsHashKey, GCAllocator> allowedAttributes;
+  };
+
+  static StaticRoot *sRoot;
 };
 
-nsTHashtable<nsISupportsHashKey>* nsXHTMLParanoidFragmentSink::sAllowedTags;
-nsTHashtable<nsISupportsHashKey>* nsXHTMLParanoidFragmentSink::sAllowedAttributes;
+
+nsXHTMLParanoidFragmentSink::StaticRoot*
+nsXHTMLParanoidFragmentSink::sRoot;
 
 nsXHTMLParanoidFragmentSink::nsXHTMLParanoidFragmentSink():
   nsXMLFragmentContentSink(PR_FALSE), mSkipLevel(0)
@@ -505,53 +511,34 @@ nsresult
 nsresult
 nsXHTMLParanoidFragmentSink::Init()
 {
-  nsresult rv = NS_ERROR_FAILURE;
-  
-  if (sAllowedTags) {
-    return NS_OK;
-  }
-
-  sAllowedTags = new nsTHashtable<nsISupportsHashKey>();
-  if (sAllowedTags) {
-    rv = sAllowedTags->Init(80);
-    for (PRUint32 i = 0; kDefaultAllowedTags[i] && NS_SUCCEEDED(rv); i++) {
-      if (!sAllowedTags->PutEntry(*kDefaultAllowedTags[i])) {
-        rv = NS_ERROR_OUT_OF_MEMORY;
-      }
+  if (sRoot) {
+    return NS_OK;
+  }
+
+  StaticRoot *root = new StaticRoot();
+
+  if (!root->allowedTags.Init(80))
+    return NS_ERROR_OUT_OF_MEMORY;
+
+  for (PRUint32 i = 0; kDefaultAllowedTags[i]; i++) {
+    if (!root->allowedTags.PutEntry(*kDefaultAllowedTags[i])) {
+      return NS_ERROR_OUT_OF_MEMORY;
     }
   }
 
-  sAllowedAttributes = new nsTHashtable<nsISupportsHashKey>();
-  if (sAllowedAttributes && NS_SUCCEEDED(rv)) {
-    rv = sAllowedAttributes->Init(80);
-    for (PRUint32 i = 0;
-         kDefaultAllowedAttributes[i] && NS_SUCCEEDED(rv); i++) {
-      if (!sAllowedAttributes->PutEntry(*kDefaultAllowedAttributes[i])) {
-        rv = NS_ERROR_OUT_OF_MEMORY;
-      }
+  if (!root->allowedAttributes.Init(80))
+    return NS_ERROR_OUT_OF_MEMORY;
+
+  for (PRUint32 i = 0;
+       kDefaultAllowedAttributes[i]; i++) {
+    if (!root->allowedAttributes.PutEntry(*kDefaultAllowedAttributes[i])) {
+      return NS_ERROR_OUT_OF_MEMORY;
     }
   }
 
-  if (NS_FAILED(rv)) {
-    NS_WARNING("Failed to populate whitelist hash sets");
-    Cleanup();
-  }
-
-  return rv;
-}
-
-void
-nsXHTMLParanoidFragmentSink::Cleanup()
-{
-  if (sAllowedTags) {
-    delete sAllowedTags;
-    sAllowedTags = nsnull;
-  }
-  
-  if (sAllowedAttributes) {
-    delete sAllowedAttributes;
-    sAllowedAttributes = nsnull;
-  }
+  NS_RootUntilShutdown(sRoot = root);
+
+  return NS_OK;
 }
 
 nsresult
@@ -571,7 +558,6 @@ void
 void
 NS_XHTMLParanoidFragmentSinkShutdown()
 {
-  nsXHTMLParanoidFragmentSink::Cleanup();
 }
 
 NS_IMPL_ISUPPORTS_INHERITED0(nsXHTMLParanoidFragmentSink,
@@ -662,7 +648,7 @@ nsXHTMLParanoidFragmentSink::HandleStart
     return NS_OK;
   }  
   
-  if (!sAllowedTags || !sAllowedTags->GetEntry(name))
+  if (!sRoot->allowedTags.GetEntry(name))
     return NS_OK;
   
   // It's an allowed element, so let's scrub the attributes
@@ -678,7 +664,7 @@ nsXHTMLParanoidFragmentSink::HandleStart
     // Add if it's xmlns, xml: or on the HTML whitelist
     if (nameSpaceID == kNameSpaceID_XMLNS ||
         nameSpaceID == kNameSpaceID_XML ||
-        (sAllowedAttributes && sAllowedAttributes->GetEntry(name))) {
+        (sRoot->allowedAttributes.GetEntry(name))) {
       allowedAttrs.AppendElement(aAtts[i]);
       allowedAttrs.AppendElement(aAtts[i + 1]);
     }
@@ -717,7 +703,7 @@ nsXHTMLParanoidFragmentSink::HandleEndEl
     return NS_OK;
   }
 
-  if (!sAllowedTags || !sAllowedTags->GetEntry(name)) {
+  if (!sRoot->allowedTags.GetEntry(name)) {
     return NS_OK;
   }