Bug 1539759 - Improve DTD entity handling. r=erahm

Differential Revision: https://phabricator.services.mozilla.com/D30248

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Peter Van der Beken 2019-05-13 07:32:42 +00:00
Родитель 66e25f6243
Коммит 068b07cee6
4 изменённых файлов: 105 добавлений и 60 удалений

Просмотреть файл

@ -1056,6 +1056,11 @@ XMLPARSEAPI(const XML_Char*)
MOZ_XML_GetMismatchedTag(XML_Parser parser);
/* END MOZILLA CHANGE */
/* BEGIN MOZILLA CHANGE (Report whether the parser is currently expanding an entity) */
XMLPARSEAPI(XML_Bool)
MOZ_XML_ProcessingEntityValue(XML_Parser parser);
/* END MOZILLA CHANGE */
#ifdef __cplusplus
}
#endif

Просмотреть файл

@ -2462,6 +2462,13 @@ MOZ_XML_GetMismatchedTag(XML_Parser parser)
}
/* END MOZILLA CHANGE */
/* BEGIN MOZILLA CHANGE (Report whether the parser is currently expanding an entity) */
XML_Bool XMLCALL
MOZ_XML_ProcessingEntityValue(XML_Parser parser) {
return openInternalEntities != NULL;
}
/* END MOZILLA CHANGE */
/* Initially tag->rawName always points into the parse buffer;
for those TAG instances opened while the current parse buffer was
processed, and not yet closed, we need to store tag->rawName in a more

Просмотреть файл

@ -54,21 +54,6 @@ static void Driver_HandleXMLDeclaration(void* aUserData,
}
}
static void Driver_HandleStartElement(void* aUserData, const XML_Char* aName,
const XML_Char** aAtts) {
NS_ASSERTION(aUserData, "expat driver should exist");
if (aUserData) {
static_cast<nsExpatDriver*>(aUserData)->HandleStartElement(aName, aAtts);
}
}
static void Driver_HandleEndElement(void* aUserData, const XML_Char* aName) {
NS_ASSERTION(aUserData, "expat driver should exist");
if (aUserData) {
static_cast<nsExpatDriver*>(aUserData)->HandleEndElement(aName);
}
}
static void Driver_HandleCharacterData(void* aUserData, const XML_Char* aData,
int aLength) {
NS_ASSERTION(aUserData, "expat driver should exist");
@ -267,41 +252,104 @@ nsExpatDriver::~nsExpatDriver() {
}
}
nsresult nsExpatDriver::HandleStartElement(const char16_t* aValue,
const char16_t** aAtts) {
NS_ASSERTION(mSink, "content sink not found!");
/* static */
void nsExpatDriver::HandleStartElement(void* aUserData, const char16_t* aName,
const char16_t** aAtts) {
nsExpatDriver* self = static_cast<nsExpatDriver*>(aUserData);
NS_ASSERTION(self->mSink, "content sink not found!");
// Calculate the total number of elements in aAtts.
// XML_GetSpecifiedAttributeCount will only give us the number of specified
// attrs (twice that number, actually), so we have to check for default attrs
// ourselves.
uint32_t attrArrayLength;
for (attrArrayLength = XML_GetSpecifiedAttributeCount(mExpatParser);
for (attrArrayLength = XML_GetSpecifiedAttributeCount(self->mExpatParser);
aAtts[attrArrayLength]; attrArrayLength += 2) {
// Just looping till we find out what the length is
}
if (mSink) {
nsresult rv = mSink->HandleStartElement(
aValue, aAtts, attrArrayLength, XML_GetCurrentLineNumber(mExpatParser),
XML_GetCurrentColumnNumber(mExpatParser));
MaybeStopParser(rv);
if (self->mSink) {
nsresult rv = self->mSink->HandleStartElement(
aName, aAtts, attrArrayLength,
XML_GetCurrentLineNumber(self->mExpatParser),
XML_GetCurrentColumnNumber(self->mExpatParser));
self->MaybeStopParser(rv);
}
}
static nsresult AppendErrorPointer(const int32_t aColNumber,
const char16_t* aSourceLine,
nsString& aSourceString) {
aSourceString.Append(char16_t('\n'));
// Last character will be '^'.
int32_t last = aColNumber - 1;
int32_t i;
uint32_t minuses = 0;
for (i = 0; i < last; ++i) {
if (aSourceLine[i] == '\t') {
// Since this uses |white-space: pre;| a tab stop equals 8 spaces.
uint32_t add = 8 - (minuses % 8);
aSourceString.AppendASCII("--------", add);
minuses += add;
} else {
aSourceString.Append(char16_t('-'));
++minuses;
}
}
aSourceString.Append(char16_t('^'));
return NS_OK;
}
nsresult nsExpatDriver::HandleEndElement(const char16_t* aValue) {
NS_ASSERTION(mSink, "content sink not found!");
NS_ASSERTION(mInternalState != NS_ERROR_HTMLPARSER_BLOCK,
/* static */
void nsExpatDriver::HandleStartElementForSystemPrincipal(
void* aUserData, const char16_t* aName, const char16_t** aAtts) {
nsExpatDriver* self = static_cast<nsExpatDriver*>(aUserData);
if (!MOZ_XML_ProcessingEntityValue(self->mExpatParser)) {
HandleStartElement(aUserData, aName, aAtts);
} else {
nsCOMPtr<Document> doc =
do_QueryInterface(self->mOriginalSink->GetTarget());
// Adjust the column number so that it is one based rather than zero based.
uint32_t colNumber = XML_GetCurrentColumnNumber(self->mExpatParser) + 1;
uint32_t lineNumber = XML_GetCurrentLineNumber(self->mExpatParser);
nsAutoString sourceText(self->mLastLine);
AppendErrorPointer(colNumber, self->mLastLine.get(), sourceText);
nsContentUtils::ReportToConsoleNonLocalized(
NS_LITERAL_STRING("Ignored element created from entity value."),
nsIScriptError::warningFlag, NS_LITERAL_CSTRING("XML Document"), doc,
nullptr, sourceText, lineNumber, colNumber);
}
}
/* static */
void nsExpatDriver::HandleEndElement(void* aUserData, const char16_t* aName) {
nsExpatDriver* self = static_cast<nsExpatDriver*>(aUserData);
NS_ASSERTION(self->mSink, "content sink not found!");
NS_ASSERTION(self->mInternalState != NS_ERROR_HTMLPARSER_BLOCK,
"Shouldn't block from HandleStartElement.");
if (mSink && mInternalState != NS_ERROR_HTMLPARSER_STOPPARSING) {
nsresult rv = mSink->HandleEndElement(aValue);
MaybeStopParser(rv);
if (self->mSink && self->mInternalState != NS_ERROR_HTMLPARSER_STOPPARSING) {
nsresult rv = self->mSink->HandleEndElement(aName);
self->MaybeStopParser(rv);
}
}
return NS_OK;
/* static */
void nsExpatDriver::HandleEndElementForSystemPrincipal(void* aUserData,
const char16_t* aName) {
nsExpatDriver* self = static_cast<nsExpatDriver*>(aUserData);
if (!MOZ_XML_ProcessingEntityValue(self->mExpatParser)) {
HandleEndElement(aUserData, aName);
}
}
nsresult nsExpatDriver::HandleCharacterData(const char16_t* aValue,
@ -646,31 +694,6 @@ static nsresult CreateErrorText(const char16_t* aDescription,
return NS_OK;
}
static nsresult AppendErrorPointer(const int32_t aColNumber,
const char16_t* aSourceLine,
nsString& aSourceString) {
aSourceString.Append(char16_t('\n'));
// Last character will be '^'.
int32_t last = aColNumber - 1;
int32_t i;
uint32_t minuses = 0;
for (i = 0; i < last; ++i) {
if (aSourceLine[i] == '\t') {
// Since this uses |white-space: pre;| a tab stop equals 8 spaces.
uint32_t add = 8 - (minuses % 8);
aSourceString.AppendASCII("--------", add);
minuses += add;
} else {
aSourceString.Append(char16_t('-'));
++minuses;
}
}
aSourceString.Append(char16_t('^'));
return NS_OK;
}
nsresult nsExpatDriver::HandleError() {
int32_t code = XML_GetErrorCode(mExpatParser);
NS_ASSERTION(code > XML_ERROR_NONE, "unexpected XML error code");
@ -1041,8 +1064,12 @@ nsExpatDriver::WillBuildModel(const CParserContext& aParserContext,
// Set up the callbacks
XML_SetXmlDeclHandler(mExpatParser, Driver_HandleXMLDeclaration);
XML_SetElementHandler(mExpatParser, Driver_HandleStartElement,
Driver_HandleEndElement);
if (doc && doc->NodePrincipal()->IsSystemPrincipal()) {
XML_SetElementHandler(mExpatParser, HandleStartElementForSystemPrincipal,
HandleEndElementForSystemPrincipal);
} else {
XML_SetElementHandler(mExpatParser, HandleStartElement, HandleEndElement);
}
XML_SetCharacterDataHandler(mExpatParser, Driver_HandleCharacterData);
XML_SetProcessingInstructionHandler(mExpatParser,
Driver_HandleProcessingInstruction);

Просмотреть файл

@ -33,8 +33,14 @@ class nsExpatDriver : public nsIDTD, public nsITokenizer {
int HandleExternalEntityRef(const char16_t* aOpenEntityNames,
const char16_t* aBase, const char16_t* aSystemId,
const char16_t* aPublicId);
nsresult HandleStartElement(const char16_t* aName, const char16_t** aAtts);
nsresult HandleEndElement(const char16_t* aName);
static void HandleStartElement(void* aUserData, const char16_t* aName,
const char16_t** aAtts);
static void HandleStartElementForSystemPrincipal(void* aUserData,
const char16_t* aName,
const char16_t** aAtts);
static void HandleEndElement(void* aUserData, const char16_t* aName);
static void HandleEndElementForSystemPrincipal(void* aUserData,
const char16_t* aName);
nsresult HandleCharacterData(const char16_t* aCData, const uint32_t aLength);
nsresult HandleComment(const char16_t* aName);
nsresult HandleProcessingInstruction(const char16_t* aTarget,