mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Avoid regressing bug 321781 in the HTML5 parser
This commit is contained in:
parent
e096617179
commit
5712cc9dc6
@ -4260,7 +4260,7 @@ nsDocument::GetElementsByTagName(const nsAString& aTagname,
|
||||
nsCOMPtr<nsIAtom> nameAtom = do_GetAtom(aTagname);
|
||||
NS_ENSURE_TRUE(nameAtom, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
nsContentList *list = NS_GetContentList(this, nameAtom, GetDefaultNamespaceID()).get();
|
||||
nsContentList *list = NS_GetContentList(this, nameAtom, kNameSpaceID_Unknown).get();
|
||||
NS_ENSURE_TRUE(list, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
// transfer ref to aReturn
|
||||
|
@ -85,6 +85,7 @@ CPPSRCS = \
|
||||
nsHtml5ReleasableElementName.cpp \
|
||||
nsHtml5MetaScanner.cpp \
|
||||
nsHtml5TreeOperation.cpp \
|
||||
nsHtml5StateSnapshot.cpp \
|
||||
$(NULL)
|
||||
|
||||
FORCE_STATIC_LIB = 1
|
||||
|
@ -50,6 +50,7 @@
|
||||
#include "nsHtml5HtmlAttributes.h"
|
||||
#include "nsHtml5StackNode.h"
|
||||
#include "nsHtml5UTF16Buffer.h"
|
||||
#include "nsHtml5StateSnapshot.h"
|
||||
#include "nsHtml5Portability.h"
|
||||
|
||||
#include "nsHtml5AttributeName.h"
|
||||
|
@ -53,6 +53,7 @@ class nsHtml5ElementName;
|
||||
class nsHtml5HtmlAttributes;
|
||||
class nsHtml5StackNode;
|
||||
class nsHtml5UTF16Buffer;
|
||||
class nsHtml5StateSnapshot;
|
||||
class nsHtml5Portability;
|
||||
|
||||
|
||||
|
@ -50,6 +50,7 @@
|
||||
#include "nsHtml5HtmlAttributes.h"
|
||||
#include "nsHtml5StackNode.h"
|
||||
#include "nsHtml5UTF16Buffer.h"
|
||||
#include "nsHtml5StateSnapshot.h"
|
||||
#include "nsHtml5Portability.h"
|
||||
|
||||
#include "nsHtml5ElementName.h"
|
||||
|
@ -53,6 +53,7 @@ class nsHtml5AttributeName;
|
||||
class nsHtml5HtmlAttributes;
|
||||
class nsHtml5StackNode;
|
||||
class nsHtml5UTF16Buffer;
|
||||
class nsHtml5StateSnapshot;
|
||||
class nsHtml5Portability;
|
||||
|
||||
|
||||
|
@ -51,6 +51,7 @@
|
||||
#include "nsHtml5ElementName.h"
|
||||
#include "nsHtml5StackNode.h"
|
||||
#include "nsHtml5UTF16Buffer.h"
|
||||
#include "nsHtml5StateSnapshot.h"
|
||||
#include "nsHtml5Portability.h"
|
||||
|
||||
#include "nsHtml5HtmlAttributes.h"
|
||||
|
@ -54,6 +54,7 @@ class nsHtml5AttributeName;
|
||||
class nsHtml5ElementName;
|
||||
class nsHtml5StackNode;
|
||||
class nsHtml5UTF16Buffer;
|
||||
class nsHtml5StateSnapshot;
|
||||
class nsHtml5Portability;
|
||||
|
||||
|
||||
|
@ -51,6 +51,7 @@
|
||||
#include "nsHtml5HtmlAttributes.h"
|
||||
#include "nsHtml5StackNode.h"
|
||||
#include "nsHtml5UTF16Buffer.h"
|
||||
#include "nsHtml5StateSnapshot.h"
|
||||
#include "nsHtml5Portability.h"
|
||||
|
||||
#include "nsHtml5MetaScanner.h"
|
||||
|
@ -54,6 +54,7 @@ class nsHtml5ElementName;
|
||||
class nsHtml5HtmlAttributes;
|
||||
class nsHtml5StackNode;
|
||||
class nsHtml5UTF16Buffer;
|
||||
class nsHtml5StateSnapshot;
|
||||
class nsHtml5Portability;
|
||||
|
||||
|
||||
|
@ -166,9 +166,10 @@ nsHtml5Parser::~nsHtml5Parser()
|
||||
if (mSniffingBuffer) {
|
||||
delete[] mSniffingBuffer;
|
||||
}
|
||||
if (mMetaScanner) {
|
||||
delete mMetaScanner;
|
||||
}
|
||||
delete mMetaScanner;
|
||||
#ifdef DEBUG
|
||||
delete mSnapshot;
|
||||
#endif
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(void)
|
||||
@ -809,6 +810,12 @@ nsHtml5Parser::DidBuildModel()
|
||||
|
||||
DropParserAndPerfHint();
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("UNSAFE SCRIPTS: %d\n", sUnsafeDocWrites);
|
||||
printf("TOKENIZER-SAFE SCRIPTS: %d\n", sTokenSafeDocWrites);
|
||||
printf("TREEBUILDER-SAFE SCRIPTS: %d\n", sTreeSafeDocWrites);
|
||||
#endif
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -1182,6 +1189,21 @@ nsHtml5Parser::ParseUntilSuspend()
|
||||
return;
|
||||
}
|
||||
// now we have a non-empty buffer
|
||||
#ifdef DEBUG
|
||||
if (mSnapshot && mFirstBuffer->key == GetRootContextKey()) {
|
||||
if (mTokenizer->isInDataState()) {
|
||||
if (mTreeBuilder->snapshotMatches(mSnapshot)) {
|
||||
sTreeSafeDocWrites++;
|
||||
} else {
|
||||
sTokenSafeDocWrites++;
|
||||
}
|
||||
} else {
|
||||
sUnsafeDocWrites++;
|
||||
}
|
||||
delete mSnapshot;
|
||||
mSnapshot = nsnull;
|
||||
}
|
||||
#endif
|
||||
mFirstBuffer->adjust(mLastWasCR);
|
||||
mLastWasCR = PR_FALSE;
|
||||
if (mFirstBuffer->hasMore()) {
|
||||
@ -1254,6 +1276,18 @@ void
|
||||
nsHtml5Parser::ExecuteScript()
|
||||
{
|
||||
NS_PRECONDITION(mScriptElement, "Trying to run a script without having one!");
|
||||
#ifdef DEBUG
|
||||
if (!mScriptsExecuting) {
|
||||
NS_ASSERTION(!mSnapshot, "Already had a state snapshot");
|
||||
mSnapshot = mTreeBuilder->newSnapshot();
|
||||
}
|
||||
#endif
|
||||
nsCOMPtr<nsIScriptElement> sele = do_QueryInterface(mScriptElement);
|
||||
|
||||
// Notify our document that we're loading this script.
|
||||
nsCOMPtr<nsIHTMLDocument> htmlDocument = do_QueryInterface(mDocument);
|
||||
NS_ASSERTION(htmlDocument, "Document didn't QI into HTML document.");
|
||||
htmlDocument->ScriptLoading(sele);
|
||||
|
||||
// Copied from nsXMLContentSink
|
||||
|
||||
@ -1265,9 +1299,12 @@ nsHtml5Parser::ExecuteScript()
|
||||
// If the act of insertion evaluated the script, we're fine.
|
||||
// Else, block the parser till the script has loaded.
|
||||
if (rv == NS_ERROR_HTMLPARSER_BLOCK) {
|
||||
nsCOMPtr<nsIScriptElement> sele = do_QueryInterface(mScriptElement);
|
||||
mScriptElements.AppendObject(sele);
|
||||
BlockParser();
|
||||
} else {
|
||||
// This may have already happened if the script executed, but in case
|
||||
// it didn't then remove the element so that it doesn't get stuck forever.
|
||||
htmlDocument->ScriptExecuted(sele);
|
||||
}
|
||||
mScriptElement = nsnull;
|
||||
}
|
||||
@ -1391,6 +1428,14 @@ nsHtml5Parser::FlushTags()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Parser::PostEvaluateScript(nsIScriptElement *aElement)
|
||||
{
|
||||
nsCOMPtr<nsIHTMLDocument> htmlDocument = do_QueryInterface(mDocument);
|
||||
NS_ASSERTION(htmlDocument, "Document didn't QI into HTML document.");
|
||||
htmlDocument->ScriptExecuted(aElement);
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Parser::ScriptExecuting()
|
||||
{
|
||||
@ -1404,3 +1449,8 @@ nsHtml5Parser::ScriptDidExecute()
|
||||
--mScriptsExecuting;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
PRUint32 nsHtml5Parser::sUnsafeDocWrites = 0;
|
||||
PRUint32 nsHtml5Parser::sTokenSafeDocWrites = 0;
|
||||
PRUint32 nsHtml5Parser::sTreeSafeDocWrites = 0;
|
||||
#endif
|
||||
|
@ -310,6 +310,7 @@ class nsHtml5Parser : public nsIParser,
|
||||
virtual nsresult ProcessBASETag(nsIContent* aContent);
|
||||
virtual void UpdateChildCounts();
|
||||
virtual nsresult FlushTags();
|
||||
virtual void PostEvaluateScript(nsIScriptElement *aElement);
|
||||
using nsContentSink::Notify;
|
||||
|
||||
// Non-inherited methods
|
||||
@ -343,7 +344,7 @@ class nsHtml5Parser : public nsIParser,
|
||||
PRBool HasDecoder() {
|
||||
return !!mUnicodeDecoder;
|
||||
}
|
||||
void ReadyToCallDidBuildModel() {
|
||||
void ReadyToCallDidBuildModelHtml5() {
|
||||
ReadyToCallDidBuildModelImpl(mTerminated);
|
||||
}
|
||||
private:
|
||||
@ -397,6 +398,12 @@ class nsHtml5Parser : public nsIParser,
|
||||
// a buffer of the size NS_HTML5_PARSER_READ_BUFFER_SIZE
|
||||
nsHtml5TreeBuilder* mTreeBuilder; // manually managed strong ref
|
||||
nsHtml5Tokenizer* mTokenizer; // manually managed strong ref
|
||||
#ifdef DEBUG
|
||||
nsHtml5StateSnapshot* mSnapshot;
|
||||
static PRUint32 sUnsafeDocWrites;
|
||||
static PRUint32 sTokenSafeDocWrites;
|
||||
static PRUint32 sTreeSafeDocWrites;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -54,6 +54,7 @@ class nsHtml5ElementName;
|
||||
class nsHtml5HtmlAttributes;
|
||||
class nsHtml5StackNode;
|
||||
class nsHtml5UTF16Buffer;
|
||||
class nsHtml5StateSnapshot;
|
||||
|
||||
|
||||
class nsHtml5Portability
|
||||
|
@ -51,6 +51,7 @@
|
||||
#include "nsHtml5ElementName.h"
|
||||
#include "nsHtml5HtmlAttributes.h"
|
||||
#include "nsHtml5UTF16Buffer.h"
|
||||
#include "nsHtml5StateSnapshot.h"
|
||||
#include "nsHtml5Portability.h"
|
||||
|
||||
#include "nsHtml5StackNode.h"
|
||||
|
@ -54,6 +54,7 @@ class nsHtml5AttributeName;
|
||||
class nsHtml5ElementName;
|
||||
class nsHtml5HtmlAttributes;
|
||||
class nsHtml5UTF16Buffer;
|
||||
class nsHtml5StateSnapshot;
|
||||
class nsHtml5Portability;
|
||||
|
||||
|
||||
|
@ -53,6 +53,7 @@
|
||||
#include "nsHtml5HtmlAttributes.h"
|
||||
#include "nsHtml5StackNode.h"
|
||||
#include "nsHtml5UTF16Buffer.h"
|
||||
#include "nsHtml5StateSnapshot.h"
|
||||
#include "nsHtml5Portability.h"
|
||||
|
||||
#include "nsHtml5Tokenizer.h"
|
||||
@ -2971,6 +2972,12 @@ nsHtml5Tokenizer::getCol()
|
||||
return col;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsHtml5Tokenizer::isInDataState()
|
||||
{
|
||||
return (stateSave == NS_HTML5TOKENIZER_DATA);
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::initializeStatics()
|
||||
{
|
||||
|
@ -56,6 +56,7 @@ class nsHtml5ElementName;
|
||||
class nsHtml5HtmlAttributes;
|
||||
class nsHtml5StackNode;
|
||||
class nsHtml5UTF16Buffer;
|
||||
class nsHtml5StateSnapshot;
|
||||
class nsHtml5Portability;
|
||||
|
||||
|
||||
@ -237,6 +238,7 @@ class nsHtml5Tokenizer
|
||||
PRBool isPrevCR();
|
||||
PRInt32 getLine();
|
||||
PRInt32 getCol();
|
||||
PRBool isInDataState();
|
||||
static void initializeStatics();
|
||||
static void releaseStatics();
|
||||
};
|
||||
|
@ -47,6 +47,7 @@
|
||||
#include "nsHtml5ByteReadable.h"
|
||||
#include "nsHtml5TreeOperation.h"
|
||||
#include "nsHtml5PendingNotification.h"
|
||||
#include "nsHtml5StateSnapshot.h"
|
||||
|
||||
#include "nsHtml5Tokenizer.h"
|
||||
#include "nsHtml5MetaScanner.h"
|
||||
@ -55,6 +56,7 @@
|
||||
#include "nsHtml5HtmlAttributes.h"
|
||||
#include "nsHtml5StackNode.h"
|
||||
#include "nsHtml5UTF16Buffer.h"
|
||||
#include "nsHtml5StateSnapshot.h"
|
||||
#include "nsHtml5Portability.h"
|
||||
|
||||
#include "nsHtml5TreeBuilder.h"
|
||||
@ -3557,6 +3559,7 @@ nsHtml5TreeBuilder::flushCharacters()
|
||||
if (charBufferLen > 0) {
|
||||
nsHtml5StackNode* current = stack[currentPtr];
|
||||
if (current->fosterParenting && charBufferContainsNonWhitespace()) {
|
||||
|
||||
PRInt32 eltPos = findLastOrRoot(NS_HTML5TREE_BUILDER_TABLE);
|
||||
nsHtml5StackNode* node = stack[eltPos];
|
||||
nsIContent* elt = node->node;
|
||||
@ -3593,6 +3596,46 @@ nsHtml5TreeBuilder::charBufferContainsNonWhitespace()
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsHtml5StateSnapshot*
|
||||
nsHtml5TreeBuilder::newSnapshot()
|
||||
{
|
||||
jArray<nsHtml5StackNode*,PRInt32> stackCopy = jArray<nsHtml5StackNode*,PRInt32>(currentPtr + 1);
|
||||
for (PRInt32 i = 0; i < stackCopy.length; i++) {
|
||||
(stackCopy[i] = stack[i])->retain();
|
||||
}
|
||||
jArray<nsHtml5StackNode*,PRInt32> listCopy = jArray<nsHtml5StackNode*,PRInt32>(listPtr + 1);
|
||||
for (PRInt32 i = 0; i < listCopy.length; i++) {
|
||||
nsHtml5StackNode* node = listOfActiveFormattingElements[i];
|
||||
if (!!node) {
|
||||
node->retain();
|
||||
}
|
||||
listCopy[i] = node;
|
||||
}
|
||||
nsHtml5Portability::retainElement(formPointer);
|
||||
return new nsHtml5StateSnapshot(stackCopy, listCopy, formPointer);
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsHtml5TreeBuilder::snapshotMatches(nsHtml5StateSnapshot* snapshot)
|
||||
{
|
||||
jArray<nsHtml5StackNode*,PRInt32> stackCopy = snapshot->stack;
|
||||
jArray<nsHtml5StackNode*,PRInt32> listCopy = snapshot->listOfActiveFormattingElements;
|
||||
if (stackCopy.length != currentPtr + 1 || listCopy.length != listPtr + 1 || formPointer != snapshot->formPointer) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
for (PRInt32 i = listCopy.length - 1; i >= 0; i--) {
|
||||
if (listCopy[i] != listOfActiveFormattingElements[i]) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
for (PRInt32 i = listCopy.length - 1; i >= 0; i--) {
|
||||
if (listCopy[i] != listOfActiveFormattingElements[i]) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5TreeBuilder::initializeStatics()
|
||||
{
|
||||
|
@ -48,6 +48,7 @@
|
||||
#include "nsHtml5ByteReadable.h"
|
||||
#include "nsHtml5TreeOperation.h"
|
||||
#include "nsHtml5PendingNotification.h"
|
||||
#include "nsHtml5StateSnapshot.h"
|
||||
|
||||
class nsHtml5Parser;
|
||||
|
||||
@ -58,6 +59,7 @@ class nsHtml5ElementName;
|
||||
class nsHtml5HtmlAttributes;
|
||||
class nsHtml5StackNode;
|
||||
class nsHtml5UTF16Buffer;
|
||||
class nsHtml5StateSnapshot;
|
||||
class nsHtml5Portability;
|
||||
|
||||
typedef nsIContent* nsIContentPtr;
|
||||
@ -196,6 +198,8 @@ class nsHtml5TreeBuilder
|
||||
void flushCharacters();
|
||||
PRBool charBufferContainsNonWhitespace();
|
||||
public:
|
||||
nsHtml5StateSnapshot* newSnapshot();
|
||||
PRBool snapshotMatches(nsHtml5StateSnapshot* snapshot);
|
||||
static void initializeStatics();
|
||||
static void releaseStatics();
|
||||
|
||||
|
@ -267,7 +267,7 @@ nsHtml5TreeBuilder::end()
|
||||
{
|
||||
mFlushTimer->Cancel();
|
||||
Flush();
|
||||
mParser->ReadyToCallDidBuildModel();
|
||||
mParser->ReadyToCallDidBuildModelHtml5();
|
||||
#ifdef DEBUG
|
||||
mActive = PR_FALSE;
|
||||
#endif
|
||||
|
@ -50,6 +50,7 @@
|
||||
#include "nsHtml5ElementName.h"
|
||||
#include "nsHtml5HtmlAttributes.h"
|
||||
#include "nsHtml5StackNode.h"
|
||||
#include "nsHtml5StateSnapshot.h"
|
||||
#include "nsHtml5Portability.h"
|
||||
|
||||
#include "nsHtml5UTF16Buffer.h"
|
||||
|
@ -53,6 +53,7 @@ class nsHtml5AttributeName;
|
||||
class nsHtml5ElementName;
|
||||
class nsHtml5HtmlAttributes;
|
||||
class nsHtml5StackNode;
|
||||
class nsHtml5StateSnapshot;
|
||||
class nsHtml5Portability;
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user