Backed out changeset 16c03995ac55 (bug 1539759) for causing Buffer Overflow in nsExpatDriver.cpp

--HG--
extra : rebase_source : 0b9e64681becc725d8550f4a6820166ce8fba2bf
This commit is contained in:
Mihai Alexandru Michis 2019-05-13 18:16:39 +03:00
parent 1390ecd567
commit 8187c0826d
4 changed files with 60 additions and 105 deletions

View file

@ -1056,11 +1056,6 @@ XMLPARSEAPI(const XML_Char*)
MOZ_XML_GetMismatchedTag(XML_Parser parser); MOZ_XML_GetMismatchedTag(XML_Parser parser);
/* END MOZILLA CHANGE */ /* 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 #ifdef __cplusplus
} }
#endif #endif

View file

@ -2462,13 +2462,6 @@ MOZ_XML_GetMismatchedTag(XML_Parser parser)
} }
/* END MOZILLA CHANGE */ /* 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; /* Initially tag->rawName always points into the parse buffer;
for those TAG instances opened while the current parse buffer was 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 processed, and not yet closed, we need to store tag->rawName in a more

View file

@ -54,6 +54,21 @@ 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, static void Driver_HandleCharacterData(void* aUserData, const XML_Char* aData,
int aLength) { int aLength) {
NS_ASSERTION(aUserData, "expat driver should exist"); NS_ASSERTION(aUserData, "expat driver should exist");
@ -252,104 +267,41 @@ nsExpatDriver::~nsExpatDriver() {
} }
} }
/* static */ nsresult nsExpatDriver::HandleStartElement(const char16_t* aValue,
void nsExpatDriver::HandleStartElement(void* aUserData, const char16_t* aName, const char16_t** aAtts) {
const char16_t** aAtts) { NS_ASSERTION(mSink, "content sink not found!");
nsExpatDriver* self = static_cast<nsExpatDriver*>(aUserData);
NS_ASSERTION(self->mSink, "content sink not found!");
// Calculate the total number of elements in aAtts. // Calculate the total number of elements in aAtts.
// XML_GetSpecifiedAttributeCount will only give us the number of specified // XML_GetSpecifiedAttributeCount will only give us the number of specified
// attrs (twice that number, actually), so we have to check for default attrs // attrs (twice that number, actually), so we have to check for default attrs
// ourselves. // ourselves.
uint32_t attrArrayLength; uint32_t attrArrayLength;
for (attrArrayLength = XML_GetSpecifiedAttributeCount(self->mExpatParser); for (attrArrayLength = XML_GetSpecifiedAttributeCount(mExpatParser);
aAtts[attrArrayLength]; attrArrayLength += 2) { aAtts[attrArrayLength]; attrArrayLength += 2) {
// Just looping till we find out what the length is // Just looping till we find out what the length is
} }
if (self->mSink) { if (mSink) {
nsresult rv = self->mSink->HandleStartElement( nsresult rv = mSink->HandleStartElement(
aName, aAtts, attrArrayLength, aValue, aAtts, attrArrayLength, XML_GetCurrentLineNumber(mExpatParser),
XML_GetCurrentLineNumber(self->mExpatParser), XML_GetCurrentColumnNumber(mExpatParser));
XML_GetCurrentColumnNumber(self->mExpatParser)); MaybeStopParser(rv);
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; return NS_OK;
} }
/* static */ nsresult nsExpatDriver::HandleEndElement(const char16_t* aValue) {
void nsExpatDriver::HandleStartElementForSystemPrincipal( NS_ASSERTION(mSink, "content sink not found!");
void* aUserData, const char16_t* aName, const char16_t** aAtts) { NS_ASSERTION(mInternalState != NS_ERROR_HTMLPARSER_BLOCK,
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."); "Shouldn't block from HandleStartElement.");
if (self->mSink && self->mInternalState != NS_ERROR_HTMLPARSER_STOPPARSING) { if (mSink && mInternalState != NS_ERROR_HTMLPARSER_STOPPARSING) {
nsresult rv = self->mSink->HandleEndElement(aName); nsresult rv = mSink->HandleEndElement(aValue);
self->MaybeStopParser(rv); MaybeStopParser(rv);
} }
}
/* static */ return NS_OK;
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, nsresult nsExpatDriver::HandleCharacterData(const char16_t* aValue,
@ -694,6 +646,31 @@ static nsresult CreateErrorText(const char16_t* aDescription,
return NS_OK; 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() { nsresult nsExpatDriver::HandleError() {
int32_t code = XML_GetErrorCode(mExpatParser); int32_t code = XML_GetErrorCode(mExpatParser);
NS_ASSERTION(code > XML_ERROR_NONE, "unexpected XML error code"); NS_ASSERTION(code > XML_ERROR_NONE, "unexpected XML error code");
@ -1064,12 +1041,8 @@ nsExpatDriver::WillBuildModel(const CParserContext& aParserContext,
// Set up the callbacks // Set up the callbacks
XML_SetXmlDeclHandler(mExpatParser, Driver_HandleXMLDeclaration); XML_SetXmlDeclHandler(mExpatParser, Driver_HandleXMLDeclaration);
if (doc && doc->NodePrincipal()->IsSystemPrincipal()) { XML_SetElementHandler(mExpatParser, Driver_HandleStartElement,
XML_SetElementHandler(mExpatParser, HandleStartElementForSystemPrincipal, Driver_HandleEndElement);
HandleEndElementForSystemPrincipal);
} else {
XML_SetElementHandler(mExpatParser, HandleStartElement, HandleEndElement);
}
XML_SetCharacterDataHandler(mExpatParser, Driver_HandleCharacterData); XML_SetCharacterDataHandler(mExpatParser, Driver_HandleCharacterData);
XML_SetProcessingInstructionHandler(mExpatParser, XML_SetProcessingInstructionHandler(mExpatParser,
Driver_HandleProcessingInstruction); Driver_HandleProcessingInstruction);

View file

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