diff --git a/mozilla/parser/htmlparser/src/CNavDTD.cpp b/mozilla/parser/htmlparser/src/CNavDTD.cpp
index e7110037fe3..a084c2c65ca 100644
--- a/mozilla/parser/htmlparser/src/CNavDTD.cpp
+++ b/mozilla/parser/htmlparser/src/CNavDTD.cpp
@@ -2423,7 +2423,15 @@ nsresult CNavDTD::CollectAttributes(nsIParserNode *aNode,eHTMLTags aTag,PRInt32
// a legitimate "SELECTED" key.
((CAttributeToken*)theToken)->SanitizeKey();
- aNode->AddAttribute(theToken);
+ // If the key is empty, the attribute is unusable, so we should not
+ // add it to the node.
+ if (!((CAttributeToken*)theToken)->GetKey().IsEmpty()) {
+ aNode->AddAttribute(theToken);
+ } else {
+ IF_FREE(theToken, mTokenAllocator);
+ }
+ } else {
+ IF_FREE(theToken, mTokenAllocator);
}
}
}
diff --git a/mozilla/parser/htmlparser/src/nsHTMLTokens.cpp b/mozilla/parser/htmlparser/src/nsHTMLTokens.cpp
index acc862124c6..c3b0dda7c59 100644
--- a/mozilla/parser/htmlparser/src/nsHTMLTokens.cpp
+++ b/mozilla/parser/htmlparser/src/nsHTMLTokens.cpp
@@ -1627,6 +1627,34 @@ nsresult ConsumeQuotedString(PRUnichar aChar,
return result;
}
+/*
+ * This method is meant to be used by view-source to consume invalid attributes.
+ * For the purposes of this method, an invalid attribute is an attribute that
+ * starts with either ' or ". We consume all ' or " and the following whitespace.
+ *
+ * @param aScanner -- the scanner we're reading our data from.
+ * @param aChar -- the character we're skipping
+ * @param aCurrent -- the current position that we're looking at.
+ * @param aNewlineCount -- a count of the newlines we've consumed.
+ * @return error result.
+ */
+static
+nsresult ConsumeInvalidAttribute(nsScanner& aScanner,
+ PRUnichar aChar,
+ nsScannerIterator& aCurrent,
+ PRInt32& aNewlineCount) {
+ NS_ASSERTION(aChar=='\'' || aChar=='"', "aChar must be a quote or apostrophe");
+ nsScannerIterator end, wsbeg;
+ aScanner.EndReading(end);
+
+ while (aCurrent!=end && *aCurrent==aChar) {
+ ++aCurrent;
+ }
+
+ aScanner.SetPosition(aCurrent);
+ return aScanner.ReadWhitespace(wsbeg,aCurrent,aNewlineCount);
+}
+
/*
* Consume the key and value portions of the attribute.
*
@@ -1655,7 +1683,8 @@ nsresult CAttributeToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 a
PRUnichar('='), PRUnichar('\n'),
PRUnichar('\r'), PRUnichar('\t'),
PRUnichar('>'), PRUnichar('<'),
- PRUnichar('\b'), PRUnichar(0) };
+ PRUnichar('\b'), PRUnichar('\''),
+ PRUnichar(0) };
static const nsReadEndCondition theEndCondition(theTerminalsChars);
nsScannerIterator start, end;
@@ -1747,12 +1776,20 @@ nsresult CAttributeToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 a
//My best guess is to grab the next non-ws char. We know it's not '=',
//so let's see what it is. If it's a '"', then assume we're reading
//from the middle of the value. Try stripping the quote and continuing...
- if (kQuote==aChar){
+ if (kQuote==aChar || kApostrophe==aChar){
+
if (!(aFlag & NS_IPARSER_FLAG_VIEW_SOURCE)) {
result=aScanner.SkipOver(aChar); //strip quote.
+ if (NS_SUCCEEDED(result)) {
+ result=aScanner.SkipWhitespace(mNewlineCount);
+ }
} else {
- aScanner.BindSubstring(mTextKey, wsstart, ++wsend);
- // I've just incremented wsend.
+ //We want to collect whitespace here so that following
+ //attributes can have the right line number (and for
+ //parity with the non-view-source code above).
+ result=ConsumeInvalidAttribute(aScanner,aChar,wsend,mNewlineCount);
+
+ aScanner.BindSubstring(mTextKey, wsstart, wsend);
aScanner.SetPosition(wsend);
}
}
@@ -1762,17 +1799,17 @@ nsresult CAttributeToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 a
}//if (consume optional value)
if (NS_OK==result) {
- result=aScanner.Peek(aChar);
-
if (mTextValue.Length() == 0 && mTextKey.Length() == 0 &&
- aChar == kLessThan) {
- // This attribute is completely bogus, tell the tokenizer.
- // This happens when we have stuff like:
- // ....
+ mNewlineCount == 0) {
+ //This attribute contains no useful information for us, so there is no
+ //use in keeping it around. Attributes that are otherwise empty, but
+ //have newlines in them are passed on the the DTD so it can get line
+ //numbering right.
return NS_ERROR_HTMLPARSER_BADATTRIBUTE;
}
#ifdef DEBUG
+ result = aScanner.Peek(aChar);
mLastAttribute = (kGreaterThan == aChar || kEOF == result);
#endif
}