Bug 516406 - Make document.write() parser and stream parser have distinct tokenizers in the HTML5 parser. r=bnewman.
This commit is contained in:
@@ -45,6 +45,7 @@
|
||||
#include "nsHtml5Atoms.h"
|
||||
#include "nsHtml5ByteReadable.h"
|
||||
#include "nsIUnicodeDecoder.h"
|
||||
#include "nsAHtml5TreeBuilderState.h"
|
||||
|
||||
#include "nsHtml5TreeBuilder.h"
|
||||
#include "nsHtml5MetaScanner.h"
|
||||
@@ -74,9 +75,12 @@ nsHtml5Tokenizer::nsHtml5Tokenizer(nsHtml5TreeBuilder* tokenHandler)
|
||||
encodingDeclarationHandler(nsnull),
|
||||
bmpChar(jArray<PRUnichar,PRInt32>(1)),
|
||||
astralChar(jArray<PRUnichar,PRInt32>(2)),
|
||||
attributes(nsnull),
|
||||
tagName(nsnull),
|
||||
attributeName(nsnull)
|
||||
attributeName(nsnull),
|
||||
doctypeName(nsnull),
|
||||
publicIdentifier(nsnull),
|
||||
systemIdentifier(nsnull),
|
||||
attributes(nsnull)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsHtml5Tokenizer);
|
||||
}
|
||||
@@ -400,6 +404,7 @@ nsHtml5Tokenizer::addAttributeWithoutValue()
|
||||
|
||||
if (!!attributeName) {
|
||||
attributes->addAttribute(attributeName, nsHtml5Portability::newEmptyString());
|
||||
attributeName = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -409,6 +414,7 @@ nsHtml5Tokenizer::addAttributeWithValue()
|
||||
if (!!attributeName) {
|
||||
nsString* value = longStrBufToString();
|
||||
attributes->addAttribute(attributeName, value);
|
||||
attributeName = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -420,39 +426,8 @@ nsHtml5Tokenizer::startErrorReporting()
|
||||
void
|
||||
nsHtml5Tokenizer::start()
|
||||
{
|
||||
confident = PR_FALSE;
|
||||
strBuf = jArray<PRUnichar,PRInt32>(64);
|
||||
strBufLen = 0;
|
||||
longStrBuf = jArray<PRUnichar,PRInt32>(1024);
|
||||
longStrBufLen = 0;
|
||||
stateSave = NS_HTML5TOKENIZER_DATA;
|
||||
line = 1;
|
||||
lastCR = PR_FALSE;
|
||||
initializeWithoutStarting();
|
||||
tokenHandler->startTokenization(this);
|
||||
index = 0;
|
||||
forceQuirks = PR_FALSE;
|
||||
additional = '\0';
|
||||
entCol = -1;
|
||||
lo = 0;
|
||||
hi = (nsHtml5NamedCharacters::NAMES.length - 1);
|
||||
candidate = -1;
|
||||
strBufMark = 0;
|
||||
prevValue = -1;
|
||||
value = 0;
|
||||
seenDigits = PR_FALSE;
|
||||
shouldSuspend = PR_FALSE;
|
||||
if (!!tagName) {
|
||||
tagName->release();
|
||||
tagName = nsnull;
|
||||
}
|
||||
if (!!attributeName) {
|
||||
attributeName->release();
|
||||
attributeName = nsnull;
|
||||
}
|
||||
if (!!attributes) {
|
||||
delete attributes;
|
||||
attributes = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
PRBool
|
||||
@@ -948,7 +923,7 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar*
|
||||
}
|
||||
case '&': {
|
||||
clearStrBufAndAppendCurrentC(c);
|
||||
rememberAmpersandLocation('\0');
|
||||
rememberAmpersandLocation('>');
|
||||
returnState = state;
|
||||
state = NS_HTML5TOKENIZER_CONSUME_CHARACTER_REFERENCE;
|
||||
goto stateloop;
|
||||
@@ -2894,6 +2869,22 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar*
|
||||
return pos;
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::initDoctypeFields()
|
||||
{
|
||||
nsHtml5Portability::releaseLocal(doctypeName);
|
||||
doctypeName = nsHtml5Atoms::emptystring;
|
||||
if (!!systemIdentifier) {
|
||||
nsHtml5Portability::releaseString(systemIdentifier);
|
||||
systemIdentifier = nsnull;
|
||||
}
|
||||
if (!!publicIdentifier) {
|
||||
nsHtml5Portability::releaseString(publicIdentifier);
|
||||
publicIdentifier = nsnull;
|
||||
}
|
||||
forceQuirks = PR_FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::emitCarriageReturn(PRUnichar* buf, PRInt32 pos)
|
||||
{
|
||||
@@ -3057,9 +3048,16 @@ nsHtml5Tokenizer::eof()
|
||||
emitComment(0, 0);
|
||||
} else {
|
||||
|
||||
nsHtml5Portability::releaseLocal(doctypeName);
|
||||
doctypeName = nsHtml5Atoms::emptystring;
|
||||
publicIdentifier = nsnull;
|
||||
systemIdentifier = nsnull;
|
||||
if (!!systemIdentifier) {
|
||||
nsHtml5Portability::releaseString(systemIdentifier);
|
||||
systemIdentifier = nsnull;
|
||||
}
|
||||
if (!!publicIdentifier) {
|
||||
nsHtml5Portability::releaseString(publicIdentifier);
|
||||
publicIdentifier = nsnull;
|
||||
}
|
||||
forceQuirks = PR_TRUE;
|
||||
emitDoctypeToken(0);
|
||||
goto eofloop_end;
|
||||
@@ -3268,8 +3266,11 @@ nsHtml5Tokenizer::emitDoctypeToken(PRInt32 pos)
|
||||
cstart = pos + 1;
|
||||
tokenHandler->doctype(doctypeName, publicIdentifier, systemIdentifier, forceQuirks);
|
||||
nsHtml5Portability::releaseLocal(doctypeName);
|
||||
doctypeName = nsnull;
|
||||
nsHtml5Portability::releaseString(publicIdentifier);
|
||||
publicIdentifier = nsnull;
|
||||
nsHtml5Portability::releaseString(systemIdentifier);
|
||||
systemIdentifier = nsnull;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -3303,11 +3304,20 @@ nsHtml5Tokenizer::emitOrAppendOne(PRUnichar* val, PRInt32 returnState)
|
||||
void
|
||||
nsHtml5Tokenizer::end()
|
||||
{
|
||||
strBuf.release();
|
||||
strBuf = nsnull;
|
||||
longStrBuf.release();
|
||||
longStrBuf = nsnull;
|
||||
systemIdentifier = nsnull;
|
||||
publicIdentifier = nsnull;
|
||||
nsHtml5Portability::releaseLocal(doctypeName);
|
||||
doctypeName = nsnull;
|
||||
if (!!systemIdentifier) {
|
||||
nsHtml5Portability::releaseString(systemIdentifier);
|
||||
systemIdentifier = nsnull;
|
||||
}
|
||||
if (!!publicIdentifier) {
|
||||
nsHtml5Portability::releaseString(publicIdentifier);
|
||||
publicIdentifier = nsnull;
|
||||
}
|
||||
if (!!tagName) {
|
||||
tagName->release();
|
||||
tagName = nsnull;
|
||||
@@ -3366,6 +3376,122 @@ nsHtml5Tokenizer::isInDataState()
|
||||
return (stateSave == NS_HTML5TOKENIZER_DATA);
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::resetToDataState()
|
||||
{
|
||||
strBufLen = 0;
|
||||
longStrBufLen = 0;
|
||||
stateSave = NS_HTML5TOKENIZER_DATA;
|
||||
lastCR = PR_FALSE;
|
||||
index = 0;
|
||||
forceQuirks = PR_FALSE;
|
||||
additional = '\0';
|
||||
entCol = -1;
|
||||
lo = 0;
|
||||
hi = (nsHtml5NamedCharacters::NAMES.length - 1);
|
||||
candidate = -1;
|
||||
strBufMark = 0;
|
||||
prevValue = -1;
|
||||
value = 0;
|
||||
seenDigits = PR_FALSE;
|
||||
shouldSuspend = PR_FALSE;
|
||||
initDoctypeFields();
|
||||
if (!!tagName) {
|
||||
tagName->release();
|
||||
tagName = nsnull;
|
||||
}
|
||||
if (!!attributeName) {
|
||||
attributeName->release();
|
||||
attributeName = nsnull;
|
||||
}
|
||||
if (!!attributes) {
|
||||
delete attributes;
|
||||
attributes = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::loadState(nsHtml5Tokenizer* other)
|
||||
{
|
||||
strBufLen = other->strBufLen;
|
||||
if (strBufLen > strBuf.length) {
|
||||
strBuf.release();
|
||||
strBuf = jArray<PRUnichar,PRInt32>(strBufLen);
|
||||
}
|
||||
nsHtml5ArrayCopy::arraycopy(other->strBuf, strBuf, strBufLen);
|
||||
longStrBufLen = other->longStrBufLen;
|
||||
if (longStrBufLen > longStrBuf.length) {
|
||||
longStrBuf.release();
|
||||
longStrBuf = jArray<PRUnichar,PRInt32>(longStrBufLen);
|
||||
}
|
||||
nsHtml5ArrayCopy::arraycopy(other->longStrBuf, longStrBuf, longStrBufLen);
|
||||
stateSave = other->stateSave;
|
||||
lastCR = other->lastCR;
|
||||
index = other->index;
|
||||
forceQuirks = other->forceQuirks;
|
||||
additional = other->additional;
|
||||
entCol = other->entCol;
|
||||
lo = other->lo;
|
||||
hi = other->hi;
|
||||
candidate = other->candidate;
|
||||
strBufMark = other->strBufMark;
|
||||
prevValue = other->prevValue;
|
||||
value = other->value;
|
||||
seenDigits = other->seenDigits;
|
||||
shouldSuspend = PR_FALSE;
|
||||
nsHtml5Portability::releaseLocal(doctypeName);
|
||||
if (!other->doctypeName) {
|
||||
doctypeName = nsnull;
|
||||
} else {
|
||||
doctypeName = nsHtml5Portability::newLocalFromLocal(other->doctypeName, interner);
|
||||
}
|
||||
nsHtml5Portability::releaseString(systemIdentifier);
|
||||
if (!other->systemIdentifier) {
|
||||
systemIdentifier = nsnull;
|
||||
} else {
|
||||
systemIdentifier = nsHtml5Portability::newStringFromString(other->systemIdentifier);
|
||||
}
|
||||
nsHtml5Portability::releaseString(publicIdentifier);
|
||||
if (!other->publicIdentifier) {
|
||||
publicIdentifier = nsnull;
|
||||
} else {
|
||||
publicIdentifier = nsHtml5Portability::newStringFromString(other->publicIdentifier);
|
||||
}
|
||||
if (!!tagName) {
|
||||
tagName->release();
|
||||
}
|
||||
if (!other->tagName) {
|
||||
tagName = nsnull;
|
||||
} else {
|
||||
tagName = other->tagName->cloneElementName(interner);
|
||||
}
|
||||
if (!!attributeName) {
|
||||
attributeName->release();
|
||||
}
|
||||
if (!other->attributeName) {
|
||||
attributeName = nsnull;
|
||||
} else {
|
||||
attributeName = other->attributeName->cloneAttributeName(interner);
|
||||
}
|
||||
if (!!attributes) {
|
||||
delete attributes;
|
||||
}
|
||||
if (!other->attributes) {
|
||||
attributes = nsnull;
|
||||
} else {
|
||||
attributes = other->attributes->cloneAttributes(interner);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::initializeWithoutStarting()
|
||||
{
|
||||
confident = PR_FALSE;
|
||||
strBuf = jArray<PRUnichar,PRInt32>(64);
|
||||
longStrBuf = jArray<PRUnichar,PRInt32>(1024);
|
||||
resetToDataState();
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::setEncodingDeclarationHandler(nsHtml5StreamParser* encodingDeclarationHandler)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user