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-21 18:24:02 +00:00
parent eb29ae8571
commit 3991c12564
4 changed files with 92 additions and 37 deletions

View File

@ -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

View File

@ -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

View File

@ -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,89 @@ 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);
}
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);
int32_t nameSpaceID;
RefPtr<nsAtom> prefix, localName;
nsContentUtils::SplitExpatName(aName, getter_AddRefs(prefix),
getter_AddRefs(localName), &nameSpaceID);
nsAutoString error;
error.AppendLiteral("Ignoring element <");
if (prefix) {
error.Append(prefix->GetUTF16String());
error.Append(':');
}
error.Append(localName->GetUTF16String());
error.AppendLiteral("> created from entity value.");
nsContentUtils::ReportToConsoleNonLocalized(
error, nsIScriptError::warningFlag, NS_LITERAL_CSTRING("XML Document"),
doc, nullptr, EmptyString(), 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,
@ -1041,8 +1074,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);

View File

@ -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,