зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
66e25f6243
Коммит
068b07cee6
|
@ -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,
|
||||
|
|
Загрузка…
Ссылка в новой задаче