Bug 393286: Make nsCSSScanner::Read regularize newlines. r+sr=bzbarsky, a=dbaron

This commit is contained in:
sharparrow1@yahoo.com 2007-08-23 16:01:52 -07:00
parent 607bb2be78
commit f6d7f34d38
2 changed files with 34 additions and 36 deletions

View File

@ -288,7 +288,6 @@ void nsCSSScanner::Init(nsIUnicharInputStream* aInput,
// Reset variables that we use to keep track of our progress through the input
mOffset = 0;
mPushbackCount = 0;
mLastRead = 0;
#ifdef CSS_REPORT_PARSE_ERRORS
mColNumber = 0;
@ -466,6 +465,24 @@ void nsCSSScanner::Close()
#define TAB_STOP_WIDTH 8
#endif
PRBool nsCSSScanner::EnsureData(nsresult& aErrorCode)
{
if (mOffset < mCount)
return PR_TRUE;
if (mInputStream) {
mOffset = 0;
aErrorCode = mInputStream->Read(mBuffer, CSS_BUFFER_SIZE, &mCount);
if (NS_FAILED(aErrorCode) || mCount == 0) {
mCount = 0;
return PR_FALSE;
}
return PR_TRUE;
}
return PR_FALSE;
}
// Returns -1 on error or eof
PRInt32 nsCSSScanner::Read(nsresult& aErrorCode)
{
@ -473,20 +490,21 @@ PRInt32 nsCSSScanner::Read(nsresult& aErrorCode)
if (0 < mPushbackCount) {
rv = PRInt32(mPushback[--mPushbackCount]);
} else {
if (mOffset == mCount) {
mOffset = 0;
if (!mInputStream) {
mCount = 0;
return -1;
}
aErrorCode = mInputStream->Read(mBuffer, CSS_BUFFER_SIZE, &mCount);
if (NS_FAILED(aErrorCode) || mCount == 0) {
mCount = 0;
return -1;
}
if (mOffset == mCount && !EnsureData(aErrorCode)) {
return -1;
}
rv = PRInt32(mReadPointer[mOffset++]);
if (((rv == '\n') && (mLastRead != '\r')) || (rv == '\r')) {
// There are four types of newlines in CSS: "\r", "\n", "\r\n", and "\f".
// To simplify dealing with newlines, they are all normalized to "\n" here
if (rv == '\r') {
if (EnsureData(aErrorCode) && mReadPointer[mOffset] == '\n') {
mOffset++;
}
rv = '\n';
} else if (rv == '\f') {
rv = '\n';
}
if (rv == '\n') {
// 0 is a magical line number meaning that we don't know (i.e., script)
if (mLineNumber != 0)
++mLineNumber;
@ -503,7 +521,6 @@ PRInt32 nsCSSScanner::Read(nsresult& aErrorCode)
}
#endif
}
mLastRead = rv;
//printf("Read => %x\n", rv);
return rv;
}
@ -511,9 +528,7 @@ PRInt32 nsCSSScanner::Read(nsresult& aErrorCode)
PRInt32 nsCSSScanner::Peek(nsresult& aErrorCode)
{
if (0 == mPushbackCount) {
PRInt32 savedLastRead = mLastRead;
PRInt32 ch = Read(aErrorCode);
mLastRead = savedLastRead;
if (ch < 0) {
return -1;
}
@ -562,7 +577,7 @@ PRBool nsCSSScanner::EatWhiteSpace(nsresult& aErrorCode)
if (ch < 0) {
break;
}
if ((ch == ' ') || (ch == '\n') || (ch == '\r') || (ch == '\t')) {
if ((ch == ' ') || (ch == '\n') || (ch == '\t')) {
eaten = PR_TRUE;
continue;
}
@ -579,13 +594,7 @@ PRBool nsCSSScanner::EatNewline(nsresult& aErrorCode)
return PR_FALSE;
}
PRBool eaten = PR_FALSE;
if (ch == '\r') {
eaten = PR_TRUE;
ch = Peek(aErrorCode);
if (ch == '\n') {
(void) Read(aErrorCode);
}
} else if (ch == '\n') {
if (ch == '\n') {
eaten = PR_TRUE;
} else {
Pushback(ch);
@ -862,10 +871,6 @@ nsCSSScanner::ParseAndAppendEscape(nsresult& aErrorCode, nsString& aOutput)
} else {
NS_ASSERTION((lexTable[ch] & IS_WHITESPACE) != 0, "bad control flow");
// single space ends escape
if (ch == '\r' && Peek(aErrorCode) == '\n') {
// if CR/LF, eat LF too
Read(aErrorCode);
}
break;
}
}
@ -874,13 +879,6 @@ nsCSSScanner::ParseAndAppendEscape(nsresult& aErrorCode, nsString& aOutput)
if ((0 <= ch) && (ch <= 255) &&
((lexTable[ch] & IS_WHITESPACE) != 0)) {
ch = Read(aErrorCode);
// special case: if trailing whitespace is CR/LF, eat both chars (not part of spec, but should be)
if (ch == '\r') {
ch = Peek(aErrorCode);
if (ch == '\n') {
ch = Read(aErrorCode);
}
}
}
}
NS_ASSERTION(rv >= 0, "How did rv become negative?");

View File

@ -198,6 +198,7 @@ class nsCSSScanner {
}
protected:
PRBool EnsureData(nsresult& aErrorCode);
PRInt32 Read(nsresult& aErrorCode);
PRInt32 Peek(nsresult& aErrorCode);
void Pushback(PRUnichar aChar);
@ -230,7 +231,6 @@ protected:
PRUnichar* mPushback;
PRInt32 mPushbackCount;
PRInt32 mPushbackSize;
PRInt32 mLastRead;
PRUnichar mLocalPushback[4];
PRUint32 mLineNumber;