summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--parser/htmlparser/nsExpatDriver.cpp14
-rw-r--r--parser/htmlparser/nsExpatDriver.h7
2 files changed, 17 insertions, 4 deletions
diff --git a/parser/htmlparser/nsExpatDriver.cpp b/parser/htmlparser/nsExpatDriver.cpp
index 8882ec593..9cf888f69 100644
--- a/parser/htmlparser/nsExpatDriver.cpp
+++ b/parser/htmlparser/nsExpatDriver.cpp
@@ -338,6 +338,9 @@ NS_IMPL_CYCLE_COLLECTING_RELEASE(nsExpatDriver)
NS_IMPL_CYCLE_COLLECTION(nsExpatDriver, mSink, mExtendedSink)
+// We store the tagdepth in a Uint8, so make sure the limit fits in a Uint8.
+PR_STATIC_ASSERT(MAX_XML_TREE_DEPTH <= UINT8_MAX);
+
nsExpatDriver::nsExpatDriver()
: mExpatParser(nullptr),
mInCData(false),
@@ -345,6 +348,7 @@ nsExpatDriver::nsExpatDriver()
mInExternalDTD(false),
mMadeFinalCallToExpat(false),
mIsFinalChunk(false),
+ mTagDepth(0),
mInternalState(NS_OK),
mExpatBuffered(0),
mCatalogData(nullptr),
@@ -359,7 +363,7 @@ nsExpatDriver::~nsExpatDriver()
}
}
-nsresult
+void
nsExpatDriver::HandleStartElement(const char16_t *aValue,
const char16_t **aAtts)
{
@@ -377,13 +381,16 @@ nsExpatDriver::HandleStartElement(const char16_t *aValue,
}
if (mSink) {
+ if (++mTagDepth == MAX_XML_TREE_DEPTH) {
+ MaybeStopParser(NS_ERROR_HTMLPARSER_HIERARCHYTOODEEP);
+ return;
+ }
+
nsresult rv = mSink->
HandleStartElement(aValue, aAtts, attrArrayLength,
XML_GetCurrentLineNumber(mExpatParser));
MaybeStopParser(rv);
}
-
- return NS_OK;
}
nsresult
@@ -395,6 +402,7 @@ nsExpatDriver::HandleEndElement(const char16_t *aValue)
if (mSink && mInternalState != NS_ERROR_HTMLPARSER_STOPPARSING) {
nsresult rv = mSink->HandleEndElement(aValue);
+ --mTagDepth;
MaybeStopParser(rv);
}
diff --git a/parser/htmlparser/nsExpatDriver.h b/parser/htmlparser/nsExpatDriver.h
index 1bf022ade..0d62bd09d 100644
--- a/parser/htmlparser/nsExpatDriver.h
+++ b/parser/htmlparser/nsExpatDriver.h
@@ -16,6 +16,9 @@
#include "nsIParser.h"
#include "nsCycleCollectionParticipant.h"
+// Tree depth limit for XML-based files (xml/svg/etc.)
+#define MAX_XML_TREE_DEPTH 200
+
class nsIExpatSink;
class nsIExtendedExpatSink;
struct nsCatalogData;
@@ -37,7 +40,7 @@ public:
const char16_t *aBase,
const char16_t *aSystemId,
const char16_t *aPublicId);
- nsresult HandleStartElement(const char16_t *aName, const char16_t **aAtts);
+ void HandleStartElement(const char16_t *aName, const char16_t **aAtts);
nsresult HandleEndElement(const char16_t *aName);
nsresult HandleCharacterData(const char16_t *aCData, const uint32_t aLength);
nsresult HandleComment(const char16_t *aName);
@@ -119,6 +122,8 @@ private:
// Whether we're sure that we won't be getting more buffers to parse from
// Necko
bool mIsFinalChunk;
+
+ uint8_t mTagDepth;
nsresult mInternalState;