- Revision
- 144595
- Author
- [email protected]
- Date
- 2013-03-03 21:51:46 -0800 (Sun, 03 Mar 2013)
Log Message
createAttribute/setAttributeNode does not properly normalize case
https://bugs.webkit.org/show_bug.cgi?id=90341
Patch by Arpita Bahuguna <[email protected]> on 2013-03-03
Reviewed by Darin Adler.
Source/WebCore:
setAttributeNode() verifies for existing attributes in a case sensitive
manner. Thus, it would add another attribute if specified in a case
different from the existing one. Instead, like setAttribute(), it too
should modify the existing attribute's value.
Test: fast/dom/Element/setAttributeNode-case-insensitivity.html
* dom/Element.cpp:
(WebCore::Element::setAttributeNode):
Made changes to check for an existing attribute by converting the
specified attribute's localName to lowercase.
LayoutTests:
* fast/dom/Element/setAttributeNode-case-insensitivity-expected.txt: Added.
* fast/dom/Element/setAttributeNode-case-insensitivity.html: Added.
Testcase for verifying that setAttributeNode() checks against existing
attributes in a case insensitive manner. It updates the value of an
existing attribute (in lower case) with that of the one set using
setAttributeNode() (in upper case).
The test also verifies the behavior of attributes when specified with
namespace and prefix.
Modified Paths
Added Paths
Diff
Modified: trunk/LayoutTests/ChangeLog (144594 => 144595)
--- trunk/LayoutTests/ChangeLog 2013-03-04 01:42:53 UTC (rev 144594)
+++ trunk/LayoutTests/ChangeLog 2013-03-04 05:51:46 UTC (rev 144595)
@@ -1,3 +1,19 @@
+2013-03-03 Arpita Bahuguna <[email protected]>
+
+ createAttribute/setAttributeNode does not properly normalize case
+ https://bugs.webkit.org/show_bug.cgi?id=90341
+
+ Reviewed by Darin Adler.
+
+ * fast/dom/Element/setAttributeNode-case-insensitivity-expected.txt: Added.
+ * fast/dom/Element/setAttributeNode-case-insensitivity.html: Added.
+ Testcase for verifying that setAttributeNode() checks against existing
+ attributes in a case insensitive manner. It updates the value of an
+ existing attribute (in lower case) with that of the one set using
+ setAttributeNode() (in upper case).
+ The test also verifies the behavior of attributes when specified with
+ namespace and prefix.
+
2013-03-03 Ryosuke Niwa <[email protected]>
Some perf. tests have variances that differ greatly between runs
Added: trunk/LayoutTests/fast/dom/Element/setAttributeNode-case-insensitivity-expected.txt (0 => 144595)
--- trunk/LayoutTests/fast/dom/Element/setAttributeNode-case-insensitivity-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/dom/Element/setAttributeNode-case-insensitivity-expected.txt 2013-03-04 05:51:46 UTC (rev 144595)
@@ -0,0 +1,16 @@
+Test for Bugzilla bug: 90341: createAttribute/setAttributeNode does not properly normalize case.
+This test verifies that the setAttributeNode() API checks for existing attributes case-insensitively. Thus the value of an existing attribute with the same name but in a different case should get replaced by the new value specified via the setAttributeNode() method. The issue can be manually verified if a green colored block is displayed instead of a red one.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+PASS test.getAttribute('style') is test.getAttribute('STYLE')
+PASS test.getAttributeNode('style').value is test.getAttributeNode('STYLE').value
+Verifying that attributes with the same name but different namespaces are treated as unique entities. For the following test two different attribute values should be returned.
+PASS test.getAttributeNodeNS('ns1', 'newattr').value is 'newattr1'
+PASS test.getAttributeNodeNS('ns2', 'newattr').value is 'newattr2'
+Verifying that attributes with same name but different case and having same namespaces are treated as same. In the following test the new attribute should overwrite the value of the existing one.
+PASS test.getAttributeNodeNS('ns1', 'newattr').value is 'newattr3'
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/dom/Element/setAttributeNode-case-insensitivity.html (0 => 144595)
--- trunk/LayoutTests/fast/dom/Element/setAttributeNode-case-insensitivity.html (rev 0)
+++ trunk/LayoutTests/fast/dom/Element/setAttributeNode-case-insensitivity.html 2013-03-04 05:51:46 UTC (rev 144595)
@@ -0,0 +1,61 @@
+<html>
+<head>
+<style>
+#test {
+ font-family: ahem;
+ width: 50;
+ height: 50;
+}
+</style>
+<script src=""
+<script>
+function runTest()
+{
+ description("This test verifies that the setAttributeNode() API checks for existing attributes case-insensitively. Thus the value of an existing attribute with the same name but in a different case should get replaced by the new value specified via the setAttributeNode() method.\nThe issue can be manually verified if a green colored block is displayed instead of a red one.");
+
+ var test = document.getElementById("test");
+ var newStyleAttr = document.createAttribute("STYLE");
+ newStyleAttr.value = "background-color: green";
+ test.setAttributeNode(newStyleAttr);
+ if (window.testRunner) {
+ shouldBe("test.getAttribute('style')", "test.getAttribute('STYLE')");
+ shouldBe("test.getAttributeNode('style').value", "test.getAttributeNode('STYLE').value");
+ }
+
+ debug("Verifying that attributes with the same name but different namespaces are treated as unique entities. For the following test two different attribute values should be returned.");
+ var newAttr1 = document.createAttributeNS("ns1", "newattr");
+ newAttr1.prefix = "prefix1";
+ newAttr1.value = "newattr1";
+ test.setAttributeNode(newAttr1);
+ var newAttr2 = document.createAttributeNS("ns2", "newattr");
+ newAttr2.prefix = "prefix2";
+ newAttr2.value = "newattr2";
+ test.setAttributeNode(newAttr2);
+ if (window.testRunner) {
+ shouldBe("test.getAttributeNodeNS('ns1', 'newattr').value", "'newattr1'");
+ shouldBe("test.getAttributeNodeNS('ns2', 'newattr').value", "'newattr2'");
+ }
+
+ debug("Verifying that attributes with same name but different case and having same namespaces are treated as same. In the following test the new attribute should overwrite the value of the existing one.");
+ var newAttr3 = document.createAttributeNS("ns1", "NEWATTR");
+ newAttr3.prefix = "prefix2";
+ newAttr3.value = "newattr3";
+ test.setAttributeNode(newAttr3);
+
+ if (window.testRunner) {
+ shouldBe("test.getAttributeNodeNS('ns1', 'newattr').value", "'newattr3'");
+
+ isSuccessfullyParsed();
+ test.style.display = 'none';
+ }
+
+}
+</script>
+</head>
+<body _onload_="runTest()">
+<div>Test for Bugzilla bug:<a href="" 90341:</a> createAttribute/setAttributeNode does not properly normalize case.</div>
+<div id="test" style="background-color: red"> </div>
+<div id="description"></div>
+<div id="console"></div>
+</body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (144594 => 144595)
--- trunk/Source/WebCore/ChangeLog 2013-03-04 01:42:53 UTC (rev 144594)
+++ trunk/Source/WebCore/ChangeLog 2013-03-04 05:51:46 UTC (rev 144595)
@@ -1,3 +1,22 @@
+2013-03-03 Arpita Bahuguna <[email protected]>
+
+ createAttribute/setAttributeNode does not properly normalize case
+ https://bugs.webkit.org/show_bug.cgi?id=90341
+
+ Reviewed by Darin Adler.
+
+ setAttributeNode() verifies for existing attributes in a case sensitive
+ manner. Thus, it would add another attribute if specified in a case
+ different from the existing one. Instead, like setAttribute(), it too
+ should modify the existing attribute's value.
+
+ Test: fast/dom/Element/setAttributeNode-case-insensitivity.html
+
+ * dom/Element.cpp:
+ (WebCore::Element::setAttributeNode):
+ Made changes to check for an existing attribute by converting the
+ specified attribute's localName to lowercase.
+
2013-03-03 Kentaro Hara <[email protected]>
Unreviewed. Rebaselined run-bindings-tests.
Modified: trunk/Source/WebCore/dom/Element.cpp (144594 => 144595)
--- trunk/Source/WebCore/dom/Element.cpp 2013-03-04 01:42:53 UTC (rev 144594)
+++ trunk/Source/WebCore/dom/Element.cpp 2013-03-04 05:51:46 UTC (rev 144595)
@@ -1708,7 +1708,9 @@
return 0;
}
- RefPtr<Attr> oldAttrNode = attrIfExists(attrNode->qualifiedName());
+ const QualifiedName& attrName = attrNode->qualifiedName();
+
+ RefPtr<Attr> oldAttrNode = attrIfExists(attrName);
if (oldAttrNode.get() == attrNode)
return attrNode; // This Attr is already attached to the element.
@@ -1722,15 +1724,16 @@
synchronizeAllAttributes();
UniqueElementData* elementData = ensureUniqueElementData();
- size_t index = elementData->getAttributeItemIndex(attrNode->qualifiedName());
+ const QualifiedName& caseAdjustedName = shouldIgnoreAttributeCase(this) ? QualifiedName(attrName.prefix(), attrName.localName().lower(), attrName.namespaceURI()) : attrName;
+ size_t index = elementData->getAttributeItemIndex(caseAdjustedName);
if (index != notFound) {
if (oldAttrNode)
detachAttrNodeFromElementWithValue(oldAttrNode.get(), elementData->attributeItem(index)->value());
else
- oldAttrNode = Attr::create(document(), attrNode->qualifiedName(), elementData->attributeItem(index)->value());
+ oldAttrNode = Attr::create(document(), attrName, elementData->attributeItem(index)->value());
}
- setAttributeInternal(index, attrNode->qualifiedName(), attrNode->value(), NotInSynchronizationOfLazyAttribute);
+ setAttributeInternal(index, index != notFound ? caseAdjustedName : attrName, attrNode->value(), NotInSynchronizationOfLazyAttribute);
attrNode->attachToElement(this);
ensureAttrNodeListForElement(this)->append(attrNode);