Bug 737013 - Expose sanitizer fragments on parseFragment(), migrate callers to the new interface. r=smaug.
authorHenri Sivonen <hsivonen@iki.fi>
Tue, 20 Mar 2012 17:28:42 +0200
changeset 89894 eb7570cdfb9e80acb308ed6214cac9c9cb784804
parent 89893 537c3637b99273acd602ee714bac029faa408e88
child 89902 be36bef9680fb8ef20ac9fb84244efa946cd3e7e
push id7367
push userhsivonen@iki.fi
push dateWed, 21 Mar 2012 10:16:39 +0000
treeherdermozilla-inbound@eb7570cdfb9e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs737013
milestone14.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 737013 - Expose sanitizer fragments on parseFragment(), migrate callers to the new interface. r=smaug.
parser/html/nsIParserUtils.idl
parser/html/nsIScriptableUnescapeHTML.idl
parser/html/nsParserUtils.cpp
parser/html/nsParserUtils.h
testing/extensions/community/chrome/content/common.js
toolkit/components/feeds/FeedProcessor.js
toolkit/components/feeds/test/test_bug675492.xul
--- a/parser/html/nsIParserUtils.idl
+++ b/parser/html/nsIParserUtils.idl
@@ -1,20 +1,24 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
 
+interface nsIDOMElement;
+interface nsIDOMDocumentFragment;
+interface nsIURI;
+
 /**
  * Non-Web HTML parser functionality to Firefox extensions and XULRunner apps. 
  * Don't use this from within Gecko--use nsContentUtils, nsTreeSanitizer, etc.
  * directly instead.
  */
-[scriptable, uuid(290f49bb-0619-4bda-8006-ab31bec7231a)]
+[scriptable, uuid(a1101145-0025-411e-8873-fdf57bf28128)]
 interface nsIParserUtils : nsISupports
 {
 
   /**
    * Flag for sanitizer: Allow comment nodes.
    */
   const unsigned long SanitizerAllowComments = (1 << 0);
 
@@ -95,16 +99,32 @@ interface nsIParserUtils : nsISupports
    * @param src the HTML source to parse (C++ callers are allowed but not
    *            required to use the same string for the return value.)
    * @param flags conversion option flags defined in nsIDocumentEncoder
    * @param wrapCol number of characters per line; 0 for no auto-wrapping
    */
   AString convertToPlainText(in AString src,
                              in unsigned long flags,
                              in unsigned long wrapCol);
+
+  /**
+   * Parses markup into a sanitized document fragment.
+   *
+   * @param fragment the input markup
+   * @param flags sanitization option flags defined above
+   * @param isXML true if |fragment| is XML and false if HTML
+   * @param baseURI the base URL for this fragment
+   * @param element the context node for the fragment parsing algorithm
+   */
+  nsIDOMDocumentFragment parseFragment(in AString fragment,
+                                       in unsigned long flags,
+                                       in boolean isXML,
+                                       in nsIURI baseURI,
+                                       in nsIDOMElement element);
+
 };
 
 %{ C++
 #define NS_PARSERUTILS_CONTRACTID \
     "@mozilla.org/parserutils;1"
 #define NS_PARSERUTILS_CID  \
 { 0xaf7b24cb, 0x893f, 0x41bb, { 0x96, 0x1f, 0x5a, 0x69, 0x38, 0x8e, 0x27, 0xc3 } }
 %}
--- a/parser/html/nsIScriptableUnescapeHTML.idl
+++ b/parser/html/nsIScriptableUnescapeHTML.idl
@@ -36,37 +36,41 @@
 
 #include "nsISupports.idl"
 
 interface nsIDOMElement;
 interface nsIDOMDocumentFragment;
 interface nsIURI;
 
 /**
- * A utility class for HTML parsing in the feed processor.
+ * This interface is OBSOLETE and exists solely for legacy extensions.
  */
 [scriptable, uuid(3ab244a9-f09d-44da-9e3f-ee4d67367f2d)]
 interface nsIScriptableUnescapeHTML : nsISupports 
 {
   /** 
    * Converts HTML to plain text. This is equivalent to calling
    * nsIParserUtils::convertToPlainText(src, 
    *   nsIDocumentEncoder::OutputSelectionOnly |
    *   nsIDocumentEncoder::OutputAbsoluteLinks, 0).
    *
-   * You should most likely call nsIParserUtils::convertToPlainText()
-   * instead of calling this method.
+   * You should call nsIParserUtils::convertToPlainText() instead of calling 
+   * this method.
    *
    * @param src The HTML string to convert to plain text.
    */ 
   AString unescape(in AString src);
         
   /**
-   * Parses markup into a sanitized document fragment.
+   * Parses markup into a sanitized document fragment. This is equivalent to
+   * calling nsIParserUtils::parseFragment(fragment, 0, isXML, baseURI,
+   * element).
    *
+   * You should call nsIParserUtils::parseFragment() instead of calling this 
+   * method.
    * @param fragment the input markup
    * @param isXML true if |fragment| is XML and false if HTML
    * @param baseURI the base URL for this fragment
    * @param element the context node for the fragment parsing algorithm
    */
   nsIDOMDocumentFragment parseFragment(in AString fragment,
                                        in boolean isXML,
                                        in nsIURI baseURI,
--- a/parser/html/nsParserUtils.cpp
+++ b/parser/html/nsParserUtils.cpp
@@ -74,19 +74,19 @@ NS_IMPL_ISUPPORTS2(nsParserUtils,
                    nsIParserUtils)
 
 static NS_DEFINE_CID(kCParserCID, NS_PARSER_CID);
 
 
 
 NS_IMETHODIMP
 nsParserUtils::ConvertToPlainText(const nsAString& aFromStr,
-                                           PRUint32 aFlags,
-                                           PRUint32 aWrapCol,
-                                           nsAString& aToStr)
+                                  PRUint32 aFlags,
+                                  PRUint32 aWrapCol,
+                                  nsAString& aToStr)
 {
   return nsContentUtils::ConvertToPlainText(aFromStr,
     aToStr,
     aFlags,
     aWrapCol);
 }
 
 NS_IMETHODIMP
@@ -137,25 +137,38 @@ nsParserUtils::Sanitize(const nsAString&
                       nsIDocumentEncoder::OutputNoScriptContent |
                       nsIDocumentEncoder::OutputEncodeBasicEntities |
                       nsIDocumentEncoder::OutputLFLineBreak |
                       nsIDocumentEncoder::OutputRaw);
 
   return encoder->EncodeToString(aToStr);
 }
 
-// The feed version of nsContentUtils::CreateContextualFragment It
-// creates a fragment, but doesn't go to all the effort to preserve
-// context like innerHTML does, because feed DOMs shouldn't have that.
 NS_IMETHODIMP
 nsParserUtils::ParseFragment(const nsAString& aFragment,
-                                      bool aIsXML,
-                                      nsIURI* aBaseURI,
-                                      nsIDOMElement* aContextElement,
-                                      nsIDOMDocumentFragment** aReturn)
+                             bool aIsXML,
+                             nsIURI* aBaseURI,
+                             nsIDOMElement* aContextElement,
+                             nsIDOMDocumentFragment** aReturn)
+{
+  return nsParserUtils::ParseFragment(aFragment,
+                                      0,
+                                      aIsXML,
+                                      aBaseURI,
+                                      aContextElement,
+                                      aReturn);
+}
+
+NS_IMETHODIMP
+nsParserUtils::ParseFragment(const nsAString& aFragment,
+                             PRUint32 aFlags,
+                             bool aIsXML,
+                             nsIURI* aBaseURI,
+                             nsIDOMElement* aContextElement,
+                             nsIDOMDocumentFragment** aReturn)
 {
   NS_ENSURE_ARG(aContextElement);
   *aReturn = nsnull;
 
   nsresult rv;
   nsCOMPtr<nsIParser> parser = do_CreateInstance(kCParserCID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
@@ -234,17 +247,17 @@ nsParserUtils::ParseFragment(const nsASt
                           spec16,
                           false);
           }
           node = node->GetNextSibling();
         }
       }
     }
     if (fragment) {
-      nsTreeSanitizer sanitizer;
+      nsTreeSanitizer sanitizer(aFlags);
       sanitizer.Sanitize(fragment);
     }
   }
 
   if (scripts_enabled)
       loader->SetEnabled(true);
   
   return rv;
--- a/parser/html/nsParserUtils.h
+++ b/parser/html/nsParserUtils.h
@@ -36,17 +36,17 @@
 
 #ifndef nsParserUtils_h_
 #define nsParserUtils_h_
 
 #include "nsIScriptableUnescapeHTML.h"
 #include "nsIParserUtils.h"
 
 class nsParserUtils : public nsIScriptableUnescapeHTML,
-                               public nsIParserUtils
+                      public nsIParserUtils
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSISCRIPTABLEUNESCAPEHTML
   NS_DECL_NSIPARSERUTILS
 };
 
 #endif // nsParserUtils_h_
--- a/testing/extensions/community/chrome/content/common.js
+++ b/testing/extensions/community/chrome/content/common.js
@@ -144,22 +144,21 @@ var qaTools = {
         if (obj instanceof Array) {
             return obj;
         }
         var newArray = new Array();
         newArray[0] = obj;
         return newArray;
     },
     writeSafeHTML : function(elementID, htmlstr) {
-        document.getElementById(elementID).innerHTML = "";  //clear it.
-        var gUnescapeHTML = Components.classes["@mozilla.org/feed-unescapehtml;1"].getService(Components.interfaces.nsIScriptableUnescapeHTML);
+        document.getElementById(elementID).textContent = "";  //clear it.
+        var utils = Components.classes["@mozilla.org/parserutils;1"].getService(Components.interfaces.nsIParserUtils);
         var context = document.getElementById(elementID);
-        var fragment = gUnescapeHTML.parseFragment(htmlstr, false, null, context);
+        var fragment = utils.parseFragment(htmlstr, 0, false, null, context);
         context.appendChild(fragment);
-
     },
 
     assignLinkHandlers : function(node) {
         var children = node.getElementsByTagName('a');
         for (var i = 0; i < children.length; i++)
            children[i].addEventListener("click", qaTools.handleLink, false);
     },
     assignLinkHandler : function(link) {
--- a/toolkit/components/feeds/FeedProcessor.js
+++ b/toolkit/components/feeds/FeedProcessor.js
@@ -70,17 +70,17 @@ const GENERATOR_CLASSNAME = "Feed Genera
 const PERSON_CONTRACTID = "@mozilla.org/feed-person;1";
 const PERSON_CLASSID = Components.ID("{95c963b7-20b2-11db-92f6-001422106990}");
 const PERSON_CLASSNAME = "Feed Person";
 
 const IO_CONTRACTID = "@mozilla.org/network/io-service;1"
 const BAG_CONTRACTID = "@mozilla.org/hash-property-bag;1"
 const ARRAY_CONTRACTID = "@mozilla.org/array;1";
 const SAX_CONTRACTID = "@mozilla.org/saxparser/xmlreader;1";
-const UNESCAPE_CONTRACTID = "@mozilla.org/feed-unescapehtml;1";
+const PARSERUTILS_CONTRACTID = "@mozilla.org/parserutils;1";
 
 
 var gIoService = null;
 
 const XMLNS = "http://www.w3.org/XML/1998/namespace";
 const RSS090NS = "http://my.netscape.com/rdf/simple/0.9/";
 
 /***** Some general utils *****/
@@ -639,24 +639,26 @@ Entry.prototype._resetBagMembersToRawTex
    Feed.prototype._resetBagMembersToRawText;
 
 // TextConstruct represents and element that could contain (X)HTML
 function TextConstruct() {
   this.lang = null;
   this.base = null;
   this.type = "text";
   this.text = null;
-  this.unescapeHTML = Cc[UNESCAPE_CONTRACTID].
-                      getService(Ci.nsIScriptableUnescapeHTML);
+  this.parserUtils = Cc[PARSERUTILS_CONTRACTID].getService(Ci.nsIParserUtils);
 }
 
 TextConstruct.prototype = {
   plainText: function TC_plainText() {
     if (this.type != "text") {
-      return this.unescapeHTML.unescape(stripTags(this.text));
+      return this.parserUtils.convertToPlainText(stripTags(this.text),
+        Ci.nsIDocumentEncoder.OutputSelectionOnly |
+        Ci.nsIDocumentEncoder.OutputAbsoluteLinks,
+        0);
     }
     return this.text;
   },
 
   createDocumentFragment: function TC_createDocumentFragment(element) {
     if (this.type == "text") {
       var doc = element.ownerDocument;
       var docFragment = doc.createDocumentFragment();
@@ -667,18 +669,18 @@ TextConstruct.prototype = {
     var isXML;
     if (this.type == "xhtml")
       isXML = true
     else if (this.type == "html")
       isXML = false;
     else
       return null;
 
-    return this.unescapeHTML.parseFragment(this.text, isXML,
-                                           this.base, element);
+    return this.parserUtils.parseFragment(this.text, 0, isXML,
+                                          this.base, element);
   },
  
   // XPCOM stuff
   classID: TEXTCONSTRUCT_CLASSID,
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIFeedTextConstruct])
 }
 
 // Generator represents the software that produced the feed
--- a/toolkit/components/feeds/test/test_bug675492.xul
+++ b/toolkit/components/feeds/test/test_bug675492.xul
@@ -17,15 +17,15 @@ https://bugzilla.mozilla.org/show_bug.cg
 
   <!-- test code goes here -->
   <script type="application/javascript">
   <![CDATA[
 
   /** Test for Bug 675492 **/
 
   Components
-    .classes["@mozilla.org/feed-unescapehtml;1"]
-    .getService(Components.interfaces.nsIScriptableUnescapeHTML)
-    .parseFragment("<p>test</p>", false, null, document.createElementNS("http://www.w3.org/1999/xhtml", "body"));
+    .classes["@mozilla.org/parserutils;1"]
+    .getService(Components.interfaces.nsIParserUtils)
+    .parseFragment("<p>test</p>", 0, false, null, document.createElementNS("http://www.w3.org/1999/xhtml", "body"));
   ok(true, "No crash!");
   ]]>
   </script>
 </window>