зеркало из https://github.com/mozilla/gecko-dev.git
Allow ParseAndAppendEscape to fail when the stream does not contain an escape, and make callers handle this failure appropriately. This changes our behavior when backslash immediately precedes end-of-stream. (Bug 384672, patch 3) r=bzbarsky
This commit is contained in:
Родитель
87048f5536
Коммит
18e5edff9c
|
@ -971,7 +971,11 @@ nsCSSScanner::NextURL(nsCSSToken& aToken)
|
||||||
ch = Read();
|
ch = Read();
|
||||||
if (ch < 0) break;
|
if (ch < 0) break;
|
||||||
if (ch == CSS_ESCAPE) {
|
if (ch == CSS_ESCAPE) {
|
||||||
ParseAndAppendEscape(ident, PR_FALSE);
|
if (!ParseAndAppendEscape(ident, PR_FALSE)) {
|
||||||
|
ok = PR_FALSE;
|
||||||
|
Pushback(ch);
|
||||||
|
break;
|
||||||
|
}
|
||||||
} else if (IsWhitespace(ch)) {
|
} else if (IsWhitespace(ch)) {
|
||||||
// Whitespace is allowed at the end of the URL
|
// Whitespace is allowed at the end of the URL
|
||||||
EatWhiteSpace();
|
EatWhiteSpace();
|
||||||
|
@ -1002,13 +1006,16 @@ nsCSSScanner::NextURL(nsCSSToken& aToken)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
/**
|
||||||
|
* Returns whether an escape was succesfully parsed; if it was not,
|
||||||
|
* the backslash needs to be its own symbol token.
|
||||||
|
*/
|
||||||
|
PRBool
|
||||||
nsCSSScanner::ParseAndAppendEscape(nsString& aOutput, PRBool aInString)
|
nsCSSScanner::ParseAndAppendEscape(nsString& aOutput, PRBool aInString)
|
||||||
{
|
{
|
||||||
PRInt32 ch = Peek();
|
PRInt32 ch = Peek();
|
||||||
if (ch < 0) {
|
if (ch < 0) {
|
||||||
aOutput.Append(CSS_ESCAPE);
|
return PR_FALSE;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
if (IsHexDigit(ch)) {
|
if (IsHexDigit(ch)) {
|
||||||
PRInt32 rv = 0;
|
PRInt32 rv = 0;
|
||||||
|
@ -1054,7 +1061,7 @@ nsCSSScanner::ParseAndAppendEscape(nsString& aOutput, PRBool aInString)
|
||||||
if (IsWhitespace(ch))
|
if (IsWhitespace(ch))
|
||||||
Pushback(ch);
|
Pushback(ch);
|
||||||
}
|
}
|
||||||
return;
|
return PR_TRUE;
|
||||||
}
|
}
|
||||||
// "Any character except a hexidecimal digit can be escaped to
|
// "Any character except a hexidecimal digit can be escaped to
|
||||||
// remove its special meaning by putting a backslash in front"
|
// remove its special meaning by putting a backslash in front"
|
||||||
|
@ -1063,6 +1070,8 @@ nsCSSScanner::ParseAndAppendEscape(nsString& aOutput, PRBool aInString)
|
||||||
if ((ch > 0) && (ch != '\n')) {
|
if ((ch > 0) && (ch != '\n')) {
|
||||||
aOutput.Append(ch);
|
aOutput.Append(ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return PR_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1080,7 +1089,9 @@ PRBool
|
||||||
nsCSSScanner::GatherIdent(PRInt32 aChar, nsString& aIdent)
|
nsCSSScanner::GatherIdent(PRInt32 aChar, nsString& aIdent)
|
||||||
{
|
{
|
||||||
if (aChar == CSS_ESCAPE) {
|
if (aChar == CSS_ESCAPE) {
|
||||||
ParseAndAppendEscape(aIdent, PR_FALSE);
|
if (!ParseAndAppendEscape(aIdent, PR_FALSE)) {
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (0 < aChar) {
|
else if (0 < aChar) {
|
||||||
aIdent.Append(aChar);
|
aIdent.Append(aChar);
|
||||||
|
@ -1107,7 +1118,10 @@ nsCSSScanner::GatherIdent(PRInt32 aChar, nsString& aIdent)
|
||||||
aChar = Read();
|
aChar = Read();
|
||||||
if (aChar < 0) break;
|
if (aChar < 0) break;
|
||||||
if (aChar == CSS_ESCAPE) {
|
if (aChar == CSS_ESCAPE) {
|
||||||
ParseAndAppendEscape(aIdent, PR_FALSE);
|
if (!ParseAndAppendEscape(aIdent, PR_FALSE)) {
|
||||||
|
Pushback(aChar);
|
||||||
|
break;
|
||||||
|
}
|
||||||
} else if (IsIdent(aChar)) {
|
} else if (IsIdent(aChar)) {
|
||||||
aIdent.Append(PRUnichar(aChar));
|
aIdent.Append(PRUnichar(aChar));
|
||||||
} else {
|
} else {
|
||||||
|
@ -1381,7 +1395,21 @@ nsCSSScanner::ParseString(PRInt32 aStop, nsCSSToken& aToken)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (ch == CSS_ESCAPE) {
|
if (ch == CSS_ESCAPE) {
|
||||||
ParseAndAppendEscape(aToken.mIdent, PR_TRUE);
|
if (!ParseAndAppendEscape(aToken.mIdent, PR_TRUE)) {
|
||||||
|
aToken.mType = eCSSToken_Bad_String;
|
||||||
|
Pushback(ch);
|
||||||
|
#ifdef CSS_REPORT_PARSE_ERRORS
|
||||||
|
// For strings, the only case where ParseAndAppendEscape will
|
||||||
|
// return false is when there's a backslash to start an escape
|
||||||
|
// immediately followed by end-of-stream. In that case, the
|
||||||
|
// correct tokenization is badstring *followed* by a DELIM for
|
||||||
|
// the backslash, but as far as the author is concerned, it
|
||||||
|
// works pretty much the same as an unterminated string, so we
|
||||||
|
// use the same error message.
|
||||||
|
ReportUnexpectedToken(aToken, "SEUnterminatedString");
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
aToken.mIdent.Append(ch);
|
aToken.mIdent.Append(ch);
|
||||||
}
|
}
|
||||||
|
|
|
@ -214,8 +214,8 @@ protected:
|
||||||
PRBool LookAhead(PRUnichar aChar);
|
PRBool LookAhead(PRUnichar aChar);
|
||||||
PRBool LookAheadOrEOF(PRUnichar aChar); // expect either aChar or EOF
|
PRBool LookAheadOrEOF(PRUnichar aChar); // expect either aChar or EOF
|
||||||
void EatWhiteSpace();
|
void EatWhiteSpace();
|
||||||
|
|
||||||
void ParseAndAppendEscape(nsString& aOutput, PRBool aInString);
|
PRBool ParseAndAppendEscape(nsString& aOutput, PRBool aInString);
|
||||||
PRBool ParseIdent(PRInt32 aChar, nsCSSToken& aResult);
|
PRBool ParseIdent(PRInt32 aChar, nsCSSToken& aResult);
|
||||||
PRBool ParseAtKeyword(PRInt32 aChar, nsCSSToken& aResult);
|
PRBool ParseAtKeyword(PRInt32 aChar, nsCSSToken& aResult);
|
||||||
PRBool ParseNumber(PRInt32 aChar, nsCSSToken& aResult);
|
PRBool ParseNumber(PRInt32 aChar, nsCSSToken& aResult);
|
||||||
|
|
|
@ -915,6 +915,9 @@ function run() {
|
||||||
test_balanced_unparseable("p #, p");
|
test_balanced_unparseable("p #, p");
|
||||||
test_balanced_unparseable("p # , p");
|
test_balanced_unparseable("p # , p");
|
||||||
|
|
||||||
|
// Test that a backslash alone is not treated as an escape.
|
||||||
|
test_unparseable_via_api("#\\");
|
||||||
|
|
||||||
run_deferred_tests();
|
run_deferred_tests();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче