Assigning to Element.prefix should throw exception when using illegal characters
authorabarth@webkit.org <abarth@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 19 Jan 2012 07:39:41 +0000 (07:39 +0000)
committerabarth@webkit.org <abarth@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 19 Jan 2012 07:39:41 +0000 (07:39 +0000)
https://bugs.webkit.org/show_bug.cgi?id=76589

Reviewed by Eric Seidel.

This patch fixes a FIXME and implements the INVALID_CHARACTER_ERR
exception described in
http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-NodeNSPrefix

Tests: fast/dom/Element/prefix-setter-exception.html

* dom/Node.cpp:
(WebCore::isValidNameStartCharacter):
(WebCore::isValidNameCharacter):
(WebCore::hasInvalidValidNameCharacters):
(WebCore::Node::checkSetPrefix):

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

LayoutTests/fast/dom/Element/prefix-setter-exception-expected.txt [new file with mode: 0644]
LayoutTests/fast/dom/Element/prefix-setter-exception.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/dom/Node.cpp

diff --git a/LayoutTests/fast/dom/Element/prefix-setter-exception-expected.txt b/LayoutTests/fast/dom/Element/prefix-setter-exception-expected.txt
new file mode 100644 (file)
index 0000000..fb60e88
--- /dev/null
@@ -0,0 +1,27 @@
+Test for the implementation of DOM Level 3 Core API on Node Interface: prefix setter. INVALID_CHARACTER_ERR: Raised if the specified prefix contains an illegal character according to the XML version in use specified in the Document.xmlVersion attribute. http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-NodeNSPrefix
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS prefixedElem.prefix = "." threw exception Error: INVALID_CHARACTER_ERR: DOM Exception 5.
+PASS prefixedElem.prefix is "before"
+PASS prefixedElem.prefix = "x." is "x."
+PASS prefixedElem.prefix is "x."
+PASS prefixedElem.prefix = "0a" threw exception Error: INVALID_CHARACTER_ERR: DOM Exception 5.
+PASS prefixedElem.prefix is "before"
+PASS prefixedElem.prefix = "a0" is "a0"
+PASS prefixedElem.prefix is "a0"
+PASS prefixedElem.prefix = "_0" is "_0"
+PASS prefixedElem.prefix is "_0"
+PASS prefixedElem.prefix = "×" threw exception Error: INVALID_CHARACTER_ERR: DOM Exception 5.
+PASS prefixedElem.prefix is "before"
+PASS prefixedElem.prefix = "·" threw exception Error: INVALID_CHARACTER_ERR: DOM Exception 5.
+PASS prefixedElem.prefix is "before"
+PASS prefixedElem.prefix = "aa" is "aa"
+PASS prefixedElem.prefix is "aa"
+PASS prefixedElem.prefix = "\n" threw exception Error: INVALID_CHARACTER_ERR: DOM Exception 5.
+PASS prefixedElem.prefix is "before"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/dom/Element/prefix-setter-exception.html b/LayoutTests/fast/dom/Element/prefix-setter-exception.html
new file mode 100644 (file)
index 0000000..12404c6
--- /dev/null
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>DOM L3 Core: Node Interface prefix property setter</title>
+</head>
+<body>
+<script src="../../js/resources/js-test-pre.js"></script>
+<script>
+description('Test for the implementation of DOM Level 3 Core API on Node Interface: prefix setter. INVALID_CHARACTER_ERR: Raised if the specified prefix contains an illegal character according to the XML version in use specified in the Document.xmlVersion attribute.  <a href="http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-NodeNSPrefix">http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-NodeNSPrefix</a>');
+
+var prefixedElem = document.createElementNS("ns1", "pre1:foo");
+document.body.appendChild(prefixedElem);
+
+function test(prefix, expectedToThrow) {
+    prefixedElem.prefix = "before";
+    if (expectedToThrow) {
+        shouldThrow('prefixedElem.prefix = ' + prefix);
+        shouldBe('prefixedElem.prefix', '"before"');
+    } else {
+        shouldBe('prefixedElem.prefix = ' + prefix, prefix);
+        shouldBe('prefixedElem.prefix', prefix);
+    }
+}
+
+test('"."', true);
+test('"x."', false);
+test('"0a"', true);
+test('"a0"', false);
+test('"_0"', false);
+test('"\xD7"', true);
+test('"\xB7"', true);
+test('"aa"', false);
+test('"\\n"', true);
+</script>
+<script src="../../js/resources/js-test-post.js"></script>
+</body>
+</html>
+
index 588630f..ed6a873 100644 (file)
@@ -1,3 +1,22 @@
+2012-01-18  Adam Barth  <abarth@webkit.org>
+
+        Assigning to Element.prefix should throw exception when using illegal characters
+        https://bugs.webkit.org/show_bug.cgi?id=76589
+
+        Reviewed by Eric Seidel.
+
+        This patch fixes a FIXME and implements the INVALID_CHARACTER_ERR
+        exception described in
+        http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-NodeNSPrefix
+
+        Tests: fast/dom/Element/prefix-setter-exception.html
+
+        * dom/Node.cpp:
+        (WebCore::isValidNameStartCharacter):
+        (WebCore::isValidNameCharacter):
+        (WebCore::hasInvalidValidNameCharacters):
+        (WebCore::Node::checkSetPrefix):
+
 2012-01-18  Shinya Kawanaka  <shinyak@google.com>
 
         ShadowContent query should be able to have fallback elements.
index eac0c95..1644618 100644 (file)
@@ -128,6 +128,62 @@ namespace WebCore {
 
 using namespace HTMLNames;
 
+// http://www.w3.org/TR/2008/REC-xml-20081126/#NT-NameStartChar
+static bool isValidNameStartCharacter(UChar c)
+{
+    return isASCIIAlpha(c)
+        || c == ':'
+        || c == '_'
+        || (c >= 0xC0 && c <= 0xD6)
+        || (c >= 0xD8 && c <= 0xF6)
+        || (c >= 0xF8 && c <= 0x2FF)
+        || (c >= 0x370 && c <= 0x37D)
+        || (c >= 0x37F && c <= 0x1FFF)
+        || (c >= 0x200C && c <= 0x200D)
+        || (c >= 0x2070 && c <= 0x218F)
+        || (c >= 0x2C00 && c <= 0x2FEF)
+        || (c >= 0x3001 && c <= 0xD7FF)
+        || (c >= 0xF900 && c <= 0xFDCF)
+        || (c >= 0xFDF0 && c <= 0xFFFD)
+        // We're supposed to allow characters in the range U+10000-U+EFFFF,
+        // but doing so precisely requires decoding UTF-16 surrogates.
+        // Instead, we just allow all non-BMP characters. This is consistent
+        // with the philosphy (if not the letter) of the XML specification:
+        //   "The intention is to be inclusive rather than exclusive, so that
+        //   writing systems not yet encoded in Unicode can be used in XML names."
+        //
+        // FIXME: Validate non-BMP characters correctly.
+        || (c >= 0xD800 && c <= 0xDFFF);
+}
+
+// http://www.w3.org/TR/2008/REC-xml-20081126/#NT-NameChar
+static bool isValidNameCharacter(UChar c)
+{
+    return isValidNameStartCharacter(c)
+        || isASCIIDigit(c)
+        || c == '-'
+        || c == '.'
+        || c == 0xB7
+        || (c >= 0x0300 && c <= 0x036F)
+        || (c >= 0x203F && c <= 0x2040);
+}
+
+// http://www.w3.org/TR/2008/REC-xml-20081126/#NT-Name
+static bool hasInvalidValidNameCharacters(const AtomicString& prefix)
+{
+    const UChar* characters = prefix.characters();
+    size_t length = prefix.length();
+    if (!length)
+        return false;
+    if (!isValidNameStartCharacter(characters[0]))
+        return true;
+    for (size_t i = 1; i < length; ++i) {
+        if (!isValidNameCharacter(characters[i]))
+            return true;
+    }
+    return false;
+}
+
 bool Node::isSupported(const String& feature, const String& version)
 {
     return DOMImplementation::hasFeature(feature, version);
@@ -1188,8 +1244,11 @@ void Node::checkSetPrefix(const AtomicString& prefix, ExceptionCode& ec)
     // Perform error checking as required by spec for setting Node.prefix. Used by
     // Element::setPrefix() and Attr::setPrefix()
 
-    // FIXME: Implement support for INVALID_CHARACTER_ERR: Raised if the specified prefix contains an illegal character.
-    
+    if (hasInvalidValidNameCharacters(prefix)) {
+        ec = INVALID_CHARACTER_ERR;
+        return;
+    }
+
     if (isReadOnlyNode()) {
         ec = NO_MODIFICATION_ALLOWED_ERR;
         return;