Do string appending in chunks rather than one character at a time in GatherIdent and ParseString. Allow EOF to terminate strings, per CSS 2.1. b=311566 Patch by Alfred Kayser <alfredkayser@gmail.com>, with some review comments addressed by me. r+sr=dbaron a=blocking1.9+

This commit is contained in:
dbaron@dbaron.org 2008-02-21 17:37:04 -08:00
parent cc759b645a
commit 8fe3b28ddb
2 changed files with 54 additions and 12 deletions

View File

@ -909,6 +909,24 @@ PRBool nsCSSScanner::GatherIdent(nsresult& aErrorCode, PRInt32 aChar,
aIdent.Append(aChar);
}
for (;;) {
// If nothing in pushback, first try to get as much as possible in one go
if (!mPushbackCount && EnsureData(aErrorCode)) {
// See how much we can consume and append in one go
PRUint32 n = mOffset;
// Count number of Ident characters that can be processed
while (n < mCount && IsIdent(mReadPointer[n])) {
++n;
}
// Add to the token what we have so far
if (n > mOffset) {
#ifdef CSS_REPORT_PARSE_ERRORS
mColNumber += n - mOffset;
#endif
aIdent.Append(&mReadPointer[mOffset], n - mOffset);
mOffset = n;
}
}
aChar = Read(aErrorCode);
if (aChar < 0) break;
if (aChar == CSS_ESCAPE) {
@ -1106,24 +1124,46 @@ PRBool nsCSSScanner::ParseString(nsresult& aErrorCode, PRInt32 aStop,
aToken.mType = eCSSToken_String;
aToken.mSymbol = PRUnichar(aStop); // remember how it's quoted
for (;;) {
if (EatNewline(aErrorCode)) {
// If nothing in pushback, first try to get as much as possible in one go
if (!mPushbackCount && EnsureData(aErrorCode)) {
// See how much we can consume and append in one go
PRUint32 n = mOffset;
// Count number of characters that can be processed
for (;n < mCount; ++n) {
PRUnichar nextChar = mReadPointer[n];
if ((nextChar == aStop) || (nextChar == CSS_ESCAPE) ||
(nextChar == '\n') || (nextChar == '\r') || (nextChar == '\f')) {
break;
}
#ifdef CSS_REPORT_PARSE_ERRORS
if (nextChar == '\t') {
mColNumber = ((mColNumber - 1 + TAB_STOP_WIDTH) / TAB_STOP_WIDTH)
* TAB_STOP_WIDTH;
} else {
++mColNumber;
}
#endif
}
// Add to the token what we have so far
if (n > mOffset) {
aToken.mIdent.Append(&mReadPointer[mOffset], n - mOffset);
mOffset = n;
}
}
PRInt32 ch = Read(aErrorCode);
if (ch < 0 || ch == aStop) {
break;
}
if (ch == '\n') {
aToken.mType = eCSSToken_Error;
#ifdef CSS_REPORT_PARSE_ERRORS
ReportUnexpectedToken(aToken, "SEUnterminatedString");
#endif
return PR_TRUE;
}
PRInt32 ch = Read(aErrorCode);
if (ch < 0) {
return PR_FALSE;
}
if (ch == aStop) {
break;
}
if (ch == CSS_ESCAPE) {
ParseAndAppendEscape(aErrorCode, aToken.mIdent);
}
else if (0 < ch) {
} else {
aToken.mIdent.Append(ch);
}
}

View File

@ -70,6 +70,9 @@ base + "//asdf.zxcv,\n#a {color: red}",
base + "p {text-indent: 0.5in;} color: maroon #a {color: red;}",
base + "p {text-indent: 0.5in;} color: maroon; #a {color: red;}",
// string tokenization as error token, not EOF (bug 311566 comment 70)
"#a { color: green; foo: { \"bar\n;color: red}",
// CSS 2.1 section 4.1.3
"@MediA All {#a {ColOR :RgB(\t0,\r128,\n0 ) } };",
base + "\\#a{color:red;}",
@ -179,8 +182,7 @@ base + "#a:: before {content: 'FAIL'}",
base + "#a ::before {content: 'FAIL'}",
"#a::before {content: 'This is \\a",
], prop: "content", pseudo: "::before",
todo: {"#a::before {content: 'This is \\a" : 1}
], prop: "content", pseudo: "::before"
},
// Background color tests