Bug 604332 - Whitelist attribute names beginning with "_" when pasting HTML into an editable field; r=roc a=LegNeato
authorEhsan Akhgari <ehsan@mozilla.com>
Mon, 18 Oct 2010 13:59:34 -0400
changeset 27166 0fe7a05219fd9e81eb3ddaf08123e56fffb75c69
parent 27165 0b5e0f7e7c57a3496b009c87c623aaa63d67312a
child 27167 ca9afc176ebb0b1d5fe82e3096fb7f69d2f3d65e
push id2540
push usereakhgari@mozilla.com
push dateWed, 20 Oct 2010 20:38:10 +0000
reviewersroc, LegNeato
bugs604332
milestone1.9.1.15pre
Bug 604332 - Whitelist attribute names beginning with "_" when pasting HTML into an editable field; r=roc a=LegNeato
content/html/document/src/nsHTMLFragmentContentSink.cpp
editor/libeditor/html/tests/test_bug520189.html
--- a/content/html/document/src/nsHTMLFragmentContentSink.cpp
+++ b/content/html/document/src/nsHTMLFragmentContentSink.cpp
@@ -1095,20 +1095,21 @@ nsHTMLParanoidFragmentSink::AddAttribute
     const nsAString& key = aNode.GetKeyAt(i);
     CopyUTF16toUTF8(key, k);
     ToLowerCase(k);
 
     nsCOMPtr<nsIAtom> keyAtom = do_GetAtom(k);
 
     // Check if this is an allowed attribute, or a style attribute in case
     // we've been asked to allow style attributes, or an HTML5 data-*
-    // attribute.
+    // attribute, or an attribute which begins with "_".
     if ((!sAllowedAttributes || !sAllowedAttributes->GetEntry(keyAtom)) &&
         (!mProcessStyle || keyAtom != nsGkAtoms::style) &&
-        !StringBeginsWith(key, NS_LITERAL_STRING("data-"))) {
+        !(StringBeginsWith(key, NS_LITERAL_STRING("data-")) ||
+          StringBeginsWith(key, NS_LITERAL_STRING("_")))) {
       continue;
     }
 
     // Get value and remove mandatory quotes
     static const char* kWhitespace = "\n\r\t\b";
     const nsAString& v =
       nsContentUtils::TrimCharsInSet(kWhitespace, aNode.GetValueAt(i));
 
--- a/editor/libeditor/html/tests/test_bug520189.html
+++ b/editor/libeditor/html/tests/test_bug520189.html
@@ -51,16 +51,18 @@ https://bugzilla.mozilla.org/show_bug.cg
   <iframe id="ii" src="about:blank"></iframe>
   <div id="jj" contenteditable="true"></div>
   <iframe id="kk" src="about:blank"></iframe>
   <div id="ll" contenteditable="true"></div>
   <iframe id="mm" src="about:blank"></iframe>
   <div id="nn" contenteditable="true"></div>
   <iframe id="oo" src="about:blank"></iframe>
   <div id="pp" contenteditable="true"></div>
+  <iframe id="qq" src="about:blank"></iframe>
+  <div id="rr" contenteditable="true"></div>
 </div>
 <pre id="test">
 <script type="application/javascript">
 
 /** Test for Bug 520182 **/
 
 const dataPayload = "foo<iframe src=\"data:text/html,bar\"></iframe>baz";
 const jsPayload = "foo<iframe src=\"javascript:void('bar');\"></iframe>baz";
@@ -78,16 +80,17 @@ const invalidStyle4Payload = "foo<span s
 const invalidStyle5Payload = "foo<span style=\"@font-face{font-family:xxx;src:'xxx.ttf';}\">bar</span>baz";
 const invalidStyle6Payload = "foo<span style=\"@namespace xxx url(http://example.com/);\">bar</span>baz";
 const invalidStyle7Payload = "<html><head><title>xxx</title></head><body>foo</body></html>";
 const nestedStylePayload = "foo<style>#bar1{-moz-binding:url('data:text/xml,<?xml version=&quot;1.0&quot;><binding xmlns=&quot;http://www.mozilla.org/xbl&quot; id=&quot;binding-1&quot;/>');<style></style>#bar2{-moz-binding:url('data:text/xml,<?xml version=&quot;1.0&quot;><binding xmlns=&quot;http://www.mozilla.org/xbl&quot; id=&quot;binding-2&quot;/>');</style>baz";
 const validImgSrc1Payload = "foo<img src=\"data:image/png,bar\">baz";
 const validImgSrc2Payload = "foo<img src=\"javascript:void('bar');\">baz";
 const validImgSrc3Payload = "foo<img src=\"file:///bar.png\">baz";
 const validDataFooPayload = "foo<span data-bar=\"value\">baz</span>";
+const validDataFoo2Payload = "foo<span _bar=\"value\">baz</span>";
 
 var tests = [
   {
     id: "a",
     isIFrame: true,
     payload: dataPayload,
     iframeCount: 0,
     rootElement: function() document.getElementById("a").contentDocument.documentElement
@@ -368,16 +371,29 @@ var tests = [
     rootElement: function() document.getElementById("oo").contentDocument.documentElement,
     checkResult: function(html) isnot(html.indexOf("bar"), -1, "Should have retained the data-bar attribute")
   },
   {
     id: "pp",
     payload: validDataFooPayload,
     rootElement: function() document.getElementById("pp"),
     checkResult: function(html) isnot(html.indexOf("bar"), -1, "Should have retained the data-bar attribute")
+  },
+  {
+    id: "qq",
+    isIFrame: true,
+    payload: validDataFoo2Payload,
+    rootElement: function() document.getElementById("qq").contentDocument.documentElement,
+    checkResult: function(html) isnot(html.indexOf("bar"), -1, "Should have retained the _bar attribute")
+  },
+  {
+    id: "rr",
+    payload: validDataFoo2Payload,
+    rootElement: function() document.getElementById("rr"),
+    checkResult: function(html) isnot(html.indexOf("bar"), -1, "Should have retained the _bar attribute")
   }
 ];
 
 function doNextTest() {
   if (typeof testCounter == "undefined")
     testCounter = 0;
   else if (++testCounter == tests.length) {
     SimpleTest.finish();