Commit 37ae718c authored by yoav@yoav.ws's avatar yoav@yoav.ws

Fixed MediaQueryTokenizer escape support

MediaQueryTokenizer handling of escapes was faulty, causing media queries with escaped code points to be considered invalid.
This CL fixes that.

BUG=358833

Review URL: https://codereview.chromium.org/221383003

git-svn-id: svn://svn.chromium.org/blink/trunk@170704 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 8b3a961f
......@@ -118,6 +118,10 @@ TEST(MediaQueryParserTest, Basic)
{"all and (orientation:landscape)", "(orientation: landscape)", true},
{"NOT braille, tv AND (max-width: 200px) and (min-WIDTH: 100px) and (orientation: landscape), (color)",
"not braille, tv and (max-width: 200px) and (min-width: 100px) and (orientation: landscape), (color)", true},
{"(m\\61x-width: 300px)", "(max-width: 300px)", true},
{"(max-width: 400\\70\\78)", "(max-width: 400px)", false},
{"(max-width: 500\\0070\\0078)", "(max-width: 500px)", false},
{"(max-width: 600\\000070\\000078)", "(max-width: 600px)", false},
{"(max-width: 700px), (max-width: 700px)", "(max-width: 700px), (max-width: 700px)", true},
{"(max-width: 800px()), (max-width: 800px)", "not all, (max-width: 800px)", true},
{"(max-width: 900px(()), (max-width: 900px)", "not all", true},
......
......@@ -353,20 +353,19 @@ String MediaQueryTokenizer::consumeName()
{
// FIXME: Is this as efficient as it can be?
// The possibility of escape chars mandates a copy AFAICT.
Vector<UChar> result;
StringBuilder result;
while (true) {
if (isNameChar(m_input.currentInputChar())) {
result.append(consume());
UChar cc = consume();
if (isNameChar(cc)) {
result.append(cc);
continue;
}
if (nextTwoCharsAreValidEscape()) {
// "consume()" fixes a spec bug.
// The first code point should be consumed before consuming the escaped code point.
consume();
if (twoCharsAreValidEscape(cc, m_input.currentInputChar())) {
result.append(consumeEscape());
continue;
}
return String(result);
reconsume(cc);
return result.toString();
}
}
......@@ -377,14 +376,15 @@ UChar MediaQueryTokenizer::consumeEscape()
ASSERT(cc != '\n');
if (isASCIIHexDigit(cc)) {
unsigned consumedHexDigits = 1;
String hexChars;
do {
hexChars.append(cc);
StringBuilder hexChars;
hexChars.append(cc);
while (consumedHexDigits < 6 && isASCIIHexDigit(m_input.currentInputChar())) {
cc = consume();
hexChars.append(cc);
consumedHexDigits++;
} while (consumedHexDigits < 6 && isASCIIHexDigit(cc));
};
bool ok = false;
UChar codePoint = hexChars.toUIntStrict(&ok, 16);
UChar codePoint = hexChars.toString().toUIntStrict(&ok, 16);
if (!ok)
return WTF::Unicode::replacementCharacter;
return codePoint;
......@@ -396,11 +396,11 @@ UChar MediaQueryTokenizer::consumeEscape()
return cc;
}
bool MediaQueryTokenizer::nextTwoCharsAreValidEscape()
bool MediaQueryTokenizer::nextTwoCharsAreValidEscape(unsigned offset)
{
if (m_input.leftChars() < 2)
if (m_input.leftChars() < offset + 1)
return false;
return twoCharsAreValidEscape(m_input.peek(1), m_input.peek(2));
return twoCharsAreValidEscape(m_input.peek(offset), m_input.peek(offset + 1));
}
// http://www.w3.org/TR/css3-syntax/#starts-with-a-number
......@@ -421,13 +421,13 @@ bool MediaQueryTokenizer::nextCharsAreNumber()
bool MediaQueryTokenizer::nextCharsAreIdentifier()
{
UChar firstChar = m_input.currentInputChar();
if (isNameStart(firstChar) || nextTwoCharsAreValidEscape())
if (isNameStart(firstChar) || nextTwoCharsAreValidEscape(0))
return true;
if (firstChar == '-') {
if (isNameStart(m_input.peek(1)))
return true;
return nextTwoCharsAreValidEscape();
return nextTwoCharsAreValidEscape(1);
}
return false;
......
......@@ -40,7 +40,7 @@ private:
String consumeName();
UChar consumeEscape();
bool nextTwoCharsAreValidEscape();
bool nextTwoCharsAreValidEscape(unsigned offset);
bool nextCharsAreNumber();
bool nextCharsAreIdentifier();
......
......@@ -19,6 +19,7 @@ TEST(MediaQueryTokenizerTest, Basic)
{
TestCase testCases[] = {
{ "(max-width: 50px)", "(max-width: 50px)" },
{ "(max-width: 50\\70\\78)", "(max-width: 50px)" },
{ "(max-width: /* comment */50px)", "(max-width: 50px)" },
{ "(max-width: /** *commen*t */60px)", "(max-width: 60px)" },
{ "(max-width: /** *commen*t **/70px)", "(max-width: 70px)" },
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment