WebCore:
authordarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 29 Mar 2009 15:37:49 +0000 (15:37 +0000)
committerdarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 29 Mar 2009 15:37:49 +0000 (15:37 +0000)
2009-03-29  Darin Adler  <darin@apple.com>

        Reviewed by Dan Bernstein.

        <rdar://problem/6015407> attr parsing should allow only identifiers

        Test: fast/css/attr-parsing.html

        * css/CSSParser.cpp:
        (WebCore::CSSParser::parseContent): Allow only CSS_IDENT, and filter out
        identifiers that start with "-".
        * css/CSSPrimitiveValue.cpp:
        (WebCore::CSSPrimitiveValue::cssText): Added a case for CSS_ATTR so the test
        case works. This has the pleasant side effect of fixing a bug too.

LayoutTests:

2009-03-29  Darin Adler  <darin@apple.com>

        Reviewed by Dan Bernstein.

        <rdar://problem/6015407> attr parsing should allow only identifiers

        * fast/css/attr-parsing-expected.txt: Added.
        * fast/css/attr-parsing.html: Added.

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

LayoutTests/ChangeLog
LayoutTests/fast/css/attr-parsing-expected.txt [new file with mode: 0644]
LayoutTests/fast/css/attr-parsing.html [new file with mode: 0644]
WebCore/ChangeLog
WebCore/css/CSSParser.cpp
WebCore/css/CSSPrimitiveValue.cpp

index 3e3b1d0..5c55d75 100644 (file)
@@ -1,5 +1,14 @@
 2009-03-29  Darin Adler  <darin@apple.com>
 
+        Reviewed by Dan Bernstein.
+
+        <rdar://problem/6015407> attr parsing should allow only identifiers
+
+        * fast/css/attr-parsing-expected.txt: Added.
+        * fast/css/attr-parsing.html: Added.
+
+2009-03-29  Darin Adler  <darin@apple.com>
+
         Bug 12104: Native Slider: When the thumb's height is specified as a percentage, it is not centered properly
         https://bugs.webkit.org/show_bug.cgi?id=12104
 
diff --git a/LayoutTests/fast/css/attr-parsing-expected.txt b/LayoutTests/fast/css/attr-parsing-expected.txt
new file mode 100644 (file)
index 0000000..7f6601a
--- /dev/null
@@ -0,0 +1,39 @@
+SUCCESS
+
+Rules from the stylesheet:
+
+#a { content: attr(b); }
+#c { }
+#d { }
+#e { }
+#f { }
+#g { }
+#h { }
+#i { }
+#j { }
+#l { }
+#n { }
+#q { }
+#r { }
+#s { }
+#t { }
+#u { }
+Expected result:
+
+#a { content: attr(b); }
+#c { }
+#d { }
+#e { }
+#f { }
+#g { }
+#h { }
+#i { }
+#j { }
+#l { }
+#n { }
+#q { }
+#r { }
+#s { }
+#t { }
+#u { }
+
diff --git a/LayoutTests/fast/css/attr-parsing.html b/LayoutTests/fast/css/attr-parsing.html
new file mode 100644 (file)
index 0000000..7a8efbd
--- /dev/null
@@ -0,0 +1,65 @@
+<style>
+#a { content: attr(b); }
+#c { content: attr("x"); }
+#d { content: attr(0); }
+#e { content: attr(0.0); }
+#f { content: attr(0%); }
+#g { content: attr(0px); }
+#h { content: attr(); }
+#i { content: attr(+0); }
+#j { content: attr(-k); }
+#l { content: attr(0m); }
+#n { content: attr(-0p); }
+#q { content: attr(url(http://webkit.org)); }
+#r { content: attr(U+0020); }
+#s { content: attr(U+0020-00FF); }
+#t { content: attr(#123456); }
+#u { content: attr(#); }
+</style>
+
+<p id="message">TEST DID NOT COMPLETE</p>
+
+<p>Rules from the stylesheet:</p>
+
+<pre id="result"></pre>
+
+<p>Expected result:</p>
+
+<pre id="expected">#a { content: attr(b); }
+#c { }
+#d { }
+#e { }
+#f { }
+#g { }
+#h { }
+#i { }
+#j { }
+#l { }
+#n { }
+#q { }
+#r { }
+#s { }
+#t { }
+#u { }
+</pre>
+
+<script>
+
+if (window.layoutTestController)
+    layoutTestController.dumpAsText();
+
+var rules = document.styleSheets[0].cssRules;
+var text = "";
+for (var i = 0; i < rules.length; i++) {
+    text += rules.item(i).cssText;
+    text += "\n";
+}
+
+document.getElementById("result").appendChild(document.createTextNode(text));
+
+if (document.getElementById("result").firstChild.data === document.getElementById("expected").firstChild.data)
+    document.getElementById("message").firstChild.data = "SUCCESS";
+else
+    document.getElementById("message").firstChild.data = "FAILURE";
+
+</script>
index 51293e1..0c9d4bc 100644 (file)
@@ -1,3 +1,18 @@
+2009-03-29  Darin Adler  <darin@apple.com>
+
+        Reviewed by Dan Bernstein.
+
+        <rdar://problem/6015407> attr parsing should allow only identifiers
+
+        Test: fast/css/attr-parsing.html
+
+        * css/CSSParser.cpp:
+        (WebCore::CSSParser::parseContent): Allow only CSS_IDENT, and filter out
+        identifiers that start with "-".
+        * css/CSSPrimitiveValue.cpp:
+        (WebCore::CSSPrimitiveValue::cssText): Added a case for CSS_ATTR so the test
+        case works. This has the pleasant side effect of fixing a bug too.
+
 2009-03-29  Alexey Proskuryakov  <ap@webkit.org>
 
         <rdar://problem/6492712> Cross-origin redirects are not handled correctly.
index 62e29b6..88bf8e6 100644 (file)
@@ -623,7 +623,6 @@ bool CSSParser::parseValue(int propId, bool important)
     case CSSPropertyContent:              // [ <string> | <uri> | <counter> | attr(X) | open-quote |
         // close-quote | no-open-quote | no-close-quote ]+ | inherit
         return parseContent(propId, important);
-        break;
 
     case CSSPropertyWhiteSpace:          // normal | pre | nowrap | inherit
         if (id == CSSValueNormal ||
@@ -2010,13 +2009,21 @@ bool CSSParser::parseContent(int propId, bool important)
                 if (args->size() != 1)
                     return false;
                 CSSParserValue* a = args->current();
+                if (a->unit != CSSPrimitiveValue::CSS_IDENT)
+                    return false;
                 String attrName = a->string;
+                // CSS allows identifiers with "-" at the start, like "-webkit-mask-image".
+                // But HTML attribute names can't have those characters, and we should not
+                // even parse them inside attr().
+                if (attrName[0] == '-')
+                    return false;
                 if (document()->isHTMLDocument())
                     attrName = attrName.lower();
                 parsedValue = CSSPrimitiveValue::create(attrName, CSSPrimitiveValue::CSS_ATTR);
             } else if (equalIgnoringCase(val->function->name, "counter(")) {
                 parsedValue = parseCounterContent(args, false);
-                if (!parsedValue) return false;
+                if (!parsedValue)
+                    return false;
             } else if (equalIgnoringCase(val->function->name, "counters(")) {
                 parsedValue = parseCounterContent(args, true);
                 if (!parsedValue)
index 4bf6005..15c5a01 100644 (file)
@@ -754,9 +754,18 @@ String CSSPrimitiveValue::cssText() const
         case CSS_IDENT:
             text = valueOrPropertyName(m_value.ident);
             break;
-        case CSS_ATTR:
-            // FIXME
-            break;
+        case CSS_ATTR: {
+            DEFINE_STATIC_LOCAL(const String, attrParen, ("attr("));
+
+            Vector<UChar> result;
+            result.reserveInitialCapacity(6 + m_value.string->length());
+
+            append(result, attrParen);
+            append(result, m_value.string);
+            result.uncheckedAppend(')');
+
+            return String::adopt(result);
+        }
         case CSS_COUNTER:
             text = "counter(";
             text += String::number(m_value.num);