Make sure that CSS escapes don't introduce UTF16 surrogates into the character

stream.  Bug 316394 final patch, r=smontagu, sr=dbaron
This commit is contained in:
bzbarsky%mit.edu 2005-11-17 15:17:00 +00:00
parent 11d61012cd
commit 2f2723c575
2 changed files with 23 additions and 26 deletions

View File

@ -786,10 +786,7 @@ PRBool nsCSSScanner::NextURL(nsresult& aErrorCode, nsCSSToken& aToken)
ch = Read(aErrorCode); ch = Read(aErrorCode);
if (ch < 0) break; if (ch < 0) break;
if (ch == CSS_ESCAPE) { if (ch == CSS_ESCAPE) {
ch = ParseEscape(aErrorCode); ParseAndAppendEscape(aErrorCode, ident);
if (0 < ch) {
ident.Append(PRUnichar(ch));
}
} else if ((ch == '"') || (ch == '\'') || (ch == '(')) { } else if ((ch == '"') || (ch == '\'') || (ch == '(')) {
// This is an invalid URL spec // This is an invalid URL spec
ok = PR_FALSE; ok = PR_FALSE;
@ -825,12 +822,14 @@ PRBool nsCSSScanner::NextURL(nsresult& aErrorCode, nsCSSToken& aToken)
} }
PRInt32 nsCSSScanner::ParseEscape(nsresult& aErrorCode) void
nsCSSScanner::ParseAndAppendEscape(nsresult& aErrorCode, nsString& aOutput)
{ {
PRUint8* lexTable = gLexTable; PRUint8* lexTable = gLexTable;
PRInt32 ch = Peek(aErrorCode); PRInt32 ch = Peek(aErrorCode);
if (ch < 0) { if (ch < 0) {
return CSS_ESCAPE; aOutput.Append(CSS_ESCAPE);
return;
} }
if ((ch <= 255) && ((lexTable[ch] & IS_HEX_DIGIT) != 0)) { if ((ch <= 255) && ((lexTable[ch] & IS_HEX_DIGIT) != 0)) {
PRInt32 rv = 0; PRInt32 rv = 0;
@ -877,18 +876,22 @@ PRInt32 nsCSSScanner::ParseEscape(nsresult& aErrorCode)
} }
} }
} }
return rv; NS_ASSERTION(rv >= 0, "How did rv become negative?");
if (rv > 0) {
AppendUCS4ToUTF16(ENSURE_VALID_CHAR(rv), aOutput);
}
return;
} else { } else {
// "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"
// -- CSS1 spec section 7.1 // -- CSS1 spec section 7.1
if (EatNewline(aErrorCode)) { // skip escaped newline if (!EatNewline(aErrorCode)) { // skip escaped newline
ch = 0;
}
else {
(void) Read(aErrorCode); (void) Read(aErrorCode);
if (ch > 0) {
aOutput.Append(ch);
}
} }
return ch; return;
} }
} }
@ -903,19 +906,16 @@ PRBool nsCSSScanner::GatherIdent(nsresult& aErrorCode, PRInt32 aChar,
nsString& aIdent) nsString& aIdent)
{ {
if (aChar == CSS_ESCAPE) { if (aChar == CSS_ESCAPE) {
aChar = ParseEscape(aErrorCode); ParseAndAppendEscape(aErrorCode, aIdent);
} }
if (0 < aChar) { else if (0 < aChar) {
aIdent.Append(PRUnichar(aChar)); aIdent.Append(aChar);
} }
for (;;) { for (;;) {
aChar = Read(aErrorCode); aChar = Read(aErrorCode);
if (aChar < 0) break; if (aChar < 0) break;
if (aChar == CSS_ESCAPE) { if (aChar == CSS_ESCAPE) {
aChar = ParseEscape(aErrorCode); ParseAndAppendEscape(aErrorCode, aIdent);
if (0 < aChar) {
aIdent.Append(PRUnichar(aChar));
}
} else if ((aChar > 255) || ((gLexTable[aChar] & IS_IDENT) != 0)) { } else if ((aChar > 255) || ((gLexTable[aChar] & IS_IDENT) != 0)) {
aIdent.Append(PRUnichar(aChar)); aIdent.Append(PRUnichar(aChar));
} else { } else {
@ -1125,13 +1125,10 @@ PRBool nsCSSScanner::ParseString(nsresult& aErrorCode, PRInt32 aStop,
break; break;
} }
if (ch == CSS_ESCAPE) { if (ch == CSS_ESCAPE) {
ch = ParseEscape(aErrorCode); ParseAndAppendEscape(aErrorCode, aToken.mIdent);
if (ch < 0) {
return PR_FALSE;
}
} }
if (0 < ch) { else if (0 < ch) {
aToken.mIdent.Append(PRUnichar(ch)); aToken.mIdent.Append(ch);
} }
} }
return PR_TRUE; return PR_TRUE;

View File

@ -203,7 +203,7 @@ protected:
PRBool EatWhiteSpace(nsresult& aErrorCode); PRBool EatWhiteSpace(nsresult& aErrorCode);
PRBool EatNewline(nsresult& aErrorCode); PRBool EatNewline(nsresult& aErrorCode);
PRInt32 ParseEscape(nsresult& aErrorCode); void ParseAndAppendEscape(nsresult& aErrorCode, nsString& aOutput);
PRBool ParseIdent(nsresult& aErrorCode, PRInt32 aChar, nsCSSToken& aResult); PRBool ParseIdent(nsresult& aErrorCode, PRInt32 aChar, nsCSSToken& aResult);
PRBool ParseAtKeyword(nsresult& aErrorCode, PRInt32 aChar, PRBool ParseAtKeyword(nsresult& aErrorCode, PRInt32 aChar,
nsCSSToken& aResult); nsCSSToken& aResult);