Bug 572642 - Part 1: Allow comments, and disallow styles when pasting CF_HTML content; r=roc
authorEhsan Akhgari <ehsan@mozilla.com>
Wed, 23 Jun 2010 14:40:08 -0400
changeset 44199 4e74c58e602034bc6262eb2ce638ea8246a1c5db
parent 44198 b6e39cfd9dcf215b55214ff0472241565c91a876
child 44200 b149725f51da976770d7a344b1e09c5f3d08125d
push id14024
push usereakhgari@mozilla.com
push dateWed, 23 Jun 2010 18:58:25 +0000
treeherdermozilla-central@b149725f51da [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs572642
milestone1.9.3a6pre
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 572642 - Part 1: Allow comments, and disallow styles when pasting CF_HTML content; r=roc
content/html/document/src/nsHTMLFragmentContentSink.cpp
editor/libeditor/html/nsHTMLDataTransfer.cpp
parser/htmlparser/public/nsIFragmentContentSink.h
--- a/content/html/document/src/nsHTMLFragmentContentSink.cpp
+++ b/content/html/document/src/nsHTMLFragmentContentSink.cpp
@@ -796,41 +796,43 @@ public:
   NS_IMETHOD AddComment(const nsIParserNode& aNode);
   NS_IMETHOD AddProcessingInstruction(const nsIParserNode& aNode);
 
   nsresult AddAttributes(const nsIParserNode& aNode,
                          nsIContent* aContent);
 
   // nsIParanoidFragmentContentSink
   virtual void AllowStyles();
+  virtual void AllowComments();
 
 protected:
   nsresult NameFromType(const nsHTMLTag aTag,
                         nsIAtom **aResult);
 
   nsresult NameFromNode(const nsIParserNode& aNode,
                         nsIAtom **aResult);
 
   void SanitizeStyleRule(nsICSSStyleRule *aRule, nsAutoString &aRuleText);
   
   PRPackedBool mSkip; // used when we descend into <style> or <script>
   PRPackedBool mProcessStyle; // used when style is explicitly white-listed
   PRPackedBool mInStyle; // whether we're inside a style element
+  PRPackedBool mProcessComments; // used when comments are allowed
 
   // Use nsTHashTable as a hash set for our whitelists
   static nsTHashtable<nsISupportsHashKey>* sAllowedTags;
   static nsTHashtable<nsISupportsHashKey>* sAllowedAttributes;
 };
 
 nsTHashtable<nsISupportsHashKey>* nsHTMLParanoidFragmentSink::sAllowedTags;
 nsTHashtable<nsISupportsHashKey>* nsHTMLParanoidFragmentSink::sAllowedAttributes;
 
 nsHTMLParanoidFragmentSink::nsHTMLParanoidFragmentSink(PRBool aAllContent):
   nsHTMLFragmentContentSink(aAllContent), mSkip(PR_FALSE),
-  mProcessStyle(PR_FALSE), mInStyle(PR_FALSE)
+  mProcessStyle(PR_FALSE), mInStyle(PR_FALSE), mProcessComments(PR_FALSE)
 {
 }
 
 nsresult
 nsHTMLParanoidFragmentSink::Init()
 {
   nsresult rv = NS_ERROR_FAILURE;
   
@@ -954,16 +956,22 @@ nsHTMLParanoidFragmentSink::NameFromNode
 }
 
 void
 nsHTMLParanoidFragmentSink::AllowStyles()
 {
   mProcessStyle = PR_TRUE;
 }
 
+void
+nsHTMLParanoidFragmentSink::AllowComments()
+{
+  mProcessComments = PR_TRUE;
+}
+
 // nsHTMLFragmentContentSink
 
 nsresult
 nsHTMLParanoidFragmentSink::AddAttributes(const nsIParserNode& aNode,
                                           nsIContent* aContent)
 {
   PRInt32 ac = aNode.GetAttributeCount();
 
@@ -1246,16 +1254,18 @@ nsHTMLParanoidFragmentSink::AddLeaf(cons
   }
 
   return nsHTMLFragmentContentSink::AddLeaf(aNode);
 }
 
 NS_IMETHODIMP
 nsHTMLParanoidFragmentSink::AddComment(const nsIParserNode& aNode)
 {
+  if (mProcessComments)
+    return nsHTMLFragmentContentSink::AddComment(aNode);
   // no comments
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsHTMLParanoidFragmentSink::AddProcessingInstruction(const nsIParserNode& aNode)
 {
   // no PIs
--- a/editor/libeditor/html/nsHTMLDataTransfer.cpp
+++ b/editor/libeditor/html/nsHTMLDataTransfer.cpp
@@ -2700,20 +2700,25 @@ nsresult nsHTMLEditor::ParseFragment(con
     sink = do_CreateInstance(NS_HTMLPARANOIDFRAGMENTSINK2_CONTRACTID);
   else
     sink = do_CreateInstance(NS_HTMLPARANOIDFRAGMENTSINK_CONTRACTID);
 
   NS_ENSURE_TRUE(sink, NS_ERROR_FAILURE);
   nsCOMPtr<nsIFragmentContentSink> fragSink(do_QueryInterface(sink));
   NS_ENSURE_TRUE(fragSink, NS_ERROR_FAILURE);
 
-  // Allow style elements and attributes
   nsCOMPtr<nsIParanoidFragmentContentSink> paranoidSink(do_QueryInterface(sink));
   NS_ASSERTION(paranoidSink, "Our content sink is paranoid");
-  paranoidSink->AllowStyles();
+  if (bContext) {
+    // Allow comemnts for the context to catch our placeholder cookie
+    paranoidSink->AllowComments();
+  } else {
+    // Allow style elements and attributes for the actual content
+    paranoidSink->AllowStyles();
+  }
 
   fragSink->SetTargetDocument(aTargetDocument);
 
   // parse the fragment
   parser->SetContentSink(sink);
   if (bContext)
     parser->Parse(aFragStr, (void*)0, NS_LITERAL_CSTRING("text/html"), PR_TRUE, eDTDMode_fragment);
   else
--- a/parser/htmlparser/public/nsIFragmentContentSink.h
+++ b/parser/htmlparser/public/nsIFragmentContentSink.h
@@ -42,17 +42,17 @@
 class nsIDOMDocumentFragment;
 class nsIDocument;
 
 #define NS_I_FRAGMENT_CONTENT_SINK_IID \
   { 0x1ecdb30d, 0x1f10, 0x45d2, \
     { 0xa4, 0xf4, 0xec, 0xbc, 0x03, 0x52, 0x9a, 0x7e } }
 
 #define NS_I_PARANOID_FRAGMENT_CONTENT_SINK_IID \
-  { 0x59ec77f5, 0x9e9b, 0x4040, \
+  { 0x69ec77f5, 0x9e9b, 0x4040, \
     { 0xbd, 0xe7, 0x4e, 0xd0, 0x13, 0xa6, 0x21, 0x74 } }
 
 /**
  * The fragment sink allows a client to parse a fragment of sink, possibly
  * surrounded in context. Also see nsIParser::ParseFragment().
  * Note: once you've parsed a fragment, the fragment sink must be re-set on
  * the parser in order to parse another fragment.
  */
@@ -112,16 +112,21 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsIFragmen
 class nsIParanoidFragmentContentSink : public nsISupports {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_I_PARANOID_FRAGMENT_CONTENT_SINK_IID)
 
   /**
    * Allow the content sink to accept style elements and attributes.
    */
   virtual void AllowStyles() = 0;
+
+  /**
+   * Allow the content sink to accept comments.
+   */
+  virtual void AllowComments() = 0;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsIParanoidFragmentContentSink,
                               NS_I_PARANOID_FRAGMENT_CONTENT_SINK_IID)
 
 /**
  * Base version takes string nested in context, content surrounded by
  * WillBuildContent()/DidBuildContent() calls. The 2nd version just loads