Diff
Modified: trunk/LayoutTests/ChangeLog (123787 => 123788)
--- trunk/LayoutTests/ChangeLog 2012-07-26 20:19:39 UTC (rev 123787)
+++ trunk/LayoutTests/ChangeLog 2012-07-26 20:23:09 UTC (rev 123788)
@@ -1,3 +1,14 @@
+2012-07-25 Ryosuke Niwa <rn...@webkit.org>
+
+ Href attribute with _javascript_ protocol is stripped when content is pasted into a XML doucment
+ https://bugs.webkit.org/show_bug.cgi?id=92310
+
+ Reviewed by Adam Barth.
+
+ Rebaseline a test that catches this bug.
+
+ * editing/pasteboard/paste-noscript-xhtml-expected.txt:
+
2012-07-26 Dan Bernstein <m...@apple.com>
<svg> element with no intrinsic size and max-width gets sized incorrectly
Modified: trunk/LayoutTests/editing/pasteboard/paste-noscript-xhtml-expected.txt (123787 => 123788)
--- trunk/LayoutTests/editing/pasteboard/paste-noscript-xhtml-expected.txt 2012-07-26 20:19:39 UTC (rev 123787)
+++ trunk/LayoutTests/editing/pasteboard/paste-noscript-xhtml-expected.txt 2012-07-26 20:23:09 UTC (rev 123788)
@@ -63,12 +63,15 @@
| id="anchor1"
| "CNN"
| <a>
+| href=""
| id="anchor2"
| "Hello"
| <iframe>
| id="iframe1"
+| src=""
| style="width: 200px; height: 100px; background-color: rgb(204, 238, 238); "
| <form>
+| action=""
| id="form1"
| style="width: 200px; height: 150px; background-color: rgb(204, 238, 238); "
| "This is a form<#selection-caret>"
Modified: trunk/Source/WebCore/ChangeLog (123787 => 123788)
--- trunk/Source/WebCore/ChangeLog 2012-07-26 20:19:39 UTC (rev 123787)
+++ trunk/Source/WebCore/ChangeLog 2012-07-26 20:23:09 UTC (rev 123788)
@@ -1,3 +1,39 @@
+2012-07-26 Ryosuke Niwa <rn...@webkit.org>
+
+ Href attribute with _javascript_ protocol is stripped when content is pasted into a XML doucment
+ https://bugs.webkit.org/show_bug.cgi?id=92310
+
+ Reviewed by Adam Barth.
+
+ The bug was caused by setAttributeNS's stripping attributes for which isAttributeToRemove
+ return true instead of setting an empty string. Changing this in setAttributeNS is problematic
+ because it will trigger a logic, in HTMLAnchorElement for example, to resolve the URL.
+
+ Fixed the bug by making XML parsers call parserSetAttributes instead of setAttributeNS.
+ After this patch, handleNamespaceAttributes and handleElementAttributes simply fills up a Vector
+ with which startElementNs (or parseStartElement in Qt) calls parserSetAttributes.
+
+ * dom/Element.cpp:
+ (WebCore::Element::parserSetAttributes): Sets emptyAtom instead of nullAtom as nullAtom can be
+ turned into "null".
+ (WebCore::Element::parseAttributeName): Extracted from setAttributeNS.
+ (WebCore::Element::setAttributeNS): No longer takes FragmentScriptingPermission.
+ * dom/Element.h:
+ (Element):
+ * editing/markup.cpp:
+ (WebCore::completeURLs): Don't resolve URLs when it's empty since empty attribute has a canonical
+ meaning in some cases. e.g. <frame src=""
+ * xml/parser/XMLDocumentParserLibxml2.cpp:
+ (WebCore::handleNamespaceAttributes): Renamed from handleElementNamespaces. Call
+ parserSetAttributes even when exiting early to be maintain the same behavior.
+ (WebCore::handleElementAttributes):
+ (WebCore::XMLDocumentParser::startElementNs):
+ * xml/parser/XMLDocumentParserQt.cpp:
+ (WebCore::handleNamespaceAttributes): Use XMLNSNames::xmlnsNamespaceURI. Call parserSetAttributes
+ even when exiting early to be maintain the same behavior.
+ (WebCore::handleElementAttributes):
+ (WebCore::XMLDocumentParser::parseStartElement):
+
2012-07-26 Dan Bernstein <m...@apple.com>
<svg> element with no intrinsic size and max-width gets sized incorrectly
Modified: trunk/Source/WebCore/dom/Element.cpp (123787 => 123788)
--- trunk/Source/WebCore/dom/Element.cpp 2012-07-26 20:19:39 UTC (rev 123787)
+++ trunk/Source/WebCore/dom/Element.cpp 2012-07-26 20:23:09 UTC (rev 123788)
@@ -784,7 +784,7 @@
}
if (isAttributeToRemove(attribute.name(), attribute.value()))
- attribute.setValue(nullAtom);
+ attribute.setValue(emptyAtom);
i++;
}
}
@@ -1462,23 +1462,30 @@
return detachAttribute(index);
}
-void Element::setAttributeNS(const AtomicString& namespaceURI, const AtomicString& qualifiedName, const AtomicString& value, ExceptionCode& ec, FragmentScriptingPermission scriptingPermission)
+bool Element::parseAttributeName(QualifiedName& out, const AtomicString& namespaceURI, const AtomicString& qualifiedName, ExceptionCode& ec)
{
String prefix, localName;
if (!Document::parseQualifiedName(qualifiedName, prefix, localName, ec))
- return;
+ return false;
+ ASSERT(!ec);
QualifiedName qName(prefix, localName, namespaceURI);
if (!Document::hasValidNamespaceForAttributes(qName)) {
ec = NAMESPACE_ERR;
- return;
+ return false;
}
- if (scriptingPermission == DisallowScriptingContent && (isEventHandlerAttribute(qName) || isAttributeToRemove(qName, value)))
+ out = qName;
+ return true;
+}
+
+void Element::setAttributeNS(const AtomicString& namespaceURI, const AtomicString& qualifiedName, const AtomicString& value, ExceptionCode& ec)
+{
+ QualifiedName parsedName = anyName;
+ if (!parseAttributeName(parsedName, namespaceURI, qualifiedName, ec))
return;
-
- setAttribute(qName, value);
+ setAttribute(parsedName, value);
}
void Element::removeAttribute(size_t index)
Modified: trunk/Source/WebCore/dom/Element.h (123787 => 123788)
--- trunk/Source/WebCore/dom/Element.h 2012-07-26 20:19:39 UTC (rev 123787)
+++ trunk/Source/WebCore/dom/Element.h 2012-07-26 20:23:09 UTC (rev 123788)
@@ -146,7 +146,8 @@
const AtomicString& getAttributeNS(const String& namespaceURI, const String& localName) const;
void setAttribute(const AtomicString& name, const AtomicString& value, ExceptionCode&);
- void setAttributeNS(const AtomicString& namespaceURI, const AtomicString& qualifiedName, const AtomicString& value, ExceptionCode&, FragmentScriptingPermission = AllowScriptingContent);
+ static bool parseAttributeName(QualifiedName&, const AtomicString& namespaceURI, const AtomicString& qualifiedName, ExceptionCode&);
+ void setAttributeNS(const AtomicString& namespaceURI, const AtomicString& qualifiedName, const AtomicString& value, ExceptionCode&);
bool isIdAttributeName(const QualifiedName&) const;
const AtomicString& getIdAttribute() const;
Modified: trunk/Source/WebCore/editing/markup.cpp (123787 => 123788)
--- trunk/Source/WebCore/editing/markup.cpp 2012-07-26 20:19:39 UTC (rev 123787)
+++ trunk/Source/WebCore/editing/markup.cpp 2012-07-26 20:23:09 UTC (rev 123788)
@@ -111,7 +111,7 @@
unsigned length = e->attributeCount();
for (unsigned i = 0; i < length; i++) {
const Attribute* attribute = e->attributeItem(i);
- if (e->isURLAttribute(*attribute))
+ if (e->isURLAttribute(*attribute) && !attribute->value().isEmpty())
changes.append(AttributeChange(e, attribute->name(), KURL(parsedBaseURL, attribute->value()).string()));
}
}
Modified: trunk/Source/WebCore/xml/parser/XMLDocumentParserLibxml2.cpp (123787 => 123788)
--- trunk/Source/WebCore/xml/parser/XMLDocumentParserLibxml2.cpp 2012-07-26 20:19:39 UTC (rev 123787)
+++ trunk/Source/WebCore/xml/parser/XMLDocumentParserLibxml2.cpp 2012-07-26 20:23:09 UTC (rev 123788)
@@ -696,7 +696,7 @@
};
typedef struct _xmlSAX2Namespace xmlSAX2Namespace;
-static inline void handleElementNamespaces(Element* newElement, const xmlChar** libxmlNamespaces, int nb_namespaces, ExceptionCode& ec, FragmentScriptingPermission scriptingPermission)
+static inline void handleNamespaceAttributes(Vector<Attribute, 8>& prefixedAttributes, const xmlChar** libxmlNamespaces, int nb_namespaces, ExceptionCode& ec)
{
xmlSAX2Namespace* namespaces = reinterpret_cast<xmlSAX2Namespace*>(libxmlNamespaces);
for (int i = 0; i < nb_namespaces; i++) {
@@ -704,9 +704,12 @@
AtomicString namespaceURI = toAtomicString(namespaces[i].uri);
if (namespaces[i].prefix)
namespaceQName = "xmlns:" + toString(namespaces[i].prefix);
- newElement->setAttributeNS(XMLNSNames::xmlnsNamespaceURI, namespaceQName, namespaceURI, ec, scriptingPermission);
- if (ec) // exception setting attributes
+
+ QualifiedName parsedName = anyName;
+ if (!Element::parseAttributeName(parsedName, XMLNSNames::xmlnsNamespaceURI, namespaceQName, ec))
return;
+
+ prefixedAttributes.append(Attribute(parsedName, namespaceURI));
}
}
@@ -719,7 +722,7 @@
};
typedef struct _xmlSAX2Attributes xmlSAX2Attributes;
-static inline void handleElementAttributes(Element* newElement, const xmlChar** libxmlAttributes, int nb_attributes, ExceptionCode& ec, FragmentScriptingPermission scriptingPermission)
+static inline void handleElementAttributes(Vector<Attribute, 8>& prefixedAttributes, const xmlChar** libxmlAttributes, int nb_attributes, ExceptionCode& ec)
{
xmlSAX2Attributes* attributes = reinterpret_cast<xmlSAX2Attributes*>(libxmlAttributes);
for (int i = 0; i < nb_attributes; i++) {
@@ -729,9 +732,11 @@
AtomicString attrURI = attrPrefix.isEmpty() ? AtomicString() : toAtomicString(attributes[i].uri);
AtomicString attrQName = attrPrefix.isEmpty() ? toAtomicString(attributes[i].localname) : attrPrefix + ":" + toString(attributes[i].localname);
- newElement->setAttributeNS(attrURI, attrQName, attrValue, ec, scriptingPermission);
- if (ec) // exception setting attributes
+ QualifiedName parsedName = anyName;
+ if (!Element::parseAttributeName(parsedName, attrURI, attrQName, ec))
return;
+
+ prefixedAttributes.append(Attribute(parsedName, attrValue));
}
}
@@ -788,14 +793,17 @@
return;
}
+ Vector<Attribute, 8> prefixedAttributes;
ExceptionCode ec = 0;
- handleElementNamespaces(newElement.get(), libxmlNamespaces, nb_namespaces, ec, m_scriptingPermission);
+ handleNamespaceAttributes(prefixedAttributes, libxmlNamespaces, nb_namespaces, ec);
if (ec) {
+ newElement->parserSetAttributes(prefixedAttributes, m_scriptingPermission);
stopParsing();
return;
}
- handleElementAttributes(newElement.get(), libxmlAttributes, nb_attributes, ec, m_scriptingPermission);
+ handleElementAttributes(prefixedAttributes, libxmlAttributes, nb_attributes, ec);
+ newElement->parserSetAttributes(prefixedAttributes, m_scriptingPermission);
if (ec) {
stopParsing();
return;
Modified: trunk/Source/WebCore/xml/parser/XMLDocumentParserQt.cpp (123787 => 123788)
--- trunk/Source/WebCore/xml/parser/XMLDocumentParserQt.cpp 2012-07-26 20:19:39 UTC (rev 123787)
+++ trunk/Source/WebCore/xml/parser/XMLDocumentParserQt.cpp 2012-07-26 20:23:09 UTC (rev 123788)
@@ -52,6 +52,7 @@
#include "ScriptValue.h"
#include "TextResourceDecoder.h"
#include "TransformSource.h"
+#include "XMLNSNames.h"
#include <QDebug>
#include <wtf/StringExtras.h>
#include <wtf/Threading.h>
@@ -315,22 +316,23 @@
return qName.left(offset);
}
-static inline void handleElementNamespaces(Element* newElement, const QXmlStreamNamespaceDeclarations &ns,
- ExceptionCode& ec, FragmentScriptingPermission scriptingPermission)
+static inline void handleNamespaceAttributes(Vector<Attribute, 8>& prefixedAttributes, const QXmlStreamNamespaceDeclarations &ns, ExceptionCode& ec)
{
for (int i = 0; i < ns.count(); ++i) {
const QXmlStreamNamespaceDeclaration &decl = ns[i];
String namespaceURI = decl.namespaceUri();
String namespaceQName = decl.prefix().isEmpty() ? String("xmlns") : String("xmlns:");
namespaceQName.append(decl.prefix());
- newElement->setAttributeNS("http://www.w3.org/2000/xmlns/", namespaceQName, namespaceURI, ec, scriptingPermission);
- if (ec) // exception setting attributes
+
+ QualifiedName parsedName = anyName;
+ if (!Element::parseAttributeName(parsedName, XMLNSNames::xmlnsNamespaceURI, namespaceQName, ec))
return;
+
+ prefixedAttributes.append(Attribute(parsedName, namespaceURI));
}
}
-static inline void handleElementAttributes(Element* newElement, const QXmlStreamAttributes &attrs, ExceptionCode& ec,
- FragmentScriptingPermission scriptingPermission)
+static inline void handleElementAttributes(Vector<Attribute, 8>& prefixedAttributes, const QXmlStreamAttributes &attrs, ExceptionCode& ec)
{
for (int i = 0; i < attrs.count(); ++i) {
const QXmlStreamAttribute &attr = attrs[i];
@@ -338,9 +340,12 @@
String attrValue = attr.value();
String attrURI = attr.namespaceUri().isEmpty() ? String() : String(attr.namespaceUri());
String attrQName = attr.qualifiedName();
- newElement->setAttributeNS(attrURI, attrQName, attrValue, ec, scriptingPermission);
- if (ec) // exception setting attributes
+
+ QualifiedName parsedName = anyName;
+ if (!Element::parseAttributeName(parsedName, attrURI, attrQName, ec))
return;
+
+ prefixedAttributes.append(Attribute(parsedName, attrURI));
}
}
@@ -455,14 +460,17 @@
bool isFirstElement = !m_sawFirstElement;
m_sawFirstElement = true;
+ Vector<Attribute, 8> prefixedAttributes;
ExceptionCode ec = 0;
- handleElementNamespaces(newElement.get(), m_stream.namespaceDeclarations(), ec, m_scriptingPermission);
+ handleNamespaceAttributes(prefixedAttributes, m_stream.namespaceDeclarations(), ec);
if (ec) {
+ newElement->parserSetAttributes(prefixedAttributes, m_scriptingPermission);
stopParsing();
return;
}
- handleElementAttributes(newElement.get(), m_stream.attributes(), ec, m_scriptingPermission);
+ handleElementAttributes(prefixedAttributes, m_stream.attributes(), ec);
+ newElement->parserSetAttributes(prefixedAttributes, m_scriptingPermission);
if (ec) {
stopParsing();
return;