Refactored script content removal in the fragment parser for clarity and speed
authorggaren@apple.com <ggaren@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 19 Mar 2013 21:51:48 +0000 (21:51 +0000)
committerggaren@apple.com <ggaren@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 19 Mar 2013 21:51:48 +0000 (21:51 +0000)
https://bugs.webkit.org/show_bug.cgi?id=112734

Reviewed by Enrica Casucci.

Source/WebCore:

* WebCore.exp.in: Export!

* dom/DocumentFragment.cpp:
(WebCore::DocumentFragment::parseHTML):
(WebCore::DocumentFragment::parseXML):
* dom/DocumentFragment.h:
(DocumentFragment): Updated for rename of FragmentScriptingPermission to
ParserContentPolicy.

* dom/Element.cpp:
(WebCore::isEventHandlerAttribute):
(WebCore::Element::isJavaScriptURLAttribute):
(WebCore::Element::isJavaScriptAttribute): Fixed a FIXME by factoring
out some helper functions that reuse isURLAttribute(). This makes our
attribute removal slightly more precise, as reflected in test changes.

(WebCore::Element::stripJavaScriptAttributes): Factored this function out
of parserSetAttributes to clarify that the parser is responsible for
fully removing scripts before inserting anything into the DOM.

Now that this is a helper function, we can avoid doing any work in the
common case, where script content is allowed. Also, when we do have to
strip attributes, we use "two finger compaction" to avoid copying the
vector, and to avoid O(N) vector removal operations when there is
something to remove.

(WebCore::Element::parserSetAttributes):
* dom/Element.h:

* dom/FragmentScriptingPermission.h:
(WebCore::scriptingContentIsAllowed):
(WebCore::disallowScriptingContent):
(WebCore::pluginContentIsAllowed):
(WebCore::allowPluginContent): Renamed for clarity, and added some helper
functions for reading values out of this enum.

* dom/ScriptableDocumentParser.cpp:
(WebCore::ScriptableDocumentParser::ScriptableDocumentParser): Moved
a settings check into the parser constructor so we're sure that all
clients get the right behavior.

* dom/ScriptableDocumentParser.h:
(WebCore::ScriptableDocumentParser::parserContentPolicy):
(ScriptableDocumentParser):
* editing/markup.cpp:
(WebCore::createFragmentFromMarkup):
(WebCore::createFragmentFromMarkupWithContext):
(WebCore::createFragmentForInnerOuterHTML):
(WebCore::createContextualFragment):
* editing/markup.h: Updated for renames.

* html/HTMLAnchorElement.cpp:
(WebCore::HTMLAnchorElement::isURLAttribute): Fixed a bug where
isURLAttribute would ignore href attributes in other namespaces, like
xlink:href.

* html/HTMLBaseElement.cpp:
(WebCore::HTMLBaseElement::isURLAttribute): Same bug.

* html/HTMLElement.cpp:
(WebCore::HTMLElement::isURLAttribute): Fixed a logic error where HTMLElement
wouldn't call through to its base class.

* html/HTMLLinkElement.cpp:
(WebCore::HTMLLinkElement::isURLAttribute): Same isURLAttribute namespace
bug as above.

* html/parser/HTMLConstructionSite.cpp:
(WebCore::setAttributes): Helper function for optionally stripping
disallowed attributes before setting them on an element. This helps all
clients get the right behavior without sprinkling checks everywhere.

(WebCore::HTMLConstructionSite::HTMLConstructionSite):
(WebCore::HTMLConstructionSite::insertHTMLHtmlStartTagBeforeHTML):

(WebCore::HTMLConstructionSite::insertScriptElement): Don't schedule the
element for insertion into the document if the element is forbidden. This
is slightly clearer than leaving an empty forbidden element in the document.

(WebCore::HTMLConstructionSite::createElement):
(WebCore::HTMLConstructionSite::createHTMLElement):
* html/parser/HTMLConstructionSite.h:
(HTMLConstructionSite):
(WebCore::HTMLConstructionSite::parserContentPolicy):
* html/parser/HTMLDocumentParser.cpp:
(WebCore::HTMLDocumentParser::HTMLDocumentParser):
(WebCore::HTMLDocumentParser::runScriptsForPausedTreeBuilder):
(WebCore::HTMLDocumentParser::parseDocumentFragment):
* html/parser/HTMLDocumentParser.h:
(HTMLDocumentParser):
(WebCore::HTMLDocumentParser::create):
* html/parser/HTMLTreeBuilder.cpp:
(WebCore::HTMLTreeBuilder::HTMLTreeBuilder):
(WebCore::HTMLTreeBuilder::FragmentParsingContext::FragmentParsingContext):
Updated for renames and interface changes above.

(WebCore::HTMLTreeBuilder::processStartTagForInBody):
(WebCore::HTMLTreeBuilder::processEndTag): Removed isParsingFragment()
checks to make it possible to use ParserContentPolicy in more places.

Removed call to removeChildren() because, if an element is forbidden,
we fully remove the element now. This brings behavior for <script>
elements in line with behavior for plug-in elements. It also brings
behavior of the HTML parser in line with behavior of the XML parser.

* html/parser/HTMLTreeBuilder.h:
(WebCore::HTMLTreeBuilder::create):
(FragmentParsingContext):
(WebCore::HTMLTreeBuilder::FragmentParsingContext::contextElement):
* platform/blackberry/PasteboardBlackBerry.cpp:
(WebCore::Pasteboard::documentFragment):
* platform/chromium/DragDataChromium.cpp:
(WebCore::DragData::asFragment):
* platform/chromium/PasteboardChromium.cpp:
(WebCore::Pasteboard::documentFragment):
* platform/gtk/PasteboardGtk.cpp:
(WebCore::Pasteboard::documentFragment):
* platform/mac/PasteboardMac.mm:
(WebCore::Pasteboard::documentFragment):
* platform/qt/DragDataQt.cpp:
(WebCore::DragData::asFragment):
* platform/qt/PasteboardQt.cpp:
(WebCore::Pasteboard::documentFragment):
* platform/win/ClipboardUtilitiesWin.cpp:
(WebCore::fragmentFromCFHTML):
(WebCore::fragmentFromHTML):
* platform/wx/PasteboardWx.cpp:
(WebCore::Pasteboard::documentFragment): Updated for renames and interface
changes.

* svg/SVGAElement.cpp:
(WebCore::SVGAElement::isURLAttribute): Fixed a bug where SVG anchor
elements didn't identify their URL attributes.

* svg/SVGAElement.h:
(SVGAElement):

* xml/XMLErrors.cpp:
(WebCore::createXHTMLParserErrorHeader):
(WebCore::XMLErrors::insertErrorMessageBlock): No need to disallow
scripting attributes here because we're creating the attributes
ourselves and we know they're not scripting attributes.

* xml/parser/XMLDocumentParser.cpp:
(WebCore::XMLDocumentParser::parseDocumentFragment):
* xml/parser/XMLDocumentParser.h:
(WebCore::XMLDocumentParser::create):
(XMLDocumentParser): Updated for renames and interface changes above.

Removed the 8 inline capacity in the attribute vector so we could share
helper functions with the HTML parser, which didn't have it.

* xml/parser/XMLDocumentParserLibxml2.cpp:
(WebCore::setAttributes):
(WebCore):
(WebCore::XMLDocumentParser::XMLDocumentParser):
(WebCore::handleNamespaceAttributes):
(WebCore::handleElementAttributes):
(WebCore::XMLDocumentParser::startElementNs):
(WebCore::XMLDocumentParser::endElementNs):
* xml/parser/XMLDocumentParserQt.cpp:
(WebCore::setAttributes):
(WebCore):
(WebCore::XMLDocumentParser::XMLDocumentParser):
(WebCore::handleNamespaceAttributes):
(WebCore::handleElementAttributes):
(WebCore::XMLDocumentParser::parseStartElement):
(WebCore::XMLDocumentParser::parseEndElement): Same changes as for the
HTML parser.

LayoutTests:

Updated tests to improve coverage and reflect behavior tweaks to improve
clarity.

* editing/pasteboard/paste-noscript-expected.txt:
    - The "href", "source", and "action" attributes are fully removed now,
    instead of being set to the empty string, because for clarity we
    fully remove script attributes instead of setting their values to
    the empty string.

    - The "formaction" attribute on the form control is not removed because,
    even though it seems to contain javascript content, the formaction
    attribute doesn't map to anything on a form element, and won't ever
    run as script.

    - I added a button with a "formaction" attribute, to verify that it
    does get stripped, since this is the case where the "formaction"
    attribute can run as script.

* editing/pasteboard/paste-noscript-svg-expected.txt:
    - The "xlink:href" attribute is fully removed now. See above.

* editing/pasteboard/paste-noscript-xhtml-expected.txt:
* editing/pasteboard/paste-noscript.html:
    - The "href", "source", and "action" attributes are fully removed now.
    See above.

    - The <script> element is fully removed now. See above.

    - The "formaction" attribute on the form control is not removed.
    See above.

    - I added a button with a "formaction" attribute. See above.

* editing/pasteboard/paste-visible-script-expected.txt:
    - The <script> elements are fully removed now. See above.

* editing/pasteboard/resources/paste-noscript-content.html:
    - The "formaction" attribute on the form control is not removed.
    See above.

    - I added a button with a "formaction" attribute. See above.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@146264 268f45cc-cd09-0410-ab3c-d52691b4dbfc

44 files changed:
LayoutTests/ChangeLog
LayoutTests/editing/pasteboard/paste-noscript-expected.txt
LayoutTests/editing/pasteboard/paste-noscript-svg-expected.txt
LayoutTests/editing/pasteboard/paste-noscript-xhtml-expected.txt
LayoutTests/editing/pasteboard/paste-noscript.html
LayoutTests/editing/pasteboard/paste-visible-script-expected.txt
LayoutTests/editing/pasteboard/resources/paste-noscript-content.html
Source/WebCore/ChangeLog
Source/WebCore/WebCore.exp.in
Source/WebCore/dom/DocumentFragment.cpp
Source/WebCore/dom/DocumentFragment.h
Source/WebCore/dom/Element.cpp
Source/WebCore/dom/Element.h
Source/WebCore/dom/FragmentScriptingPermission.h
Source/WebCore/dom/ScriptableDocumentParser.cpp
Source/WebCore/dom/ScriptableDocumentParser.h
Source/WebCore/editing/markup.cpp
Source/WebCore/editing/markup.h
Source/WebCore/html/HTMLAnchorElement.cpp
Source/WebCore/html/HTMLBaseElement.cpp
Source/WebCore/html/HTMLElement.cpp
Source/WebCore/html/HTMLLinkElement.cpp
Source/WebCore/html/parser/HTMLConstructionSite.cpp
Source/WebCore/html/parser/HTMLConstructionSite.h
Source/WebCore/html/parser/HTMLDocumentParser.cpp
Source/WebCore/html/parser/HTMLDocumentParser.h
Source/WebCore/html/parser/HTMLTreeBuilder.cpp
Source/WebCore/html/parser/HTMLTreeBuilder.h
Source/WebCore/platform/blackberry/PasteboardBlackBerry.cpp
Source/WebCore/platform/chromium/DragDataChromium.cpp
Source/WebCore/platform/chromium/PasteboardChromium.cpp
Source/WebCore/platform/gtk/PasteboardGtk.cpp
Source/WebCore/platform/mac/PasteboardMac.mm
Source/WebCore/platform/qt/DragDataQt.cpp
Source/WebCore/platform/qt/PasteboardQt.cpp
Source/WebCore/platform/win/ClipboardUtilitiesWin.cpp
Source/WebCore/platform/wx/PasteboardWx.cpp
Source/WebCore/svg/SVGAElement.cpp
Source/WebCore/svg/SVGAElement.h
Source/WebCore/xml/XMLErrors.cpp
Source/WebCore/xml/parser/XMLDocumentParser.cpp
Source/WebCore/xml/parser/XMLDocumentParser.h
Source/WebCore/xml/parser/XMLDocumentParserLibxml2.cpp
Source/WebCore/xml/parser/XMLDocumentParserQt.cpp

index 564f344..a2a900f 100644 (file)
@@ -1,3 +1,53 @@
+2013-03-19  Geoffrey Garen  <ggaren@apple.com>
+
+        Refactored script content removal in the fragment parser for clarity and speed
+        https://bugs.webkit.org/show_bug.cgi?id=112734
+
+        Reviewed by Enrica Casucci.
+
+        Updated tests to improve coverage and reflect behavior tweaks to improve
+        clarity.
+
+        * editing/pasteboard/paste-noscript-expected.txt: 
+            - The "href", "source", and "action" attributes are fully removed now,
+            instead of being set to the empty string, because for clarity we
+            fully remove script attributes instead of setting their values to
+            the empty string.
+
+            - The "formaction" attribute on the form control is not removed because,
+            even though it seems to contain javascript content, the formaction
+            attribute doesn't map to anything on a form element, and won't ever
+            run as script.
+
+            - I added a button with a "formaction" attribute, to verify that it
+            does get stripped, since this is the case where the "formaction"
+            attribute can run as script.
+
+        * editing/pasteboard/paste-noscript-svg-expected.txt:
+            - The "xlink:href" attribute is fully removed now. See above.
+
+        * editing/pasteboard/paste-noscript-xhtml-expected.txt:
+        * editing/pasteboard/paste-noscript.html:
+            - The "href", "source", and "action" attributes are fully removed now.
+            See above.
+
+            - The <script> element is fully removed now. See above.
+
+            - The "formaction" attribute on the form control is not removed.
+            See above.
+
+            - I added a button with a "formaction" attribute. See above.
+
+
+        * editing/pasteboard/paste-visible-script-expected.txt:
+            - The <script> elements are fully removed now. See above.
+
+        * editing/pasteboard/resources/paste-noscript-content.html:
+            - The "formaction" attribute on the form control is not removed.
+            See above.
+
+            - I added a button with a "formaction" attribute. See above.
+
 2013-03-19  Mark Hahnenberg  <mhahnenberg@apple.com>
 
         Crash in SpeculativeJIT::fillSpeculateIntInternal<false> on http://bellard.org/jslinux
index e66c779..9daea30 100644 (file)
@@ -2,18 +2,18 @@ This test copies all the elements containing event handlers and javascript urls,
 Hello 
 CNN Hello 
 This is a form
-
+Submit.
 Hello 
 CNN Hello 
 This is a form
-
+Submit.
 <button id="button1" onclick="sayHello()" ondblclick="sayHello()" style="width: 100px;">Hello</button>
 <button id="button1" style="width: 100px;">Hello</button>
 <a id="anchor1" href="http://www.cnn.com/">CNN</a>
 <a id="anchor1" href="http://www.cnn.com/">CNN</a>
 <a id="anchor2" href="javascript:sayHello()">Hello</a>
-<a id="anchor2" href="">Hello</a>
+<a id="anchor2">Hello</a>
 <iframe id="iframe1" src="javascript:var x = 1;" style="width: 200px; height: 100px; background-color:#cee;"></iframe>
-<iframe id="iframe1" src="" style="width: 200px; height: 100px; background-color: rgb(204, 238, 238);"></iframe>
-<form id="form1" action="javascript:sayHello()" formaction="javascript:sayHello()" style="width: 200px; height: 150px; background-color:#cee;">This is a form<br><img src="../resources/abe.png"></form>
-<form id="form1" action="" formaction="" style="width: 200px; height: 150px; background-color: rgb(204, 238, 238);">This is a form<br><img src="../resources/abe.png"></form>
+<iframe id="iframe1" style="width: 200px; height: 100px; background-color: rgb(204, 238, 238);"></iframe>
+<form id="form1" action="javascript:sayHello()" formaction="javascript:sayHello()" style="width: 200px; height: 150px; background-color:#cee;">This is a form<br><img src="../resources/abe.png"><button formaction="javascript:sayHello()">Submit.</button></form>
+<form id="form1" formaction="javascript:sayHello()" style="width: 200px; height: 150px; background-color: rgb(204, 238, 238);">This is a form<br><img src="../resources/abe.png"><button>Submit.</button></form>
index eb62f5c..772ce37 100644 (file)
@@ -1,5 +1,5 @@
 This test copies the content of an iframe and pastes it in an editable area and verifies that no script, handlers or javascript urls are copied.
 Hello
 world
-<div id="div1">Hello</div><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="5cm" height="3cm" viewBox="0 0 5 3" version="1.1"><a xlink:href=""><ellipse cx="2.5" cy="1.5" rx="2" ry="1" fill="red"></ellipse></a></svg><div id="div2">world</div>
+<div id="div1">Hello</div><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="5cm" height="3cm" viewBox="0 0 5 3" version="1.1"><a><ellipse cx="2.5" cy="1.5" rx="2" ry="1" fill="red"></ellipse></a></svg><div id="div2">world</div>
 
index bb423f8..8bb0d63 100644 (file)
@@ -45,7 +45,10 @@ Copied content:
 |   formaction="javascript:sayHello()"
 |   id="form1"
 |   style="width: 200px; height: 150px; background-color:#cee;"
-|   "This is a form<#selection-focus>"
+|   "This is a form. "
+|   <button>
+|     formaction="javascript:sayHello()"
+|     "Submit.<#selection-focus>"
 | "
 
 "
@@ -64,21 +67,19 @@ Pasted content:
 |   id="anchor1"
 |   "CNN"
 | <a>
-|   href=""
 |   id="anchor2"
 |   "Hello"
-| <script>
-| <script>
 | <iframe>
 |   id="iframe1"
-|   src=""
 |   style="width: 200px; height: 100px; background-color: rgb(204, 238, 238);"
 | <form>
-|   action=""
-|   formaction=""
+|   formaction="javascript:sayHello()"
 |   id="form1"
 |   style="width: 200px; height: 150px; background-color: rgb(204, 238, 238);"
-|   "This is a form<#selection-caret>"
+|   "This is a form."
+|   " "
+|   <button>
+|     "Submit.<#selection-caret>"
 
 FRAME 0:
 | <head>
index 694088b..234d876 100644 (file)
@@ -16,7 +16,7 @@ in an editable area and verifies that no script, handlers or javascript urls are
 <a id="anchor1" href="http://www.cnn.com/">CNN</a>
 <a id="anchor2" href="javascript:sayHello()">Hello</a>
 <iframe id="iframe1" src="javascript:var x = 1;" style="width: 200px; height: 100px; background-color:#cee;"></iframe>
-<form id="form1" action="javascript:sayHello()" formaction="javascript:sayHello()" style="width: 200px; height: 150px; background-color:#cee;">This is a form<br><img src="../resources/abe.png"></img></form>
+<form id="form1" action="javascript:sayHello()" formaction="javascript:sayHello()" style="width: 200px; height: 150px; background-color:#cee;">This is a form<br><img src="../resources/abe.png"></img><button formaction="javascript:sayHello()">Submit.</button></form>
 </div>
 <div id="pastehere" contenteditable="true">
 </div>
index 905a885..566d4f3 100644 (file)
@@ -3,4 +3,4 @@ function sayHello() { alert("Hello"); }
 World
 Hello
 World
-<div id="pastehere" contenteditable="true">Hello<script></script><script></script><div id="test2">World</div></div>
+<div id="pastehere" contenteditable="true">Hello<div id="test2">World</div></div>
index 20c2b37..fb2bf2e 100644 (file)
@@ -11,5 +11,5 @@ if (window.testRunner)
 <script style="display: block; position: fixed; top: 4000px">alert('hello');</script>
 <script src="../editing.js" style="display: block; position: fixed; top: 4000px"></script>
 <iframe id="iframe1" src="javascript:alert('hello')" style="width: 200px; height: 100px; background-color:#cee;"></iframe>
-<form id="form1" action="javascript:sayHello()" formaction="javascript:sayHello()" style="width: 200px; height: 150px; background-color:#cee;">This is a form</form>
+<form id="form1" action="javascript:sayHello()" formaction="javascript:sayHello()" style="width: 200px; height: 150px; background-color:#cee;">This is a form. <button formaction="javascript:sayHello()">Submit.</button></form>
 </body>
index 129c80e..ff9afb6 100644 (file)
@@ -1,3 +1,180 @@
+2013-03-19  Geoffrey Garen  <ggaren@apple.com>
+
+        Refactored script content removal in the fragment parser for clarity and speed
+        https://bugs.webkit.org/show_bug.cgi?id=112734
+
+        Reviewed by Enrica Casucci.
+
+        * WebCore.exp.in: Export!
+
+        * dom/DocumentFragment.cpp:
+        (WebCore::DocumentFragment::parseHTML):
+        (WebCore::DocumentFragment::parseXML):
+        * dom/DocumentFragment.h:
+        (DocumentFragment): Updated for rename of FragmentScriptingPermission to
+        ParserContentPolicy.
+
+        * dom/Element.cpp:
+        (WebCore::isEventHandlerAttribute):
+        (WebCore::Element::isJavaScriptURLAttribute):
+        (WebCore::Element::isJavaScriptAttribute): Fixed a FIXME by factoring
+        out some helper functions that reuse isURLAttribute(). This makes our
+        attribute removal slightly more precise, as reflected in test changes.
+
+        (WebCore::Element::stripJavaScriptAttributes): Factored this function out
+        of parserSetAttributes to clarify that the parser is responsible for
+        fully removing scripts before inserting anything into the DOM.
+
+        Now that this is a helper function, we can avoid doing any work in the
+        common case, where script content is allowed. Also, when we do have to
+        strip attributes, we use "two finger compaction" to avoid copying the
+        vector, and to avoid O(N) vector removal operations when there is
+        something to remove.
+
+        (WebCore::Element::parserSetAttributes):
+        * dom/Element.h:
+
+        * dom/FragmentScriptingPermission.h:
+        (WebCore::scriptingContentIsAllowed):
+        (WebCore::disallowScriptingContent):
+        (WebCore::pluginContentIsAllowed):
+        (WebCore::allowPluginContent): Renamed for clarity, and added some helper
+        functions for reading values out of this enum.
+
+        * dom/ScriptableDocumentParser.cpp:
+        (WebCore::ScriptableDocumentParser::ScriptableDocumentParser): Moved
+        a settings check into the parser constructor so we're sure that all
+        clients get the right behavior.
+
+        * dom/ScriptableDocumentParser.h:
+        (WebCore::ScriptableDocumentParser::parserContentPolicy):
+        (ScriptableDocumentParser):
+        * editing/markup.cpp:
+        (WebCore::createFragmentFromMarkup):
+        (WebCore::createFragmentFromMarkupWithContext):
+        (WebCore::createFragmentForInnerOuterHTML):
+        (WebCore::createContextualFragment):
+        * editing/markup.h: Updated for renames.
+
+        * html/HTMLAnchorElement.cpp:
+        (WebCore::HTMLAnchorElement::isURLAttribute): Fixed a bug where
+        isURLAttribute would ignore href attributes in other namespaces, like
+        xlink:href.
+
+        * html/HTMLBaseElement.cpp:
+        (WebCore::HTMLBaseElement::isURLAttribute): Same bug.
+
+        * html/HTMLElement.cpp:
+        (WebCore::HTMLElement::isURLAttribute): Fixed a logic error where HTMLElement
+        wouldn't call through to its base class.
+
+        * html/HTMLLinkElement.cpp:
+        (WebCore::HTMLLinkElement::isURLAttribute): Same isURLAttribute namespace
+        bug as above.
+
+        * html/parser/HTMLConstructionSite.cpp:
+        (WebCore::setAttributes): Helper function for optionally stripping
+        disallowed attributes before setting them on an element. This helps all
+        clients get the right behavior without sprinkling checks everywhere.
+
+        (WebCore::HTMLConstructionSite::HTMLConstructionSite):
+        (WebCore::HTMLConstructionSite::insertHTMLHtmlStartTagBeforeHTML):
+
+        (WebCore::HTMLConstructionSite::insertScriptElement): Don't schedule the
+        element for insertion into the document if the element is forbidden. This
+        is slightly clearer than leaving an empty forbidden element in the document.
+
+        (WebCore::HTMLConstructionSite::createElement):
+        (WebCore::HTMLConstructionSite::createHTMLElement):
+        * html/parser/HTMLConstructionSite.h:
+        (HTMLConstructionSite):
+        (WebCore::HTMLConstructionSite::parserContentPolicy):
+        * html/parser/HTMLDocumentParser.cpp:
+        (WebCore::HTMLDocumentParser::HTMLDocumentParser):
+        (WebCore::HTMLDocumentParser::runScriptsForPausedTreeBuilder):
+        (WebCore::HTMLDocumentParser::parseDocumentFragment):
+        * html/parser/HTMLDocumentParser.h:
+        (HTMLDocumentParser):
+        (WebCore::HTMLDocumentParser::create):
+        * html/parser/HTMLTreeBuilder.cpp:
+        (WebCore::HTMLTreeBuilder::HTMLTreeBuilder):
+        (WebCore::HTMLTreeBuilder::FragmentParsingContext::FragmentParsingContext):
+        Updated for renames and interface changes above.
+
+        (WebCore::HTMLTreeBuilder::processStartTagForInBody):
+        (WebCore::HTMLTreeBuilder::processEndTag): Removed isParsingFragment()
+        checks to make it possible to use ParserContentPolicy in more places.
+
+        Removed call to removeChildren() because, if an element is forbidden,
+        we fully remove the element now. This brings behavior for <script>
+        elements in line with behavior for plug-in elements. It also brings
+        behavior of the HTML parser in line with behavior of the XML parser.
+
+        * html/parser/HTMLTreeBuilder.h:
+        (WebCore::HTMLTreeBuilder::create):
+        (FragmentParsingContext):
+        (WebCore::HTMLTreeBuilder::FragmentParsingContext::contextElement):
+        * platform/blackberry/PasteboardBlackBerry.cpp:
+        (WebCore::Pasteboard::documentFragment):
+        * platform/chromium/DragDataChromium.cpp:
+        (WebCore::DragData::asFragment):
+        * platform/chromium/PasteboardChromium.cpp:
+        (WebCore::Pasteboard::documentFragment):
+        * platform/gtk/PasteboardGtk.cpp:
+        (WebCore::Pasteboard::documentFragment):
+        * platform/mac/PasteboardMac.mm:
+        (WebCore::Pasteboard::documentFragment):
+        * platform/qt/DragDataQt.cpp:
+        (WebCore::DragData::asFragment):
+        * platform/qt/PasteboardQt.cpp:
+        (WebCore::Pasteboard::documentFragment):
+        * platform/win/ClipboardUtilitiesWin.cpp:
+        (WebCore::fragmentFromCFHTML):
+        (WebCore::fragmentFromHTML):
+        * platform/wx/PasteboardWx.cpp:
+        (WebCore::Pasteboard::documentFragment): Updated for renames and interface
+        changes.
+
+        * svg/SVGAElement.cpp:
+        (WebCore::SVGAElement::isURLAttribute): Fixed a bug where SVG anchor
+        elements didn't identify their URL attributes.
+
+        * svg/SVGAElement.h:
+        (SVGAElement):
+
+        * xml/XMLErrors.cpp:
+        (WebCore::createXHTMLParserErrorHeader):
+        (WebCore::XMLErrors::insertErrorMessageBlock): No need to disallow
+        scripting attributes here because we're creating the attributes 
+        ourselves and we know they're not scripting attributes.
+
+        * xml/parser/XMLDocumentParser.cpp:
+        (WebCore::XMLDocumentParser::parseDocumentFragment):
+        * xml/parser/XMLDocumentParser.h:
+        (WebCore::XMLDocumentParser::create):
+        (XMLDocumentParser): Updated for renames and interface changes above.
+
+        Removed the 8 inline capacity in the attribute vector so we could share
+        helper functions with the HTML parser, which didn't have it.
+
+        * xml/parser/XMLDocumentParserLibxml2.cpp:
+        (WebCore::setAttributes):
+        (WebCore):
+        (WebCore::XMLDocumentParser::XMLDocumentParser):
+        (WebCore::handleNamespaceAttributes):
+        (WebCore::handleElementAttributes):
+        (WebCore::XMLDocumentParser::startElementNs):
+        (WebCore::XMLDocumentParser::endElementNs):
+        * xml/parser/XMLDocumentParserQt.cpp:
+        (WebCore::setAttributes):
+        (WebCore):
+        (WebCore::XMLDocumentParser::XMLDocumentParser):
+        (WebCore::handleNamespaceAttributes):
+        (WebCore::handleElementAttributes):
+        (WebCore::XMLDocumentParser::parseStartElement):
+        (WebCore::XMLDocumentParser::parseEndElement): Same changes as for the
+        HTML parser.
+
 2013-03-19  Philip Rogers  <pdr@google.com>
 
         Clean up static_casts for SVG renderers
index 822efa8..e09a59f 100644 (file)
@@ -704,6 +704,7 @@ __ZN7WebCore24ComposedShadowTreeWalker11nextSiblingEv
 __ZN7WebCore24ComposedShadowTreeWalker4nextEv
 __ZN7WebCore24ComposedShadowTreeWalker8previousEv
 __ZN7WebCore24ComposedShadowTreeWalker9lastChildEv
+__ZN7WebCore24createFragmentFromMarkupEPNS_8DocumentERKN3WTF6StringES5_NS_19ParserContentPolicyE
 __ZN7WebCore24DocumentMarkerController10markersForEPNS_4NodeENS_14DocumentMarker11MarkerTypesE
 __ZN7WebCore24DocumentMarkerController13removeMarkersENS_14DocumentMarker11MarkerTypesE
 __ZN7WebCore24DocumentMarkerController18addTextMatchMarkerEPKNS_5RangeEb
@@ -716,7 +717,6 @@ __ZN7WebCore24FrameDestructionObserverD2Ev
 __ZN7WebCore24ScopeContentDistribution16hasShadowElementEPKNS_10ShadowRootE
 __ZN7WebCore24ScopeContentDistribution18countElementShadowEPKNS_10ShadowRootE
 __ZN7WebCore24ScopeContentDistribution17hasContentElementEPKNS_10ShadowRootE
-__ZN7WebCore24createFragmentFromMarkupEPNS_8DocumentERKN3WTF6StringES5_NS_27FragmentScriptingPermissionE
 __ZN7WebCore24decodeURLEscapeSequencesERKN3WTF6StringE
 __ZN7WebCore24deleteCookiesForHostnameERKNS_21NetworkStorageSessionERKN3WTF6StringE
 __ZN7WebCore24fileSystemRepresentationERKN3WTF6StringE
index e660248..342d171 100644 (file)
@@ -75,14 +75,14 @@ PassRefPtr<Node> DocumentFragment::cloneNode(bool deep)
     return clone.release();
 }
 
-void DocumentFragment::parseHTML(const String& source, Element* contextElement, FragmentScriptingPermission scriptingPermission)
+void DocumentFragment::parseHTML(const String& source, Element* contextElement, ParserContentPolicy parserContentPolicy)
 {
-    HTMLDocumentParser::parseDocumentFragment(source, this, contextElement, scriptingPermission);
+    HTMLDocumentParser::parseDocumentFragment(source, this, contextElement, parserContentPolicy);
 }
 
-bool DocumentFragment::parseXML(const String& source, Element* contextElement, FragmentScriptingPermission scriptingPermission)
+bool DocumentFragment::parseXML(const String& source, Element* contextElement, ParserContentPolicy parserContentPolicy)
 {
-    return XMLDocumentParser::parseDocumentFragment(source, this, contextElement, scriptingPermission);
+    return XMLDocumentParser::parseDocumentFragment(source, this, contextElement, parserContentPolicy);
 }
 
 }
index 1aca4cc..d23c482 100644 (file)
@@ -33,8 +33,8 @@ class DocumentFragment : public ContainerNode {
 public:
     static PassRefPtr<DocumentFragment> create(Document*);
 
-    void parseHTML(const String&, Element* contextElement, FragmentScriptingPermission = AllowScriptingContent);
-    bool parseXML(const String&, Element* contextElement, FragmentScriptingPermission = AllowScriptingContent);
+    void parseHTML(const String&, Element* contextElement, ParserContentPolicy = AllowScriptingContent);
+    bool parseXML(const String&, Element* contextElement, ParserContentPolicy = AllowScriptingContent);
     
     virtual bool canContainRangeEndPoint() const { return true; }
     virtual bool isTemplateContent() const { return false; }
index 6e89c01..aa7f52d 100644 (file)
@@ -1019,57 +1019,61 @@ bool Element::shouldInvalidateDistributionWhenAttributeChanged(ElementShadow* el
 // It is a simple solution that has the advantage of not requiring any
 // code or configuration change if a new event handler is defined.
 
-static bool isEventHandlerAttribute(const QualifiedName& name)
+static inline bool isEventHandlerAttribute(const Attribute& attribute)
 {
-    return name.namespaceURI().isNull() && name.localName().startsWith("on");
+    return attribute.name().namespaceURI().isNull() && attribute.name().localName().startsWith("on");
 }
 
-// FIXME: Share code with Element::isURLAttribute.
-static bool isAttributeToRemove(const QualifiedName& name, const AtomicString& value)
+bool Element::isJavaScriptURLAttribute(const Attribute& attribute)
 {
-    return (name.localName() == hrefAttr.localName() || name.localName() == nohrefAttr.localName()
-        || name == srcAttr || name == actionAttr || name == formactionAttr) && protocolIsJavaScript(stripLeadingAndTrailingHTMLSpaces(value));
+    if (!isURLAttribute(attribute))
+        return false;
+    if (!protocolIsJavaScript(stripLeadingAndTrailingHTMLSpaces(attribute.value())))
+        return false;
+    return true;
+}
+
+bool Element::isJavaScriptAttribute(const Attribute& attribute)
+{
+    if (isEventHandlerAttribute(attribute))
+        return true;
+    if (isJavaScriptURLAttribute(attribute))
+        return true;
+    return false;
+}
+
+void Element::stripJavaScriptAttributes(Vector<Attribute>& attributeVector)
+{
+    size_t destination = 0;
+    for (size_t source = 0; source < attributeVector.size(); ++source) {
+        if (isJavaScriptAttribute(attributeVector[source]))
+            continue;
+
+        if (source != destination)
+            attributeVector[destination] = attributeVector[source];
+
+        ++destination;
+    }
+    attributeVector.shrink(destination);
 }
 
-void Element::parserSetAttributes(const Vector<Attribute>& attributeVector, FragmentScriptingPermission scriptingPermission)
+void Element::parserSetAttributes(const Vector<Attribute>& attributeVector)
 {
     ASSERT(!inDocument());
     ASSERT(!parentNode());
-
     ASSERT(!m_elementData);
 
     if (attributeVector.isEmpty())
         return;
 
-    Vector<Attribute> filteredAttributes = attributeVector;
-
-    // If the element is created as result of a paste or drag-n-drop operation
-    // we want to remove all the script and event handlers.
-    if (!scriptingContentIsAllowed(scriptingPermission)) {
-        size_t i = 0;
-        while (i < filteredAttributes.size()) {
-            Attribute& attribute = filteredAttributes[i];
-            if (isEventHandlerAttribute(attribute.name())) {
-                filteredAttributes.remove(i);
-                continue;
-            }
-
-            if (isAttributeToRemove(attribute.name(), attribute.value()))
-                attribute.setValue(emptyAtom);
-            i++;
-        }
-    }
-
     if (document() && document()->sharedObjectPool())
-        m_elementData = document()->sharedObjectPool()->cachedShareableElementDataWithAttributes(filteredAttributes);
+        m_elementData = document()->sharedObjectPool()->cachedShareableElementDataWithAttributes(attributeVector);
     else
-        m_elementData = ShareableElementData::createWithAttributes(filteredAttributes);
+        m_elementData = ShareableElementData::createWithAttributes(attributeVector);
 
-    // Iterate over the set of attributes we already have on the stack in case
-    // attributeChanged mutates m_elementData.
-    // FIXME: Find a way so we don't have to do this.
-    for (unsigned i = 0; i < filteredAttributes.size(); ++i)
-        attributeChanged(filteredAttributes[i].name(), filteredAttributes[i].value());
+    // Use attributeVector instead of m_elementData because attributeChanged might modify m_elementData.
+    for (unsigned i = 0; i < attributeVector.size(); ++i)
+        attributeChanged(attributeVector[i].name(), attributeVector[i].value());
 }
 
 bool Element::hasAttributes() const
index 9ca4a57..baa9d42 100644 (file)
@@ -378,7 +378,9 @@ public:
     virtual void parseAttribute(const QualifiedName&, const AtomicString&) { }
 
     // Only called by the parser immediately after element construction.
-    void parserSetAttributes(const Vector<Attribute>&, FragmentScriptingPermission);
+    void parserSetAttributes(const Vector<Attribute>&);
+
+    void stripJavaScriptAttributes(Vector<Attribute>&);
 
     const ElementData* elementData() const { return m_elementData.get(); }
     UniqueElementData* ensureUniqueElementData();
@@ -720,6 +722,9 @@ private:
 
     void createRendererIfNeeded();
 
+    bool isJavaScriptAttribute(const Attribute&);
+    bool isJavaScriptURLAttribute(const Attribute&);
+
     RefPtr<ElementData> m_elementData;
 };
     
index 97a71ca..21b3552 100644 (file)
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef FragmentScriptingPermission_h
-#define FragmentScriptingPermission_h
+// FIXME: Move this file to ParserContentPolicy.h.
+
+#ifndef ParserContentPolicy_h
+#define ParserContentPolicy_h
 
 namespace WebCore {
 
-// FIXME: This enum is poorly named.  It is used to remove script contents when
-// generating DocumentFragments for paste in platform/*/Pasteboard.*.
-enum FragmentScriptingPermission {
-    DisallowScriptingAndPluginContentIfNeeded,
+enum ParserContentPolicy {
+    DisallowScriptingAndPluginContent,
     DisallowScriptingContent,
     AllowScriptingContent,
     AllowScriptingContentAndDoNotMarkAlreadyStarted,
 };
 
-static inline bool scriptingContentIsAllowed(FragmentScriptingPermission scriptingPermission) 
+static inline bool scriptingContentIsAllowed(ParserContentPolicy parserContentPolicy) 
+{
+    return parserContentPolicy == AllowScriptingContent || parserContentPolicy == AllowScriptingContentAndDoNotMarkAlreadyStarted;
+}
+
+static inline ParserContentPolicy disallowScriptingContent(ParserContentPolicy parserContentPolicy)
+{
+    if (!scriptingContentIsAllowed(parserContentPolicy))
+        return parserContentPolicy;
+    return DisallowScriptingContent;
+}
+
+static inline bool pluginContentIsAllowed(ParserContentPolicy parserContentPolicy)
 {
-    return scriptingPermission == AllowScriptingContent || scriptingPermission == AllowScriptingContentAndDoNotMarkAlreadyStarted;
+    return parserContentPolicy != DisallowScriptingAndPluginContent;
 }
 
-static inline bool pluginContentIsAllowed(FragmentScriptingPermission scriptingPermission)
+static inline ParserContentPolicy allowPluginContent(ParserContentPolicy parserContentPolicy)
 {
-    return scriptingPermission != DisallowScriptingAndPluginContentIfNeeded;
+    if (pluginContentIsAllowed(parserContentPolicy))
+        return parserContentPolicy;
+    return DisallowScriptingContent;
 }
 
 } // namespace WebCore
 
-#endif // FragmentScriptingPermission_h
+#endif // ParserContentPolicy_h
index 708dc1d..23bb887 100644 (file)
 #include "config.h"
 #include "ScriptableDocumentParser.h"
 
+#include "Document.h"
+#include "Frame.h"
+#include "ScriptController.h"
+#include "Settings.h"
+
 namespace WebCore {
 
-ScriptableDocumentParser::ScriptableDocumentParser(Document* document)
+ScriptableDocumentParser::ScriptableDocumentParser(Document* document, ParserContentPolicy parserContentPolicy)
     : DecodedDataDocumentParser(document)
     , m_wasCreatedByScript(false)
+    , m_parserContentPolicy(parserContentPolicy)
 {
+    if (!pluginContentIsAllowed(m_parserContentPolicy) && (!document->settings() || document->settings()->unsafePluginPastingEnabled()))
+        m_parserContentPolicy = allowPluginContent(m_parserContentPolicy);
 }
 
 };
index b140cf1..39223ce 100644 (file)
@@ -27,6 +27,7 @@
 #define ScriptableDocumentParser_h
 
 #include "DecodedDataDocumentParser.h"
+#include "FragmentScriptingPermission.h"
 #include <wtf/text/TextPosition.h>
 
 namespace WebCore {
@@ -50,14 +51,17 @@ public:
     void setWasCreatedByScript(bool wasCreatedByScript) { m_wasCreatedByScript = wasCreatedByScript; }
     bool wasCreatedByScript() const { return m_wasCreatedByScript; }
 
+    ParserContentPolicy parserContentPolicy() { return m_parserContentPolicy; }
+
 protected:
-    explicit ScriptableDocumentParser(Document*);
+    explicit ScriptableDocumentParser(Document*, ParserContentPolicy = AllowScriptingContent);
 
 private:
     virtual ScriptableDocumentParser* asScriptableDocumentParser() { return this; }
 
     // http://www.whatwg.org/specs/web-apps/current-work/#script-created-parser
     bool m_wasCreatedByScript;
+    ParserContentPolicy m_parserContentPolicy;
 };
 
 }
index 3ffdaae..02cd40a 100644 (file)
@@ -668,16 +668,13 @@ String createMarkup(const Range* range, Vector<Node*>* nodes, EAnnotateForInterc
     return createMarkupInternal(document, range, updatedRange, nodes, shouldAnnotate, convertBlocksToInlines, shouldResolveURLs);
 }
 
-PassRefPtr<DocumentFragment> createFragmentFromMarkup(Document* document, const String& markup, const String& baseURL, FragmentScriptingPermission scriptingPermission)
+PassRefPtr<DocumentFragment> createFragmentFromMarkup(Document* document, const String& markup, const String& baseURL, ParserContentPolicy parserContentPolicy)
 {
     // We use a fake body element here to trick the HTML parser to using the InBody insertion mode.
     RefPtr<HTMLBodyElement> fakeBody = HTMLBodyElement::create(document);
     RefPtr<DocumentFragment> fragment = DocumentFragment::create(document);
 
-    if (scriptingPermission == DisallowScriptingAndPluginContentIfNeeded && (!document->settings() || document->settings()->unsafePluginPastingEnabled()))
-        scriptingPermission = DisallowScriptingContent;
-
-    fragment->parseHTML(markup, fakeBody.get(), scriptingPermission);
+    fragment->parseHTML(markup, fakeBody.get(), parserContentPolicy);
 
     if (!baseURL.isEmpty() && baseURL != blankURL() && baseURL != document->baseURL())
         completeURLs(fragment.get(), baseURL);
@@ -725,7 +722,7 @@ static void trimFragment(DocumentFragment* fragment, Node* nodeBeforeContext, No
 }
 
 PassRefPtr<DocumentFragment> createFragmentFromMarkupWithContext(Document* document, const String& markup, unsigned fragmentStart, unsigned fragmentEnd,
-    const String& baseURL, FragmentScriptingPermission scriptingPermission)
+    const String& baseURL, ParserContentPolicy parserContentPolicy)
 {
     // FIXME: Need to handle the case where the markup already contains these markers.
 
@@ -736,7 +733,7 @@ PassRefPtr<DocumentFragment> createFragmentFromMarkupWithContext(Document* docum
     MarkupAccumulator::appendComment(taggedMarkup, fragmentMarkerTag);
     taggedMarkup.append(markup.substring(fragmentEnd));
 
-    RefPtr<DocumentFragment> taggedFragment = createFragmentFromMarkup(document, taggedMarkup.toString(), baseURL, scriptingPermission);
+    RefPtr<DocumentFragment> taggedFragment = createFragmentFromMarkup(document, taggedMarkup.toString(), baseURL, parserContentPolicy);
     RefPtr<Document> taggedDocument = Document::create(0, KURL());
     taggedDocument->setContextFeatures(document->contextFeatures());
     taggedDocument->takeAllChildrenFrom(taggedFragment.get());
@@ -986,7 +983,7 @@ String urlToMarkup(const KURL& url, const String& title)
     return markup.toString();
 }
 
-PassRefPtr<DocumentFragment> createFragmentForInnerOuterHTML(const String& markup, Element* contextElement, FragmentScriptingPermission scriptingPermission, ExceptionCode& ec)
+PassRefPtr<DocumentFragment> createFragmentForInnerOuterHTML(const String& markup, Element* contextElement, ParserContentPolicy parserContentPolicy, ExceptionCode& ec)
 {
     Document* document = contextElement->document();
 #if ENABLE(TEMPLATE_ELEMENT)
@@ -996,11 +993,11 @@ PassRefPtr<DocumentFragment> createFragmentForInnerOuterHTML(const String& marku
     RefPtr<DocumentFragment> fragment = DocumentFragment::create(document);
 
     if (document->isHTMLDocument()) {
-        fragment->parseHTML(markup, contextElement, scriptingPermission);
+        fragment->parseHTML(markup, contextElement, parserContentPolicy);
         return fragment;
     }
 
-    bool wasValid = fragment->parseXML(markup, contextElement, scriptingPermission);
+    bool wasValid = fragment->parseXML(markup, contextElement, parserContentPolicy);
     if (!wasValid) {
         ec = SYNTAX_ERR;
         return 0;
@@ -1043,7 +1040,7 @@ static inline void removeElementPreservingChildren(PassRefPtr<DocumentFragment>
     fragment->removeChild(element, ASSERT_NO_EXCEPTION);
 }
 
-PassRefPtr<DocumentFragment> createContextualFragment(const String& markup, HTMLElement* element, FragmentScriptingPermission scriptingPermission, ExceptionCode& ec)
+PassRefPtr<DocumentFragment> createContextualFragment(const String& markup, HTMLElement* element, ParserContentPolicy parserContentPolicy, ExceptionCode& ec)
 {
     ASSERT(element);
     if (element->ieForbidsInsertHTML()) {
@@ -1057,7 +1054,7 @@ PassRefPtr<DocumentFragment> createContextualFragment(const String& markup, HTML
         return 0;
     }
 
-    RefPtr<DocumentFragment> fragment = createFragmentForInnerOuterHTML(markup, element, scriptingPermission, ec);
+    RefPtr<DocumentFragment> fragment = createFragmentForInnerOuterHTML(markup, element, parserContentPolicy, ec);
     if (!fragment)
         return 0;
 
index 83350f1..6c0d2d7 100644 (file)
@@ -49,12 +49,12 @@ enum EChildrenOnly { IncludeNode, ChildrenOnly };
 enum EAbsoluteURLs { DoNotResolveURLs, ResolveAllURLs, ResolveNonLocalURLs };
 
 PassRefPtr<DocumentFragment> createFragmentFromText(Range* context, const String& text);
-PassRefPtr<DocumentFragment> createFragmentFromMarkup(Document*, const String& markup, const String& baseURL, FragmentScriptingPermission = AllowScriptingContent);
-PassRefPtr<DocumentFragment> createFragmentFromMarkupWithContext(Document*, const String& markup, unsigned fragmentStart, unsigned fragmentEnd, const String& baseURL, FragmentScriptingPermission);
+PassRefPtr<DocumentFragment> createFragmentFromMarkup(Document*, const String& markup, const String& baseURL, ParserContentPolicy = AllowScriptingContent);
+PassRefPtr<DocumentFragment> createFragmentFromMarkupWithContext(Document*, const String& markup, unsigned fragmentStart, unsigned fragmentEnd, const String& baseURL, ParserContentPolicy);
 PassRefPtr<DocumentFragment> createFragmentFromNodes(Document*, const Vector<Node*>&);
-PassRefPtr<DocumentFragment> createFragmentForInnerOuterHTML(const String&, Element*, FragmentScriptingPermission, ExceptionCode&);
+PassRefPtr<DocumentFragment> createFragmentForInnerOuterHTML(const String&, Element*, ParserContentPolicy, ExceptionCode&);
 PassRefPtr<DocumentFragment> createFragmentForTransformToFragment(const String&, const String& sourceMIMEType, Document* outputDoc);
-PassRefPtr<DocumentFragment> createContextualFragment(const String&, HTMLElement*, FragmentScriptingPermission, ExceptionCode&);
+PassRefPtr<DocumentFragment> createContextualFragment(const String&, HTMLElement*, ParserContentPolicy, ExceptionCode&);
 
 bool isPlainTextMarkup(Node*);
 
index 4051628..465c4f5 100644 (file)
@@ -245,7 +245,7 @@ void HTMLAnchorElement::accessKeyAction(bool sendMouseEvents)
 
 bool HTMLAnchorElement::isURLAttribute(const Attribute& attribute) const
 {
-    return attribute.name() == hrefAttr || HTMLElement::isURLAttribute(attribute);
+    return attribute.name().localName() == hrefAttr || HTMLElement::isURLAttribute(attribute);
 }
 
 bool HTMLAnchorElement::canStartSelection() const
index bb5bc8c..9056dd6 100644 (file)
@@ -69,7 +69,7 @@ void HTMLBaseElement::removedFrom(ContainerNode* insertionPoint)
 
 bool HTMLBaseElement::isURLAttribute(const Attribute& attribute) const
 {
-    return attribute.name() == hrefAttr || HTMLElement::isURLAttribute(attribute);
+    return attribute.name().localName() == hrefAttr || HTMLElement::isURLAttribute(attribute);
 }
 
 String HTMLBaseElement::target() const
index ac88213..e4cf89e 100644 (file)
@@ -965,11 +965,10 @@ void HTMLElement::adjustDirectionalityIfNeededAfterChildrenChanged(Node* beforeC
 bool HTMLElement::isURLAttribute(const Attribute& attribute) const
 {
 #if ENABLE(MICRODATA)
-    return attribute.name() == itemidAttr;
-#else
-    UNUSED_PARAM(attribute);
-    return false;
+    if (attribute.name() == itemidAttr)
+        return true;
 #endif
+    return StyledElement::isURLAttribute(attribute);
 }
 
 #if ENABLE(MICRODATA)
index f82e602..4f0a939 100644 (file)
@@ -421,7 +421,7 @@ void HTMLLinkElement::startLoadingDynamicSheet()
 
 bool HTMLLinkElement::isURLAttribute(const Attribute& attribute) const
 {
-    return attribute.name() == hrefAttr || HTMLElement::isURLAttribute(attribute);
+    return attribute.name().localName() == hrefAttr || HTMLElement::isURLAttribute(attribute);
 }
 
 KURL HTMLLinkElement::href() const
index 453e383..ec51014 100644 (file)
@@ -56,6 +56,13 @@ namespace WebCore {
 
 using namespace HTMLNames;
 
+static inline void setAttributes(Element* element, AtomicHTMLToken* token, ParserContentPolicy parserContentPolicy)
+{
+    if (!scriptingContentIsAllowed(parserContentPolicy))
+        element->stripJavaScriptAttributes(token->attributes());
+    element->parserSetAttributes(token->attributes());
+}
+
 static bool hasImpliedEndTag(const HTMLStackItem* item)
 {
     return item->hasTagName(ddTag)
@@ -134,10 +141,10 @@ void HTMLConstructionSite::executeQueuedTasks()
     // We might be detached now.
 }
 
-HTMLConstructionSite::HTMLConstructionSite(Document* document, unsigned maximumDOMTreeDepth)
+HTMLConstructionSite::HTMLConstructionSite(Document* document, ParserContentPolicy parserContentPolicy, unsigned maximumDOMTreeDepth)
     : m_document(document)
     , m_attachmentRoot(document)
-    , m_fragmentScriptingPermission(AllowScriptingContent)
+    , m_parserContentPolicy(parserContentPolicy)
     , m_isParsingFragment(false)
     , m_redirectAttachToFosterParent(false)
     , m_maximumDOMTreeDepth(maximumDOMTreeDepth)
@@ -146,10 +153,10 @@ HTMLConstructionSite::HTMLConstructionSite(Document* document, unsigned maximumD
     ASSERT(m_document->isHTMLDocument() || m_document->isXHTMLDocument());
 }
 
-HTMLConstructionSite::HTMLConstructionSite(DocumentFragment* fragment, FragmentScriptingPermission scriptingPermission, unsigned maximumDOMTreeDepth)
+HTMLConstructionSite::HTMLConstructionSite(DocumentFragment* fragment, ParserContentPolicy parserContentPolicy, unsigned maximumDOMTreeDepth)
     : m_document(fragment->document())
     , m_attachmentRoot(fragment)
-    , m_fragmentScriptingPermission(scriptingPermission)
+    , m_parserContentPolicy(parserContentPolicy)
     , m_isParsingFragment(true)
     , m_redirectAttachToFosterParent(false)
     , m_maximumDOMTreeDepth(maximumDOMTreeDepth)
@@ -190,7 +197,7 @@ void HTMLConstructionSite::dispatchDocumentElementAvailableIfNeeded()
 void HTMLConstructionSite::insertHTMLHtmlStartTagBeforeHTML(AtomicHTMLToken* token)
 {
     RefPtr<HTMLHtmlElement> element = HTMLHtmlElement::create(m_document);
-    element->parserSetAttributes(token->attributes(), m_fragmentScriptingPermission);
+    setAttributes(element.get(), token, m_parserContentPolicy);
     attachLater(m_attachmentRoot, element);
     m_openElements.pushHTMLHtmlElement(HTMLStackItem::create(element, token));
 
@@ -440,12 +447,12 @@ void HTMLConstructionSite::insertScriptElement(AtomicHTMLToken* token)
     // For createContextualFragment, the specifications say to mark it parser-inserted and already-started and later unmark them.
     // However, we short circuit that logic to avoid the subtree traversal to find script elements since scripts can never see
     // those flags or effects thereof.
-    const bool parserInserted = m_fragmentScriptingPermission != AllowScriptingContentAndDoNotMarkAlreadyStarted;
+    const bool parserInserted = m_parserContentPolicy != AllowScriptingContentAndDoNotMarkAlreadyStarted;
     const bool alreadyStarted = m_isParsingFragment && parserInserted;
     RefPtr<HTMLScriptElement> element = HTMLScriptElement::create(scriptTag, ownerDocumentForCurrentNode(), parserInserted, alreadyStarted);
-    if (scriptingContentIsAllowed(m_fragmentScriptingPermission))
-        element->parserSetAttributes(token->attributes(), m_fragmentScriptingPermission);
-    attachLater(currentNode(), element);
+    setAttributes(element.get(), token, m_parserContentPolicy);
+    if (scriptingContentIsAllowed(m_parserContentPolicy))
+        attachLater(currentNode(), element);
     m_openElements.push(HTMLStackItem::create(element.release(), token));
 }
 
@@ -511,7 +518,7 @@ PassRefPtr<Element> HTMLConstructionSite::createElement(AtomicHTMLToken* token,
 {
     QualifiedName tagName(nullAtom, token->name(), namespaceURI);
     RefPtr<Element> element = ownerDocumentForCurrentNode()->createElement(tagName, true);
-    element->parserSetAttributes(token->attributes(), m_fragmentScriptingPermission);
+    setAttributes(element.get(), token, m_parserContentPolicy);
     return element.release();
 }
 
@@ -531,7 +538,7 @@ PassRefPtr<Element> HTMLConstructionSite::createHTMLElement(AtomicHTMLToken* tok
     // have to pass the current form element.  We should rework form association
     // to occur after construction to allow better code sharing here.
     RefPtr<Element> element = HTMLElementFactory::createHTMLElement(tagName, ownerDocumentForCurrentNode(), form(), true);
-    element->parserSetAttributes(token->attributes(), m_fragmentScriptingPermission);
+    setAttributes(element.get(), token, m_parserContentPolicy);
     ASSERT(element->isHTMLElement());
     return element.release();
 }
index 1cc9c80..8a95165 100644 (file)
@@ -72,8 +72,8 @@ class HTMLFormElement;
 class HTMLConstructionSite {
     WTF_MAKE_NONCOPYABLE(HTMLConstructionSite);
 public:
-    HTMLConstructionSite(Document*, unsigned maximumDOMTreeDepth);
-    HTMLConstructionSite(DocumentFragment*, FragmentScriptingPermission, unsigned maximumDOMTreeDepth);
+    HTMLConstructionSite(Document*, ParserContentPolicy, unsigned maximumDOMTreeDepth);
+    HTMLConstructionSite(DocumentFragment*, ParserContentPolicy, unsigned maximumDOMTreeDepth);
     ~HTMLConstructionSite();
 
     void detach();
@@ -131,6 +131,8 @@ public:
     HTMLFormElement* form() const { return m_form.get(); }
     PassRefPtr<HTMLFormElement> takeForm();
 
+    ParserContentPolicy parserContentPolicy() { return m_parserContentPolicy; }
+
     class RedirectToFosterParentGuard {
         WTF_MAKE_NONCOPYABLE(RedirectToFosterParentGuard);
     public:
@@ -183,7 +185,7 @@ private:
 
     AttachmentQueue m_attachmentQueue;
 
-    FragmentScriptingPermission m_fragmentScriptingPermission;
+    ParserContentPolicy m_parserContentPolicy;
     bool m_isParsingFragment;
 
     // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#parsing-main-intable
index 9edb14b..8e919d0 100644 (file)
@@ -83,7 +83,7 @@ HTMLDocumentParser::HTMLDocumentParser(HTMLDocument* document, bool reportErrors
     , m_token(m_options.useThreading ? nullptr : adoptPtr(new HTMLToken))
     , m_tokenizer(m_options.useThreading ? nullptr : HTMLTokenizer::create(m_options))
     , m_scriptRunner(HTMLScriptRunner::create(document, this))
-    , m_treeBuilder(HTMLTreeBuilder::create(this, document, reportErrors, m_options))
+    , m_treeBuilder(HTMLTreeBuilder::create(this, document, parserContentPolicy(), reportErrors, m_options))
     , m_parserScheduler(HTMLParserScheduler::create(this))
     , m_xssAuditorDelegate(document)
 #if ENABLE(THREADED_HTML_PARSER)
@@ -100,12 +100,12 @@ HTMLDocumentParser::HTMLDocumentParser(HTMLDocument* document, bool reportErrors
 
 // FIXME: Member variables should be grouped into self-initializing structs to
 // minimize code duplication between these constructors.
-HTMLDocumentParser::HTMLDocumentParser(DocumentFragment* fragment, Element* contextElement, FragmentScriptingPermission scriptingPermission)
-    : ScriptableDocumentParser(fragment->document())
+HTMLDocumentParser::HTMLDocumentParser(DocumentFragment* fragment, Element* contextElement, ParserContentPolicy parserContentPolicy)
+    : ScriptableDocumentParser(fragment->document(), parserContentPolicy)
     , m_options(fragment->document())
     , m_token(adoptPtr(new HTMLToken))
     , m_tokenizer(HTMLTokenizer::create(m_options))
-    , m_treeBuilder(HTMLTreeBuilder::create(this, fragment, contextElement, scriptingPermission, m_options))
+    , m_treeBuilder(HTMLTreeBuilder::create(this, fragment, contextElement, this->parserContentPolicy(), m_options))
     , m_xssAuditorDelegate(fragment->document())
 #if ENABLE(THREADED_HTML_PARSER)
     , m_weakFactory(this)
@@ -261,6 +261,8 @@ void HTMLDocumentParser::resumeParsingAfterYield()
 
 void HTMLDocumentParser::runScriptsForPausedTreeBuilder()
 {
+    ASSERT(scriptingContentIsAllowed(parserContentPolicy()));
+
     TextPosition scriptStartPosition = TextPosition::belowRangePosition();
     RefPtr<Element> scriptElement = m_treeBuilder->takeScriptToProcess(scriptStartPosition);
     // We will not have a scriptRunner when parsing a DocumentFragment.
@@ -952,9 +954,9 @@ void HTMLDocumentParser::executeScriptsWaitingForStylesheets()
         resumeParsingAfterScriptExecution();
 }
 
-void HTMLDocumentParser::parseDocumentFragment(const String& source, DocumentFragment* fragment, Element* contextElement, FragmentScriptingPermission scriptingPermission)
+void HTMLDocumentParser::parseDocumentFragment(const String& source, DocumentFragment* fragment, Element* contextElement, ParserContentPolicy parserContentPolicy)
 {
-    RefPtr<HTMLDocumentParser> parser = HTMLDocumentParser::create(fragment, contextElement, scriptingPermission);
+    RefPtr<HTMLDocumentParser> parser = HTMLDocumentParser::create(fragment, contextElement, parserContentPolicy);
     parser->insert(source); // Use insert() so that the parser will not yield.
     parser->finish();
     ASSERT(!parser->processingData()); // Make sure we're done. <rdar://problem/3963151>
index 1daeef3..4044ded 100644 (file)
@@ -76,7 +76,7 @@ public:
     // Exposed for HTMLParserScheduler
     void resumeParsingAfterYield();
 
-    static void parseDocumentFragment(const String&, DocumentFragment*, Element* contextElement, FragmentScriptingPermission = AllowScriptingContent);
+    static void parseDocumentFragment(const String&, DocumentFragment*, Element* contextElement, ParserContentPolicy = AllowScriptingContent);
 
     HTMLTokenizer* tokenizer() const { return m_tokenizer.get(); }
 
@@ -105,16 +105,16 @@ protected:
     virtual void finish() OVERRIDE;
 
     HTMLDocumentParser(HTMLDocument*, bool reportErrors);
-    HTMLDocumentParser(DocumentFragment*, Element* contextElement, FragmentScriptingPermission);
+    HTMLDocumentParser(DocumentFragment*, Element* contextElement, ParserContentPolicy);
 
     HTMLTreeBuilder* treeBuilder() const { return m_treeBuilder.get(); }
 
     void forcePlaintextForTextDocument();
 
 private:
-    static PassRefPtr<HTMLDocumentParser> create(DocumentFragment* fragment, Element* contextElement, FragmentScriptingPermission permission)
+    static PassRefPtr<HTMLDocumentParser> create(DocumentFragment* fragment, Element* contextElement, ParserContentPolicy parserContentPolicy)
     {
-        return adoptRef(new HTMLDocumentParser(fragment, contextElement, permission));
+        return adoptRef(new HTMLDocumentParser(fragment, contextElement, parserContentPolicy));
     }
 
     // DocumentParser
index dca8ae6..30272dd 100644 (file)
@@ -263,12 +263,12 @@ private:
 };
 
 
-HTMLTreeBuilder::HTMLTreeBuilder(HTMLDocumentParser* parser, HTMLDocument* document, bool, const HTMLParserOptions& options)
+HTMLTreeBuilder::HTMLTreeBuilder(HTMLDocumentParser* parser, HTMLDocument* document, ParserContentPolicy parserContentPolicy, bool, const HTMLParserOptions& options)
     : m_framesetOk(true)
 #ifndef NDEBUG
     , m_isAttached(true)
 #endif
-    , m_tree(document, options.maximumDOMTreeDepth)
+    , m_tree(document, parserContentPolicy, options.maximumDOMTreeDepth)
     , m_insertionMode(InitialMode)
     , m_originalInsertionMode(InitialMode)
     , m_shouldSkipLeadingNewline(false)
@@ -280,13 +280,13 @@ HTMLTreeBuilder::HTMLTreeBuilder(HTMLDocumentParser* parser, HTMLDocument* docum
 
 // FIXME: Member variables should be grouped into self-initializing structs to
 // minimize code duplication between these constructors.
-HTMLTreeBuilder::HTMLTreeBuilder(HTMLDocumentParser* parser, DocumentFragment* fragment, Element* contextElement, FragmentScriptingPermission scriptingPermission, const HTMLParserOptions& options)
+HTMLTreeBuilder::HTMLTreeBuilder(HTMLDocumentParser* parser, DocumentFragment* fragment, Element* contextElement, ParserContentPolicy parserContentPolicy, const HTMLParserOptions& options)
     : m_framesetOk(true)
 #ifndef NDEBUG
     , m_isAttached(true)
 #endif
-    , m_fragmentContext(fragment, contextElement, scriptingPermission)
-    , m_tree(fragment, scriptingPermission, options.maximumDOMTreeDepth)
+    , m_fragmentContext(fragment, contextElement)
+    , m_tree(fragment, parserContentPolicy, options.maximumDOMTreeDepth)
     , m_insertionMode(InitialMode)
     , m_originalInsertionMode(InitialMode)
     , m_shouldSkipLeadingNewline(false)
@@ -333,14 +333,12 @@ void HTMLTreeBuilder::detach()
 HTMLTreeBuilder::FragmentParsingContext::FragmentParsingContext()
     : m_fragment(0)
     , m_contextElement(0)
-    , m_scriptingPermission(AllowScriptingContent)
 {
 }
 
-HTMLTreeBuilder::FragmentParsingContext::FragmentParsingContext(DocumentFragment* fragment, Element* contextElement, FragmentScriptingPermission scriptingPermission)
+HTMLTreeBuilder::FragmentParsingContext::FragmentParsingContext(DocumentFragment* fragment, Element* contextElement)
     : m_fragment(fragment)
     , m_contextElement(contextElement)
-    , m_scriptingPermission(scriptingPermission)
 {
     ASSERT(!fragment->hasChildNodes());
 }
@@ -790,7 +788,7 @@ void HTMLTreeBuilder::processStartTagForInBody(AtomicHTMLToken* token)
     if (token->name() == appletTag
         || token->name() == embedTag
         || token->name() == objectTag) {
-        if (isParsingFragment() && !pluginContentIsAllowed(m_fragmentContext.scriptingPermission()))
+        if (!pluginContentIsAllowed(m_tree.parserContentPolicy()))
             return;
     }
     if (token->name() == appletTag
@@ -2180,10 +2178,9 @@ void HTMLTreeBuilder::processEndTag(AtomicHTMLToken* token)
         if (token->name() == scriptTag) {
             // Pause ourselves so that parsing stops until the script can be processed by the caller.
             ASSERT(m_tree.currentStackItem()->hasTagName(scriptTag));
-            m_scriptToProcess = m_tree.currentElement();
+            if (scriptingContentIsAllowed(m_tree.parserContentPolicy()))
+                m_scriptToProcess = m_tree.currentElement();
             m_tree.openElements()->pop();
-            if (isParsingFragment() && !scriptingContentIsAllowed(m_fragmentContext.scriptingPermission()))
-                m_scriptToProcess->removeChildren();
             setInsertionMode(m_originalInsertionMode);
 
             if (m_parser->tokenizer()) {
index e48a196..f6b2e5b 100644 (file)
@@ -58,13 +58,13 @@ class HTMLDocumentParser;
 class HTMLTreeBuilder {
     WTF_MAKE_NONCOPYABLE(HTMLTreeBuilder); WTF_MAKE_FAST_ALLOCATED;
 public:
-    static PassOwnPtr<HTMLTreeBuilder> create(HTMLDocumentParser* parser, HTMLDocument* document, bool reportErrors, const HTMLParserOptions& options)
+    static PassOwnPtr<HTMLTreeBuilder> create(HTMLDocumentParser* parser, HTMLDocument* document, ParserContentPolicy parserContentPolicy, bool reportErrors, const HTMLParserOptions& options)
     {
-        return adoptPtr(new HTMLTreeBuilder(parser, document, reportErrors, options));
+        return adoptPtr(new HTMLTreeBuilder(parser, document, parserContentPolicy, reportErrors, options));
     }
-    static PassOwnPtr<HTMLTreeBuilder> create(HTMLDocumentParser* parser, DocumentFragment* fragment, Element* contextElement, FragmentScriptingPermission scriptingPermission, const HTMLParserOptions& options)
+    static PassOwnPtr<HTMLTreeBuilder> create(HTMLDocumentParser* parser, DocumentFragment* fragment, Element* contextElement, ParserContentPolicy parserContentPolicy, const HTMLParserOptions& options)
     {
-        return adoptPtr(new HTMLTreeBuilder(parser, fragment, contextElement, scriptingPermission, options));
+        return adoptPtr(new HTMLTreeBuilder(parser, fragment, contextElement, parserContentPolicy, options));
     }
     ~HTMLTreeBuilder();
 
@@ -121,8 +121,8 @@ private:
         AfterAfterFramesetMode,
     };
 
-    HTMLTreeBuilder(HTMLDocumentParser*, HTMLDocument*, bool reportErrors, const HTMLParserOptions&);
-    HTMLTreeBuilder(HTMLDocumentParser*, DocumentFragment*, Element* contextElement, FragmentScriptingPermission, const HTMLParserOptions&);
+    HTMLTreeBuilder(HTMLDocumentParser*, HTMLDocument*, ParserContentPolicy, bool reportErrors, const HTMLParserOptions&);
+    HTMLTreeBuilder(HTMLDocumentParser*, DocumentFragment*, Element* contextElement, ParserContentPolicy, const HTMLParserOptions&);
 
     void processToken(AtomicHTMLToken*);
 
@@ -204,19 +204,15 @@ private:
         WTF_MAKE_NONCOPYABLE(FragmentParsingContext);
     public:
         FragmentParsingContext();
-        FragmentParsingContext(DocumentFragment*, Element* contextElement, FragmentScriptingPermission);
+        FragmentParsingContext(DocumentFragment*, Element* contextElement);
         ~FragmentParsingContext();
 
         DocumentFragment* fragment() const { return m_fragment; }
         Element* contextElement() const { ASSERT(m_fragment); return m_contextElement; }
-        FragmentScriptingPermission scriptingPermission() const { ASSERT(m_fragment); return m_scriptingPermission; }
 
     private:
         DocumentFragment* m_fragment;
         Element* m_contextElement;
-
-        // DisallowScriptingContent causes the Parser to remove children from <script> tags (so javascript doesn't show up in pastes).
-        FragmentScriptingPermission m_scriptingPermission;
     };
 
     bool m_framesetOk;
index de29274..608e24d 100644 (file)
@@ -97,7 +97,7 @@ PassRefPtr<DocumentFragment> Pasteboard::documentFragment(Frame* frame, PassRefP
     RefPtr<DocumentFragment> fragment;
     if (!html.isEmpty()) {
         String url = BlackBerry::Platform::Clipboard::readURL();
-        if (fragment = createFragmentFromMarkup(frame->document(), html, url, DisallowScriptingAndPluginContentIfNeeded))
+        if (fragment = createFragmentFromMarkup(frame->document(), html, url, DisallowScriptingAndPluginContent))
             return fragment.release();
     }
 
index fbde5ed..07f9fdd 100644 (file)
@@ -154,7 +154,7 @@ PassRefPtr<DocumentFragment> DragData::asFragment(Frame* frame, PassRefPtr<Range
         String html;
         KURL baseURL;
         m_platformDragData->htmlAndBaseURL(html, baseURL);
-        if (RefPtr<DocumentFragment> fragment = createFragmentFromMarkup(frame->document(), html, baseURL, DisallowScriptingAndPluginContentIfNeeded))
+        if (RefPtr<DocumentFragment> fragment = createFragmentFromMarkup(frame->document(), html, baseURL, DisallowScriptingAndPluginContent))
             return fragment.release();
     }
 
index e5353a4..df1c6e5 100644 (file)
@@ -187,7 +187,7 @@ PassRefPtr<DocumentFragment> Pasteboard::documentFragment(Frame* frame, PassRefP
         WebKit::WebURL url;
         WebKit::WebString markup = WebKit::Platform::current()->clipboard()->readHTML(buffer, &url, &fragmentStart, &fragmentEnd);
         if (!markup.isEmpty()) {
-            if (RefPtr<DocumentFragment> fragment = createFragmentFromMarkupWithContext(frame->document(), markup, fragmentStart, fragmentEnd, KURL(url), DisallowScriptingAndPluginContentIfNeeded))
+            if (RefPtr<DocumentFragment> fragment = createFragmentFromMarkupWithContext(frame->document(), markup, fragmentStart, fragmentEnd, KURL(url), DisallowScriptingAndPluginContent))
                 return fragment.release();
         }
     }
index d42554f..cd62054 100644 (file)
@@ -172,7 +172,7 @@ PassRefPtr<DocumentFragment> Pasteboard::documentFragment(Frame* frame, PassRefP
     chosePlainText = false;
 
     if (dataObject->hasMarkup()) {
-        RefPtr<DocumentFragment> fragment = createFragmentFromMarkup(frame->document(), dataObject->markup(), "", DisallowScriptingAndPluginContentIfNeeded);
+        RefPtr<DocumentFragment> fragment = createFragmentFromMarkup(frame->document(), dataObject->markup(), "", DisallowScriptingAndPluginContent);
         if (fragment)
             return fragment.release();
     }
index 6af0162..2ebec20 100644 (file)
@@ -483,7 +483,7 @@ PassRefPtr<DocumentFragment> Pasteboard::documentFragment(Frame* frame, PassRefP
                     if (DocumentLoader* loader = frame->loader()->documentLoader())
                         loader->addAllArchiveResources(coreArchive.get());
 
-                    fragment = createFragmentFromMarkup(frame->document(), markupString, mainResource->url(), DisallowScriptingAndPluginContentIfNeeded);
+                    fragment = createFragmentFromMarkup(frame->document(), markupString, mainResource->url(), DisallowScriptingAndPluginContent);
                     [markupString release];
                 } else if (MIMETypeRegistry::isSupportedImageMIMEType(MIMEType))
                    fragment = documentFragmentWithImageResource(frame, mainResource);                    
@@ -522,7 +522,7 @@ PassRefPtr<DocumentFragment> Pasteboard::documentFragment(Frame* frame, PassRefP
             }
         }
         if ([HTMLString length] != 0 &&
-            (fragment = createFragmentFromMarkup(frame->document(), HTMLString, "", DisallowScriptingAndPluginContentIfNeeded)))
+            (fragment = createFragmentFromMarkup(frame->document(), HTMLString, "", DisallowScriptingAndPluginContent)))
             return fragment.release();
     }
 
index 95992d7..1f3340b 100644 (file)
@@ -137,7 +137,7 @@ String DragData::asURL(Frame*, FilenameConversionPolicy filenamePolicy, String*)
 PassRefPtr<DocumentFragment> DragData::asFragment(Frame* frame, PassRefPtr<Range>, bool, bool&) const
 {
     if (m_platformDragData && m_platformDragData->hasHtml())
-        return createFragmentFromMarkup(frame->document(), m_platformDragData->html(), "", DisallowScriptingAndPluginContentIfNeeded);
+        return createFragmentFromMarkup(frame->document(), m_platformDragData->html(), "", DisallowScriptingAndPluginContent);
 
     return 0;
 }
index 547b69a..08e97c7 100644 (file)
@@ -112,7 +112,7 @@ PassRefPtr<DocumentFragment> Pasteboard::documentFragment(Frame* frame, PassRefP
     if (mimeData->hasHtml()) {
         QString html = mimeData->html();
         if (!html.isEmpty()) {
-            RefPtr<DocumentFragment> fragment = createFragmentFromMarkup(frame->document(), html, "", DisallowScriptingAndPluginContentIfNeeded);
+            RefPtr<DocumentFragment> fragment = createFragmentFromMarkup(frame->document(), html, "", DisallowScriptingAndPluginContent);
             if (fragment)
                 return fragment.release();
         }
index 64ed507..3b71067 100644 (file)
@@ -641,7 +641,7 @@ PassRefPtr<DocumentFragment> fragmentFromCFHTML(Document* doc, const String& cfh
     }
 
     String markup = extractMarkupFromCFHTML(cfhtml);
-    return createFragmentFromMarkup(doc, markup, srcURL, DisallowScriptingAndPluginContentIfNeeded);
+    return createFragmentFromMarkup(doc, markup, srcURL, DisallowScriptingAndPluginContent);
 }
 
 PassRefPtr<DocumentFragment> fragmentFromHTML(Document* doc, IDataObject* data) 
@@ -658,7 +658,7 @@ PassRefPtr<DocumentFragment> fragmentFromHTML(Document* doc, IDataObject* data)
     String html = getTextHTML(data);
     String srcURL;
     if (!html.isEmpty())
-        return createFragmentFromMarkup(doc, html, srcURL, DisallowScriptingAndPluginContentIfNeeded);
+        return createFragmentFromMarkup(doc, html, srcURL, DisallowScriptingAndPluginContent);
 
     return 0;
 }
@@ -676,7 +676,7 @@ PassRefPtr<DocumentFragment> fragmentFromHTML(Document* document, const DragData
 
     String srcURL;
     if (getDataMapItem(data, texthtmlFormat(), stringData))
-        return createFragmentFromMarkup(document, stringData, srcURL, DisallowScriptingAndPluginContentIfNeeded);
+        return createFragmentFromMarkup(document, stringData, srcURL, DisallowScriptingAndPluginContent);
 
     return 0;
 }
index 956a327..d0cdc0a 100644 (file)
@@ -99,7 +99,7 @@ PassRefPtr<DocumentFragment> Pasteboard::documentFragment(Frame* frame, PassRefP
             wxHTMLDataObject data;
             wxTheClipboard->GetData(data);
             chosePlainText = false;
-            fragment = createFragmentFromMarkup(frame->document(), data.GetHTML(), "", DisallowScriptingAndPluginContentIfNeeded);
+            fragment = createFragmentFromMarkup(frame->document(), data.GetHTML(), "", DisallowScriptingAndPluginContent);
         } else
 #endif
         {
index 4b8631d..7e70933 100644 (file)
@@ -50,6 +50,8 @@
 
 namespace WebCore {
 
+using namespace HTMLNames;
+
 // Animated property definitions
 DEFINE_ANIMATED_STRING(SVGAElement, SVGNames::targetAttr, SVGTarget, svgTarget)
 DEFINE_ANIMATED_STRING(SVGAElement, XLinkNames::hrefAttr, Href, href)
@@ -206,6 +208,11 @@ bool SVGAElement::isFocusable() const
     return SVGElement::isFocusable();
 }
 
+bool SVGAElement::isURLAttribute(const Attribute& attribute) const
+{
+    return attribute.name().localName() == hrefAttr || SVGStyledTransformableElement::isURLAttribute(attribute);
+}
+
 bool SVGAElement::isMouseFocusable() const
 {
     return false;
index 4c50987..4a315dc 100644 (file)
@@ -60,6 +60,7 @@ private:
     virtual bool isMouseFocusable() const;
     virtual bool isKeyboardFocusable(KeyboardEvent*) const;
     virtual bool isFocusable() const;
+    virtual bool isURLAttribute(const Attribute&) const;
 
     virtual bool childShouldCreateRenderer(const NodeRenderingContext&) const;
 
index ec3a270..61b5c0a 100644 (file)
@@ -93,7 +93,7 @@ static inline PassRefPtr<Element> createXHTMLParserErrorHeader(Document* doc, co
 
     Vector<Attribute> reportAttributes;
     reportAttributes.append(Attribute(styleAttr, "display: block; white-space: pre; border: 2px solid #c77; padding: 0 1em 0 1em; margin: 1em; background-color: #fdd; color: black"));
-    reportElement->parserSetAttributes(reportAttributes, DisallowScriptingContent);
+    reportElement->parserSetAttributes(reportAttributes);
 
     RefPtr<Element> h3 = doc->createElement(h3Tag, true);
     reportElement->parserAppendChild(h3.get());
@@ -102,7 +102,7 @@ static inline PassRefPtr<Element> createXHTMLParserErrorHeader(Document* doc, co
     RefPtr<Element> fixed = doc->createElement(divTag, true);
     Vector<Attribute> fixedAttributes;
     fixedAttributes.append(Attribute(styleAttr, "font-family:monospace;font-size:12px"));
-    fixed->parserSetAttributes(fixedAttributes, DisallowScriptingContent);
+    fixed->parserSetAttributes(fixedAttributes);
     reportElement->parserAppendChild(fixed.get());
 
     fixed->parserAppendChild(doc->createTextNode(errorMessages));
@@ -161,7 +161,7 @@ void XMLErrors::insertErrorMessageBlock()
         Vector<Attribute> attributes;
         attributes.append(Attribute(styleAttr, "white-space: normal"));
         RefPtr<Element> paragraph = m_document->createElement(pTag, true);
-        paragraph->parserSetAttributes(attributes, DisallowScriptingContent);
+        paragraph->parserSetAttributes(attributes);
         paragraph->parserAppendChild(m_document->createTextNode("This document was created as the result of an XSL transformation. The line and column numbers given are from the transformed result."));
         reportElement->parserAppendChild(paragraph.release());
     }
index 9e95a54..7f2b17a 100644 (file)
@@ -286,7 +286,7 @@ void XMLDocumentParser::pauseParsing()
     m_parserPaused = true;
 }
 
-bool XMLDocumentParser::parseDocumentFragment(const String& chunk, DocumentFragment* fragment, Element* contextElement, FragmentScriptingPermission scriptingPermission)
+bool XMLDocumentParser::parseDocumentFragment(const String& chunk, DocumentFragment* fragment, Element* contextElement, ParserContentPolicy parserContentPolicy)
 {
     if (!chunk.length())
         return true;
@@ -299,7 +299,7 @@ bool XMLDocumentParser::parseDocumentFragment(const String& chunk, DocumentFragm
         return true;
     }
 
-    RefPtr<XMLDocumentParser> parser = XMLDocumentParser::create(fragment, contextElement, scriptingPermission);
+    RefPtr<XMLDocumentParser> parser = XMLDocumentParser::create(fragment, contextElement, parserContentPolicy);
     bool wellFormed = parser->appendFragmentSource(chunk);
     // Do not call finish().  Current finish() and doEnd() implementations touch the main Document/loader
     // and can cause crashes in the fragment case.
index 3d7280c..aa464e0 100644 (file)
@@ -79,9 +79,9 @@ class Text;
         {
             return adoptRef(new XMLDocumentParser(document, view));
         }
-        static PassRefPtr<XMLDocumentParser> create(DocumentFragment* fragment, Element* element, FragmentScriptingPermission permission)
+        static PassRefPtr<XMLDocumentParser> create(DocumentFragment* fragment, Element* element, ParserContentPolicy parserContentPolicy)
         {
-            return adoptRef(new XMLDocumentParser(fragment, element, permission));
+            return adoptRef(new XMLDocumentParser(fragment, element, parserContentPolicy));
         }
 
         ~XMLDocumentParser();
@@ -92,7 +92,7 @@ class Text;
         void setIsXHTMLDocument(bool isXHTML) { m_isXHTMLDocument = isXHTML; }
         bool isXHTMLDocument() const { return m_isXHTMLDocument; }
 
-        static bool parseDocumentFragment(const String&, DocumentFragment*, Element* parent = 0, FragmentScriptingPermission = AllowScriptingContent);
+        static bool parseDocumentFragment(const String&, DocumentFragment*, Element* parent = 0, ParserContentPolicy = AllowScriptingContent);
 
         // Used by the XMLHttpRequest to check if the responseXML was well formed.
         virtual bool wellFormed() const { return !m_sawError; }
@@ -103,7 +103,7 @@ class Text;
 
     private:
         XMLDocumentParser(Document*, FrameView* = 0);
-        XMLDocumentParser(DocumentFragment*, Element*, FragmentScriptingPermission);
+        XMLDocumentParser(DocumentFragment*, Element*, ParserContentPolicy);
 
         // From DocumentParser
         virtual void insert(const SegmentedString&);
@@ -215,7 +215,6 @@ public:
         typedef HashMap<AtomicString, AtomicString> PrefixForNamespaceMap;
         PrefixForNamespaceMap m_prefixToNamespaceMap;
         SegmentedString m_pendingSrc;
-        FragmentScriptingPermission m_scriptingPermission;
     };
 
 #if ENABLE(XSLT)
index bba0c0e..d216750 100644 (file)
@@ -367,6 +367,13 @@ private:
     unsigned m_currentOffset;
 };
 
+static inline void setAttributes(Element* element, Vector<Attribute>& attributeVector, ParserContentPolicy parserContentPolicy)
+{
+    if (!scriptingContentIsAllowed(parserContentPolicy))
+        element->stripJavaScriptAttributes(attributeVector);
+    element->parserSetAttributes(attributeVector);
+}
+
 static void switchToUTF16(xmlParserCtxtPtr ctxt)
 {
     // Hack around libxml2's lack of encoding overide support by manually
@@ -563,12 +570,11 @@ XMLDocumentParser::XMLDocumentParser(Document* document, FrameView* frameView)
     , m_pendingScript(0)
     , m_scriptStartPosition(TextPosition::belowRangePosition())
     , m_parsingFragment(false)
-    , m_scriptingPermission(AllowScriptingContent)
 {
 }
 
-XMLDocumentParser::XMLDocumentParser(DocumentFragment* fragment, Element* parentElement, FragmentScriptingPermission scriptingPermission)
-    : ScriptableDocumentParser(fragment->document())
+XMLDocumentParser::XMLDocumentParser(DocumentFragment* fragment, Element* parentElement, ParserContentPolicy parserContentPolicy)
+    : ScriptableDocumentParser(fragment->document(), parserContentPolicy)
     , m_view(0)
     , m_context(0)
     , m_pendingCallbacks(PendingCallbacks::create())
@@ -587,7 +593,6 @@ XMLDocumentParser::XMLDocumentParser(DocumentFragment* fragment, Element* parent
     , m_pendingScript(0)
     , m_scriptStartPosition(TextPosition::belowRangePosition())
     , m_parsingFragment(true)
-    , m_scriptingPermission(scriptingPermission)
 {
     fragment->ref();
 
@@ -700,7 +705,7 @@ struct _xmlSAX2Namespace {
 };
 typedef struct _xmlSAX2Namespace xmlSAX2Namespace;
 
-static inline void handleNamespaceAttributes(Vector<Attribute, 8>& prefixedAttributes, const xmlChar** libxmlNamespaces, int nb_namespaces, ExceptionCode& ec)
+static inline void handleNamespaceAttributes(Vector<Attribute>& prefixedAttributes, const xmlChar** libxmlNamespaces, int nb_namespaces, ExceptionCode& ec)
 {
     xmlSAX2Namespace* namespaces = reinterpret_cast<xmlSAX2Namespace*>(libxmlNamespaces);
     for (int i = 0; i < nb_namespaces; i++) {
@@ -726,7 +731,7 @@ struct _xmlSAX2Attributes {
 };
 typedef struct _xmlSAX2Attributes xmlSAX2Attributes;
 
-static inline void handleElementAttributes(Vector<Attribute, 8>& prefixedAttributes, const xmlChar** libxmlAttributes, int nb_attributes, ExceptionCode& ec)
+static inline void handleElementAttributes(Vector<Attribute>& prefixedAttributes, const xmlChar** libxmlAttributes, int nb_attributes, ExceptionCode& ec)
 {
     xmlSAX2Attributes* attributes = reinterpret_cast<xmlSAX2Attributes*>(libxmlAttributes);
     for (int i = 0; i < nb_attributes; i++) {
@@ -797,17 +802,17 @@ void XMLDocumentParser::startElementNs(const xmlChar* xmlLocalName, const xmlCha
         return;
     }
 
-    Vector<Attribute, 8> prefixedAttributes;
+    Vector<Attribute> prefixedAttributes;
     ExceptionCode ec = 0;
     handleNamespaceAttributes(prefixedAttributes, libxmlNamespaces, nb_namespaces, ec);
     if (ec) {
-        newElement->parserSetAttributes(prefixedAttributes, m_scriptingPermission);
+        setAttributes(newElement.get(), prefixedAttributes, parserContentPolicy());
         stopParsing();
         return;
     }
 
     handleElementAttributes(prefixedAttributes, libxmlAttributes, nb_attributes, ec);
-    newElement->parserSetAttributes(prefixedAttributes, m_scriptingPermission);
+    setAttributes(newElement.get(), prefixedAttributes, parserContentPolicy());
     if (ec) {
         stopParsing();
         return;
@@ -863,7 +868,7 @@ void XMLDocumentParser::endElementNs()
     if (hackAroundLibXMLEntityParsingBug() && context()->depth <= depthTriggeringEntityExpansion())
         setDepthTriggeringEntityExpansion(-1);
 
-    if (!scriptingContentIsAllowed(m_scriptingPermission) && n->isElementNode() && toScriptElement(toElement(n.get()))) {
+    if (!scriptingContentIsAllowed(parserContentPolicy()) && n->isElementNode() && toScriptElement(toElement(n.get()))) {
         popCurrentNode();
         n->remove(IGNORE_EXCEPTION);
         return;
index a60ef1d..b15da86 100644 (file)
@@ -64,6 +64,13 @@ using namespace std;
 
 namespace WebCore {
 
+static inline void setAttributes(Element* element, Vector<Attribute>& attributeVector, ParserContentPolicy parserContentPolicy)
+{
+    if (!scriptingContentIsAllowed(parserContentPolicy))
+        element->stripJavaScriptAttributes(attributeVector);
+    element->parserSetAttributes(attributeVector);
+}
+
 class EntityResolver : public QXmlStreamEntityResolver {
     virtual QString resolveUndeclaredEntity(const QString &name);
 };
@@ -104,13 +111,12 @@ XMLDocumentParser::XMLDocumentParser(Document* document, FrameView* frameView)
     , m_pendingScript(0)
     , m_scriptStartPosition(TextPosition::belowRangePosition())
     , m_parsingFragment(false)
-    , m_scriptingPermission(AllowScriptingContent)
 {
     m_stream.setEntityResolver(new EntityResolver);
 }
 
-XMLDocumentParser::XMLDocumentParser(DocumentFragment* fragment, Element* parentElement, FragmentScriptingPermission permission)
-    : ScriptableDocumentParser(fragment->document())
+XMLDocumentParser::XMLDocumentParser(DocumentFragment* fragment, Element* parentElement, ParserContentPolicy parserContentPolicy)
+    : ScriptableDocumentParser(fragment->document(), parserContentPolicy)
     , m_view(0)
     , m_wroteText(false)
     , m_currentNode(fragment)
@@ -126,7 +132,6 @@ XMLDocumentParser::XMLDocumentParser(DocumentFragment* fragment, Element* parent
     , m_pendingScript(0)
     , m_scriptStartPosition(TextPosition::belowRangePosition())
     , m_parsingFragment(true)
-    , m_scriptingPermission(permission)
 {
     fragment->ref();
 
@@ -330,7 +335,7 @@ static inline String prefixFromQName(const QString& qName)
         return qName.left(offset);
 }
 
-static inline void handleNamespaceAttributes(Vector<Attribute, 8>& prefixedAttributes, const QXmlStreamNamespaceDeclarations &ns, ExceptionCode& ec)
+static inline void handleNamespaceAttributes(Vector<Attribute>& prefixedAttributes, const QXmlStreamNamespaceDeclarations &ns, ExceptionCode& ec)
 {
     for (int i = 0; i < ns.count(); ++i) {
         const QXmlStreamNamespaceDeclaration &decl = ns[i];
@@ -346,7 +351,7 @@ static inline void handleNamespaceAttributes(Vector<Attribute, 8>& prefixedAttri
     }
 }
 
-static inline void handleElementAttributes(Vector<Attribute, 8>& prefixedAttributes, const QXmlStreamAttributes &attrs, ExceptionCode& ec)
+static inline void handleElementAttributes(Vector<Attribute>& prefixedAttributes, const QXmlStreamAttributes &attrs, ExceptionCode& ec)
 {
     for (int i = 0; i < attrs.count(); ++i) {
         const QXmlStreamAttribute &attr = attrs[i];
@@ -470,17 +475,17 @@ void XMLDocumentParser::parseStartElement()
     bool isFirstElement = !m_sawFirstElement;
     m_sawFirstElement = true;
 
-    Vector<Attribute, 8> prefixedAttributes;
+    Vector<Attribute> prefixedAttributes;
     ExceptionCode ec = 0;
     handleNamespaceAttributes(prefixedAttributes, m_stream.namespaceDeclarations(), ec);
     if (ec) {
-        newElement->parserSetAttributes(prefixedAttributes, m_scriptingPermission);
+        setAttributes(newElement.get(), prefixedAttributes, parserContentPolicy());
         stopParsing();
         return;
     }
 
     handleElementAttributes(prefixedAttributes, m_stream.attributes(), ec);
-    newElement->parserSetAttributes(prefixedAttributes, m_scriptingPermission);
+    setAttributes(newElement.get(), prefixedAttributes, parserContentPolicy());
     if (ec) {
         stopParsing();
         return;
@@ -510,7 +515,7 @@ void XMLDocumentParser::parseEndElement()
     RefPtr<ContainerNode> n = m_currentNode;
     n->finishParsingChildren();
 
-    if (!scriptingContentIsAllowed(m_scriptingPermission) && n->isElementNode() && toScriptElement(toElement(n.get()))) {
+    if (!scriptingContentIsAllowed(parserContentPolicy()) && n->isElementNode() && toScriptElement(toElement(n.get()))) {
         popCurrentNode();
         n->remove(IGNORE_EXCEPTION);
         return;