зеркало из https://github.com/mozilla/gecko-dev.git
Improved NS_ERROR_OUT_OF_MEMORY error handling. b=354074 r=mrbkap sr=jst
This commit is contained in:
Родитель
6d59aea94b
Коммит
e5b2a2562a
|
@ -371,6 +371,7 @@ CNavDTD::BuildNeglectedTarget(eHTMLTags aTarget,
|
|||
}
|
||||
|
||||
CToken* target = mTokenAllocator->CreateTokenOfType(aType, aTarget);
|
||||
NS_ENSURE_TRUE(target, NS_ERROR_OUT_OF_MEMORY);
|
||||
mTokenizer->PushTokenFront(target);
|
||||
return BuildModel(aParser, mTokenizer, 0, aSink);
|
||||
}
|
||||
|
@ -1156,10 +1157,7 @@ CNavDTD::HandleKeyGen(nsIParserNode* aNode)
|
|||
// <OPTION>s and </SELECT>.
|
||||
theToken = mTokenAllocator->CreateTokenOfType(eToken_end,
|
||||
eHTMLTag_select);
|
||||
if (!theToken) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
NS_ENSURE_TRUE(theToken, NS_ERROR_OUT_OF_MEMORY);
|
||||
mTokenizer->PushTokenFront(theToken);
|
||||
|
||||
for (theIndex = theContent.Count()-1; theIndex > -1; --theIndex) {
|
||||
|
@ -1167,16 +1165,12 @@ CNavDTD::HandleKeyGen(nsIParserNode* aNode)
|
|||
theToken = mTokenAllocator->CreateTokenOfType(eToken_text,
|
||||
eHTMLTag_text,
|
||||
*theTextValue);
|
||||
if (!theToken) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
NS_ENSURE_TRUE(theToken, NS_ERROR_OUT_OF_MEMORY);
|
||||
mTokenizer->PushTokenFront(theToken);
|
||||
|
||||
theToken = mTokenAllocator->CreateTokenOfType(eToken_start,
|
||||
eHTMLTag_option);
|
||||
if (!theToken) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
NS_ENSURE_TRUE(theToken, NS_ERROR_OUT_OF_MEMORY);
|
||||
mTokenizer->PushTokenFront(theToken);
|
||||
}
|
||||
|
||||
|
@ -1186,9 +1180,7 @@ CNavDTD::HandleKeyGen(nsIParserNode* aNode)
|
|||
theToken = mTokenAllocator->CreateTokenOfType(eToken_attribute,
|
||||
eHTMLTag_unknown,
|
||||
theAttribute);
|
||||
if (!theToken) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
NS_ENSURE_TRUE(theToken, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
((CAttributeToken*)theToken)->SetKey(NS_LITERAL_STRING("_moz-type"));
|
||||
mTokenizer->PushTokenFront(theToken);
|
||||
|
@ -1202,6 +1194,7 @@ CNavDTD::HandleKeyGen(nsIParserNode* aNode)
|
|||
|
||||
theToken = mTokenAllocator->CreateTokenOfType(eToken_start,
|
||||
eHTMLTag_select);
|
||||
NS_ENSURE_TRUE(theToken, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
// Increment the count because of the additional attribute from the form processor.
|
||||
theToken->SetAttributeCount(theAttrCount + 1);
|
||||
|
@ -1238,6 +1231,7 @@ CNavDTD::HandleStartToken(CToken* aToken)
|
|||
NS_PRECONDITION(nsnull != aToken, kNullToken);
|
||||
|
||||
nsCParserNode* theNode = mNodeAllocator.CreateNode(aToken, mTokenAllocator);
|
||||
NS_ENSURE_TRUE(theNode, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
eHTMLTags theChildTag = (eHTMLTags)aToken->GetTypeID();
|
||||
PRInt16 attrCount = aToken->GetAttributeCount();
|
||||
|
@ -1646,6 +1640,7 @@ CNavDTD::HandleEndToken(CToken* aToken)
|
|||
if (!CanOmit(theParentTag, theChildTag, theParentContains)) {
|
||||
CToken* theStartToken =
|
||||
mTokenAllocator->CreateTokenOfType(eToken_start, theChildTag);
|
||||
NS_ENSURE_TRUE(theStartToken, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
// This check for NS_DTD_FLAG_IN_MISPLACED_CONTENT was added
|
||||
// to fix bug 142965.
|
||||
|
@ -1831,9 +1826,7 @@ CNavDTD::HandleEntityToken(CToken* aToken)
|
|||
entityName.Append(theStr);
|
||||
theToken = mTokenAllocator->CreateTokenOfType(eToken_text, eHTMLTag_text,
|
||||
entityName);
|
||||
if (!theToken) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
NS_ENSURE_TRUE(theToken, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
// theToken should get recycled automagically...
|
||||
return HandleToken(theToken, mParser);
|
||||
|
@ -1841,17 +1834,16 @@ CNavDTD::HandleEntityToken(CToken* aToken)
|
|||
|
||||
eHTMLTags theParentTag = mBodyContext->Last();
|
||||
nsCParserNode* theNode = mNodeAllocator.CreateNode(aToken, mTokenAllocator);
|
||||
NS_ENSURE_TRUE(theNode, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
if (theNode) {
|
||||
PRBool theParentContains = -1;
|
||||
if (CanOmit(theParentTag, eHTMLTag_entity, theParentContains)) {
|
||||
eHTMLTags theCurrTag = (eHTMLTags)aToken->GetTypeID();
|
||||
HandleOmittedTag(aToken, theCurrTag, theParentTag, theNode);
|
||||
} else {
|
||||
result = AddLeaf(theNode);
|
||||
}
|
||||
IF_FREE(theNode, &mNodeAllocator);
|
||||
PRBool theParentContains = -1;
|
||||
if (CanOmit(theParentTag, eHTMLTag_entity, theParentContains)) {
|
||||
eHTMLTags theCurrTag = (eHTMLTags)aToken->GetTypeID();
|
||||
HandleOmittedTag(aToken, theCurrTag, theParentTag, theNode);
|
||||
} else {
|
||||
result = AddLeaf(theNode);
|
||||
}
|
||||
IF_FREE(theNode, &mNodeAllocator);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -1870,23 +1862,18 @@ CNavDTD::HandleCommentToken(CToken* aToken)
|
|||
{
|
||||
NS_PRECONDITION(nsnull != aToken, kNullToken);
|
||||
|
||||
nsresult result = NS_OK;
|
||||
|
||||
nsCParserNode* theNode = mNodeAllocator.CreateNode(aToken, mTokenAllocator);
|
||||
NS_ENSURE_TRUE(theNode, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
if (theNode) {
|
||||
STOP_TIMER();
|
||||
MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::HandleCommentToken(), this=%p\n", this));
|
||||
STOP_TIMER();
|
||||
MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::HandleCommentToken(), this=%p\n", this));
|
||||
|
||||
result = mSink
|
||||
? mSink->AddComment(*theNode)
|
||||
: NS_OK;
|
||||
nsresult result = mSink ? mSink->AddComment(*theNode) : NS_OK;
|
||||
|
||||
IF_FREE(theNode, &mNodeAllocator);
|
||||
IF_FREE(theNode, &mNodeAllocator);
|
||||
|
||||
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::HandleCommentToken(), this=%p\n", this));
|
||||
START_TIMER();
|
||||
}
|
||||
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::HandleCommentToken(), this=%p\n", this));
|
||||
START_TIMER();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -1922,24 +1909,19 @@ CNavDTD::HandleProcessingInstructionToken(CToken* aToken)
|
|||
{
|
||||
NS_PRECONDITION(nsnull != aToken, kNullToken);
|
||||
|
||||
nsresult result = NS_OK;
|
||||
|
||||
nsCParserNode* theNode = mNodeAllocator.CreateNode(aToken, mTokenAllocator);
|
||||
NS_ENSURE_TRUE(theNode, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
if (theNode) {
|
||||
STOP_TIMER();
|
||||
MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::HandleProcessingInstructionToken(), this=%p\n", this));
|
||||
STOP_TIMER();
|
||||
MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::HandleProcessingInstructionToken(), this=%p\n", this));
|
||||
|
||||
result = mSink
|
||||
? mSink->AddProcessingInstruction(*theNode)
|
||||
: NS_OK;
|
||||
nsresult result = mSink ? mSink->AddProcessingInstruction(*theNode) : NS_OK;
|
||||
|
||||
IF_FREE(theNode, &mNodeAllocator);
|
||||
IF_FREE(theNode, &mNodeAllocator);
|
||||
|
||||
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::HandleProcessingInstructionToken(), this=%p\n", this));
|
||||
START_TIMER();
|
||||
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::HandleProcessingInstructionToken(), this=%p\n", this));
|
||||
START_TIMER();
|
||||
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -1956,8 +1938,6 @@ CNavDTD::HandleDocTypeDeclToken(CToken* aToken)
|
|||
{
|
||||
NS_PRECONDITION(nsnull != aToken, kNullToken);
|
||||
|
||||
nsresult result = NS_OK;
|
||||
|
||||
CDoctypeDeclToken* theToken = NS_STATIC_CAST(CDoctypeDeclToken*, aToken);
|
||||
nsAutoString docTypeStr(theToken->GetStringValue());
|
||||
// XXX Doesn't this count the newlines twice?
|
||||
|
@ -1977,19 +1957,17 @@ CNavDTD::HandleDocTypeDeclToken(CToken* aToken)
|
|||
theToken->SetStringValue(docTypeStr);
|
||||
|
||||
nsCParserNode* theNode = mNodeAllocator.CreateNode(aToken, mTokenAllocator);
|
||||
if (theNode) {
|
||||
STOP_TIMER();
|
||||
MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::HandleDocTypeDeclToken(), this=%p\n", this));
|
||||
NS_ENSURE_TRUE(theNode, NS_ERROR_OUT_OF_MEMORY);
|
||||
STOP_TIMER();
|
||||
MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::HandleDocTypeDeclToken(), this=%p\n", this));
|
||||
|
||||
result = mSink
|
||||
? mSink->AddDocTypeDecl(*theNode)
|
||||
: NS_OK;
|
||||
nsresult result = mSink ? mSink->AddDocTypeDecl(*theNode) : NS_OK;
|
||||
|
||||
IF_FREE(theNode, &mNodeAllocator);
|
||||
IF_FREE(theNode, &mNodeAllocator);
|
||||
|
||||
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::HandleDocTypeDeclToken(), this=%p\n", this));
|
||||
START_TIMER();
|
||||
|
||||
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::HandleDocTypeDeclToken(), this=%p\n", this));
|
||||
START_TIMER();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -646,7 +646,7 @@ nsHTMLTokenizer::ConsumeAttributes(PRUnichar aChar,
|
|||
NS_STATIC_CAST(CAttributeToken*,
|
||||
theAllocator->CreateTokenOfType(eToken_attribute,
|
||||
eHTMLTag_unknown));
|
||||
if (theToken) {
|
||||
if (NS_LIKELY(theToken != nsnull)) {
|
||||
// Tell the new token to finish consuming text...
|
||||
result = theToken->Consume(aChar, aScanner, mFlags);
|
||||
|
||||
|
@ -661,6 +661,9 @@ nsHTMLTokenizer::ConsumeAttributes(PRUnichar aChar,
|
|||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
result = NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
|
@ -719,163 +722,167 @@ nsHTMLTokenizer::ConsumeStartTag(PRUnichar aChar,
|
|||
|
||||
nsTokenAllocator* theAllocator = this->GetTokenAllocator();
|
||||
aToken = theAllocator->CreateTokenOfType(eToken_start, eHTMLTag_unknown);
|
||||
NS_ENSURE_TRUE(aToken, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
if (aToken) {
|
||||
// Tell the new token to finish consuming text...
|
||||
result = aToken->Consume(aChar, aScanner, mFlags);
|
||||
// Tell the new token to finish consuming text...
|
||||
result = aToken->Consume(aChar, aScanner, mFlags);
|
||||
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
AddToken(aToken, result, &mTokenDeque, theAllocator);
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
AddToken(aToken, result, &mTokenDeque, theAllocator);
|
||||
|
||||
eHTMLTags theTag = (eHTMLTags)aToken->GetTypeID();
|
||||
eHTMLTags theTag = (eHTMLTags)aToken->GetTypeID();
|
||||
|
||||
// Good. Now, let's see if the next char is ">".
|
||||
// If so, we have a complete tag, otherwise, we have attributes.
|
||||
result = aScanner.Peek(aChar);
|
||||
if (NS_FAILED(result)) {
|
||||
aToken->SetInError(PR_TRUE);
|
||||
// Good. Now, let's see if the next char is ">".
|
||||
// If so, we have a complete tag, otherwise, we have attributes.
|
||||
result = aScanner.Peek(aChar);
|
||||
if (NS_FAILED(result)) {
|
||||
aToken->SetInError(PR_TRUE);
|
||||
|
||||
// Don't return early here so we can create a text and end token for
|
||||
// the special <iframe>, <script> and similar tags down below.
|
||||
result = NS_OK;
|
||||
} else {
|
||||
if (kGreaterThan != aChar) { // Look for a '>'
|
||||
result = ConsumeAttributes(aChar, aToken, aScanner);
|
||||
} else {
|
||||
aScanner.GetChar(aChar);
|
||||
}
|
||||
}
|
||||
|
||||
/* Now that that's over with, we have one more problem to solve.
|
||||
In the case that we just read a <SCRIPT> or <STYLE> tags, we should go and
|
||||
consume all the content itself.
|
||||
But XML doesn't treat these tags differently, so we shouldn't if the
|
||||
document is XML.
|
||||
*/
|
||||
if (NS_SUCCEEDED(result) && !(mFlags & NS_IPARSER_FLAG_XML)) {
|
||||
PRBool isCDATA = gHTMLElements[theTag].CanContainType(kCDATA);
|
||||
PRBool isPCDATA = eHTMLTag_textarea == theTag ||
|
||||
eHTMLTag_title == theTag;
|
||||
|
||||
// XXX This is an evil hack, we should be able to handle these properly
|
||||
// in the DTD.
|
||||
if ((eHTMLTag_iframe == theTag &&
|
||||
(mFlags & NS_IPARSER_FLAG_FRAMES_ENABLED)) ||
|
||||
(eHTMLTag_noframes == theTag &&
|
||||
(mFlags & NS_IPARSER_FLAG_FRAMES_ENABLED)) ||
|
||||
(eHTMLTag_noscript == theTag &&
|
||||
(mFlags & NS_IPARSER_FLAG_SCRIPT_ENABLED)) ||
|
||||
(eHTMLTag_noembed == theTag)) {
|
||||
isCDATA = PR_TRUE;
|
||||
}
|
||||
|
||||
// Plaintext contains CDATA, but it's special, so we handle it
|
||||
// differently than the other CDATA elements
|
||||
if (eHTMLTag_plaintext == theTag) {
|
||||
isCDATA = PR_FALSE;
|
||||
|
||||
// Note: We check in ConsumeToken() for this flag, and if we see it
|
||||
// we only construct text tokens (which is what we want).
|
||||
mFlags |= NS_IPARSER_FLAG_PLAIN_TEXT;
|
||||
}
|
||||
|
||||
|
||||
if (isCDATA || isPCDATA) {
|
||||
PRBool done = PR_FALSE;
|
||||
nsDependentString endTagName(nsHTMLTags::GetStringValue(theTag));
|
||||
|
||||
CToken* text =
|
||||
theAllocator->CreateTokenOfType(eToken_text, eHTMLTag_text);
|
||||
CTextToken* textToken = NS_STATIC_CAST(CTextToken*, text);
|
||||
|
||||
if (isCDATA) {
|
||||
result = textToken->ConsumeCharacterData(theTag != eHTMLTag_script,
|
||||
aScanner,
|
||||
endTagName,
|
||||
mFlags,
|
||||
done);
|
||||
|
||||
// Only flush tokens for <script>, to give ourselves more of a
|
||||
// chance of allowing inlines to contain blocks.
|
||||
aFlushTokens = done && theTag == eHTMLTag_script;
|
||||
} else if (isPCDATA) {
|
||||
// Title is consumed conservatively in order to not regress
|
||||
// bug 42945
|
||||
result = textToken->ConsumeParsedCharacterData(
|
||||
theTag == eHTMLTag_textarea,
|
||||
theTag == eHTMLTag_title,
|
||||
aScanner,
|
||||
endTagName,
|
||||
mFlags,
|
||||
done);
|
||||
|
||||
// Note: we *don't* set aFlushTokens here.
|
||||
}
|
||||
|
||||
// We want to do this unless result is kEOF, in which case we will
|
||||
// simply unwind our stack and wait for more data anyway.
|
||||
if (kEOF != result) {
|
||||
AddToken(text, NS_OK, &mTokenDeque, theAllocator);
|
||||
CToken* endToken = nsnull;
|
||||
|
||||
if (NS_SUCCEEDED(result) && done) {
|
||||
PRUnichar theChar;
|
||||
// Get the <
|
||||
result = aScanner.GetChar(theChar);
|
||||
NS_ASSERTION(NS_SUCCEEDED(result) && theChar == kLessThan,
|
||||
"CTextToken::Consume*Data is broken!");
|
||||
#ifdef DEBUG
|
||||
// Ensure we have a /
|
||||
PRUnichar tempChar; // Don't change non-debug vars in debug-only code
|
||||
result = aScanner.Peek(tempChar);
|
||||
NS_ASSERTION(NS_SUCCEEDED(result) && tempChar == kForwardSlash,
|
||||
"CTextToken::Consume*Data is broken!");
|
||||
#endif
|
||||
result = ConsumeEndTag(PRUnichar('/'), endToken, aScanner);
|
||||
if (!(mFlags & NS_IPARSER_FLAG_VIEW_SOURCE) &&
|
||||
NS_SUCCEEDED(result)) {
|
||||
// If ConsumeCharacterData returned a success result (and
|
||||
// we're not in view source), then we want to make sure that
|
||||
// we're going to execute this script (since the result means
|
||||
// that we've found an end tag that satisfies all of the right
|
||||
// conditions).
|
||||
endToken->SetInError(PR_FALSE);
|
||||
}
|
||||
} else if (result == kFakeEndTag &&
|
||||
!(mFlags & NS_IPARSER_FLAG_VIEW_SOURCE)) {
|
||||
result = NS_OK;
|
||||
endToken = theAllocator->CreateTokenOfType(eToken_end, theTag,
|
||||
endTagName);
|
||||
AddToken(endToken, result, &mTokenDeque, theAllocator);
|
||||
if (endToken) {
|
||||
endToken->SetInError(PR_TRUE);
|
||||
}
|
||||
} else if (result == kFakeEndTag) {
|
||||
// If we are here, we are both faking having seen the end tag
|
||||
// and are in view-source.
|
||||
result = NS_OK;
|
||||
}
|
||||
} else {
|
||||
IF_FREE(text, mTokenAllocator);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This code is confusing, so pay attention.
|
||||
// If you're here, it's because we were in the midst of consuming a start
|
||||
// tag but ran out of data (not in the stream, but in this *part* of the
|
||||
// stream. For simplicity, we have to unwind our input. Therefore, we pop
|
||||
// and discard any new tokens we've cued this round. Later we can get
|
||||
// smarter about this.
|
||||
if (NS_FAILED(result)) {
|
||||
while (mTokenDeque.GetSize()>theDequeSize) {
|
||||
CToken* theToken = (CToken*)mTokenDeque.Pop();
|
||||
IF_FREE(theToken, mTokenAllocator);
|
||||
}
|
||||
}
|
||||
// Don't return early here so we can create a text and end token for
|
||||
// the special <iframe>, <script> and similar tags down below.
|
||||
result = NS_OK;
|
||||
} else {
|
||||
IF_FREE(aToken, mTokenAllocator);
|
||||
if (kGreaterThan != aChar) { // Look for a '>'
|
||||
result = ConsumeAttributes(aChar, aToken, aScanner);
|
||||
} else {
|
||||
aScanner.GetChar(aChar);
|
||||
}
|
||||
}
|
||||
|
||||
/* Now that that's over with, we have one more problem to solve.
|
||||
In the case that we just read a <SCRIPT> or <STYLE> tags, we should go and
|
||||
consume all the content itself.
|
||||
But XML doesn't treat these tags differently, so we shouldn't if the
|
||||
document is XML.
|
||||
*/
|
||||
if (NS_SUCCEEDED(result) && !(mFlags & NS_IPARSER_FLAG_XML)) {
|
||||
PRBool isCDATA = gHTMLElements[theTag].CanContainType(kCDATA);
|
||||
PRBool isPCDATA = eHTMLTag_textarea == theTag ||
|
||||
eHTMLTag_title == theTag;
|
||||
|
||||
// XXX This is an evil hack, we should be able to handle these properly
|
||||
// in the DTD.
|
||||
if ((eHTMLTag_iframe == theTag &&
|
||||
(mFlags & NS_IPARSER_FLAG_FRAMES_ENABLED)) ||
|
||||
(eHTMLTag_noframes == theTag &&
|
||||
(mFlags & NS_IPARSER_FLAG_FRAMES_ENABLED)) ||
|
||||
(eHTMLTag_noscript == theTag &&
|
||||
(mFlags & NS_IPARSER_FLAG_SCRIPT_ENABLED)) ||
|
||||
(eHTMLTag_noembed == theTag)) {
|
||||
isCDATA = PR_TRUE;
|
||||
}
|
||||
|
||||
// Plaintext contains CDATA, but it's special, so we handle it
|
||||
// differently than the other CDATA elements
|
||||
if (eHTMLTag_plaintext == theTag) {
|
||||
isCDATA = PR_FALSE;
|
||||
|
||||
// Note: We check in ConsumeToken() for this flag, and if we see it
|
||||
// we only construct text tokens (which is what we want).
|
||||
mFlags |= NS_IPARSER_FLAG_PLAIN_TEXT;
|
||||
}
|
||||
|
||||
|
||||
if (isCDATA || isPCDATA) {
|
||||
PRBool done = PR_FALSE;
|
||||
nsDependentString endTagName(nsHTMLTags::GetStringValue(theTag));
|
||||
|
||||
CToken* text =
|
||||
theAllocator->CreateTokenOfType(eToken_text, eHTMLTag_text);
|
||||
NS_ENSURE_TRUE(text, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
CTextToken* textToken = NS_STATIC_CAST(CTextToken*, text);
|
||||
|
||||
if (isCDATA) {
|
||||
result = textToken->ConsumeCharacterData(theTag != eHTMLTag_script,
|
||||
aScanner,
|
||||
endTagName,
|
||||
mFlags,
|
||||
done);
|
||||
|
||||
// Only flush tokens for <script>, to give ourselves more of a
|
||||
// chance of allowing inlines to contain blocks.
|
||||
aFlushTokens = done && theTag == eHTMLTag_script;
|
||||
} else if (isPCDATA) {
|
||||
// Title is consumed conservatively in order to not regress
|
||||
// bug 42945
|
||||
result = textToken->ConsumeParsedCharacterData(
|
||||
theTag == eHTMLTag_textarea,
|
||||
theTag == eHTMLTag_title,
|
||||
aScanner,
|
||||
endTagName,
|
||||
mFlags,
|
||||
done);
|
||||
|
||||
// Note: we *don't* set aFlushTokens here.
|
||||
}
|
||||
|
||||
// We want to do this unless result is kEOF, in which case we will
|
||||
// simply unwind our stack and wait for more data anyway.
|
||||
if (kEOF != result) {
|
||||
AddToken(text, NS_OK, &mTokenDeque, theAllocator);
|
||||
CToken* endToken = nsnull;
|
||||
|
||||
if (NS_SUCCEEDED(result) && done) {
|
||||
PRUnichar theChar;
|
||||
// Get the <
|
||||
result = aScanner.GetChar(theChar);
|
||||
NS_ASSERTION(NS_SUCCEEDED(result) && theChar == kLessThan,
|
||||
"CTextToken::Consume*Data is broken!");
|
||||
#ifdef DEBUG
|
||||
// Ensure we have a /
|
||||
PRUnichar tempChar; // Don't change non-debug vars in debug-only code
|
||||
result = aScanner.Peek(tempChar);
|
||||
NS_ASSERTION(NS_SUCCEEDED(result) && tempChar == kForwardSlash,
|
||||
"CTextToken::Consume*Data is broken!");
|
||||
#endif
|
||||
result = ConsumeEndTag(PRUnichar('/'), endToken, aScanner);
|
||||
if (!(mFlags & NS_IPARSER_FLAG_VIEW_SOURCE) &&
|
||||
NS_SUCCEEDED(result)) {
|
||||
// If ConsumeCharacterData returned a success result (and
|
||||
// we're not in view source), then we want to make sure that
|
||||
// we're going to execute this script (since the result means
|
||||
// that we've found an end tag that satisfies all of the right
|
||||
// conditions).
|
||||
endToken->SetInError(PR_FALSE);
|
||||
}
|
||||
} else if (result == kFakeEndTag &&
|
||||
!(mFlags & NS_IPARSER_FLAG_VIEW_SOURCE)) {
|
||||
result = NS_OK;
|
||||
endToken = theAllocator->CreateTokenOfType(eToken_end, theTag,
|
||||
endTagName);
|
||||
AddToken(endToken, result, &mTokenDeque, theAllocator);
|
||||
if (NS_LIKELY(endToken != nsnull)) {
|
||||
endToken->SetInError(PR_TRUE);
|
||||
}
|
||||
else {
|
||||
result = NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
} else if (result == kFakeEndTag) {
|
||||
// If we are here, we are both faking having seen the end tag
|
||||
// and are in view-source.
|
||||
result = NS_OK;
|
||||
}
|
||||
} else {
|
||||
IF_FREE(text, mTokenAllocator);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This code is confusing, so pay attention.
|
||||
// If you're here, it's because we were in the midst of consuming a start
|
||||
// tag but ran out of data (not in the stream, but in this *part* of the
|
||||
// stream. For simplicity, we have to unwind our input. Therefore, we pop
|
||||
// and discard any new tokens we've cued this round. Later we can get
|
||||
// smarter about this.
|
||||
if (NS_FAILED(result)) {
|
||||
while (mTokenDeque.GetSize()>theDequeSize) {
|
||||
CToken* theToken = (CToken*)mTokenDeque.Pop();
|
||||
IF_FREE(theToken, mTokenAllocator);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
IF_FREE(aToken, mTokenAllocator);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -899,45 +906,45 @@ nsHTMLTokenizer::ConsumeEndTag(PRUnichar aChar,
|
|||
|
||||
nsTokenAllocator* theAllocator = this->GetTokenAllocator();
|
||||
aToken = theAllocator->CreateTokenOfType(eToken_end, eHTMLTag_unknown);
|
||||
NS_ENSURE_TRUE(aToken, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
// Remember this for later in case you have to unwind...
|
||||
PRInt32 theDequeSize = mTokenDeque.GetSize();
|
||||
nsresult result = NS_OK;
|
||||
|
||||
if (aToken) {
|
||||
// Tell the new token to finish consuming text...
|
||||
result = aToken->Consume(aChar, aScanner, mFlags);
|
||||
AddToken(aToken, result, &mTokenDeque, theAllocator);
|
||||
if (NS_FAILED(result)) {
|
||||
// Note that this early-return here is safe because we have not yet
|
||||
// added any of our tokens to the queue (AddToken only adds the token if
|
||||
// result is a success), so we don't need to fall through.
|
||||
return result;
|
||||
}
|
||||
// Tell the new token to finish consuming text...
|
||||
result = aToken->Consume(aChar, aScanner, mFlags);
|
||||
AddToken(aToken, result, &mTokenDeque, theAllocator);
|
||||
if (NS_FAILED(result)) {
|
||||
// Note that this early-return here is safe because we have not yet
|
||||
// added any of our tokens to the queue (AddToken only adds the token if
|
||||
// result is a success), so we don't need to fall through.
|
||||
return result;
|
||||
}
|
||||
|
||||
result = aScanner.Peek(aChar);
|
||||
if (NS_FAILED(result)) {
|
||||
aToken->SetInError(PR_TRUE);
|
||||
result = aScanner.Peek(aChar);
|
||||
if (NS_FAILED(result)) {
|
||||
aToken->SetInError(PR_TRUE);
|
||||
|
||||
// Note: We know here that the scanner is not incremental since if
|
||||
// this peek fails, then we've already masked over a kEOF coming from
|
||||
// the Consume() call above.
|
||||
return NS_OK;
|
||||
}
|
||||
// Note: We know here that the scanner is not incremental since if
|
||||
// this peek fails, then we've already masked over a kEOF coming from
|
||||
// the Consume() call above.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (kGreaterThan != aChar) {
|
||||
result = ConsumeAttributes(aChar, aToken, aScanner);
|
||||
} else {
|
||||
aScanner.GetChar(aChar);
|
||||
}
|
||||
if (kGreaterThan != aChar) {
|
||||
result = ConsumeAttributes(aChar, aToken, aScanner);
|
||||
} else {
|
||||
aScanner.GetChar(aChar);
|
||||
}
|
||||
|
||||
// Do the same thing as we do in ConsumeStartTag. Basically, if we've run
|
||||
// out of room in this *section* of the document, pop all of the tokens
|
||||
// we've consumed this round and wait for more data.
|
||||
if (NS_FAILED(result)) {
|
||||
while (mTokenDeque.GetSize() > theDequeSize) {
|
||||
CToken* theToken = (CToken*)mTokenDeque.Pop();
|
||||
IF_FREE(theToken, mTokenAllocator);
|
||||
}
|
||||
// Do the same thing as we do in ConsumeStartTag. Basically, if we've run
|
||||
// out of room in this *section* of the document, pop all of the tokens
|
||||
// we've consumed this round and wait for more data.
|
||||
if (NS_FAILED(result)) {
|
||||
while (mTokenDeque.GetSize() > theDequeSize) {
|
||||
CToken* theToken = (CToken*)mTokenDeque.Pop();
|
||||
IF_FREE(theToken, mTokenAllocator);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -965,6 +972,7 @@ nsHTMLTokenizer::ConsumeEntity(PRUnichar aChar,
|
|||
if (NS_SUCCEEDED(result)) {
|
||||
if (nsCRT::IsAsciiAlpha(theChar) || theChar == kHashsign) {
|
||||
aToken = theAllocator->CreateTokenOfType(eToken_entity, eHTMLTag_entity);
|
||||
NS_ENSURE_TRUE(aToken, NS_ERROR_OUT_OF_MEMORY);
|
||||
result = aToken->Consume(theChar, aScanner, mFlags);
|
||||
|
||||
if (result == NS_HTMLTOKENS_NOT_AN_ENTITY) {
|
||||
|
|
|
@ -108,6 +108,7 @@ class nsCParserNode : public nsIParserNode {
|
|||
#else
|
||||
nsFixedSizeAllocator& pool = aNodeAllocator->GetArenaPool();
|
||||
void* place = pool.Alloc(sizeof(nsCParserNode));
|
||||
NS_ENSURE_TRUE(place, nsnull);
|
||||
return ::new (place)
|
||||
#endif
|
||||
nsCParserNode(aToken, aTokenAllocator, aNodeAllocator);
|
||||
|
@ -281,6 +282,7 @@ public:
|
|||
#else
|
||||
nsFixedSizeAllocator& pool = aNodeAllocator->GetArenaPool();
|
||||
void* place = pool.Alloc(sizeof(nsCParserStartNode));
|
||||
NS_ENSURE_TRUE(place, nsnull);
|
||||
return ::new (place)
|
||||
#endif
|
||||
nsCParserStartNode(aToken, aTokenAllocator, aNodeAllocator);
|
||||
|
|
|
@ -797,6 +797,7 @@ nsresult CViewSourceHTML::WriteTag(PRInt32 aTagType,const nsSubstring & aText,PR
|
|||
theAllocator->CreateTokenOfType(eToken_start,
|
||||
eHTMLTag_span,
|
||||
NS_LITERAL_STRING("SPAN")));
|
||||
NS_ENSURE_TRUE(theTagToken, NS_ERROR_OUT_OF_MEMORY);
|
||||
theContext.mErrorNode.Init(theTagToken, theAllocator);
|
||||
AddAttrToNode(theContext.mErrorNode, theAllocator,
|
||||
NS_LITERAL_STRING("class"),
|
||||
|
@ -826,6 +827,7 @@ nsresult CViewSourceHTML::WriteTag(PRInt32 aTagType,const nsSubstring & aText,PR
|
|||
theAllocator->CreateTokenOfType(eToken_start,
|
||||
eHTMLTag_span,
|
||||
NS_LITERAL_STRING("SPAN")));
|
||||
NS_ENSURE_TRUE(theTagToken, NS_ERROR_OUT_OF_MEMORY);
|
||||
theContext.mStartNode.Init(theTagToken, theAllocator);
|
||||
AddAttrToNode(theContext.mStartNode, theAllocator,
|
||||
NS_LITERAL_STRING("class"),
|
||||
|
|
Загрузка…
Ссылка в новой задаче