summaryrefslogtreecommitdiff
path: root/parser/htmlparser
diff options
context:
space:
mode:
authorPale Moon <git-repo@palemoon.org>2014-11-18 10:25:39 +0100
committerPale Moon <git-repo@palemoon.org>2014-11-18 10:25:39 +0100
commit0b32321ffd4faa2e93068f3e7c2e0bb2df3d7c6b (patch)
treeced38d60d5e627a22d3f918238d0c615b6d7ba88 /parser/htmlparser
parent6fb0a31b5bb396fa4a5a99c2316f5895b8d2843e (diff)
downloadpalemoon-gre-0b32321ffd4faa2e93068f3e7c2e0bb2df3d7c6b.tar.gz
Crash fix: prevent crash from excessive tag depths in data files.
Limit is taken from layout reflow depth (200 at this time) although never allowed to be > UInt8 (255). 200 levels of nesting should certainly suffice.
Diffstat (limited to 'parser/htmlparser')
-rw-r--r--parser/htmlparser/src/nsExpatDriver.cpp15
-rw-r--r--parser/htmlparser/src/nsExpatDriver.h4
2 files changed, 15 insertions, 4 deletions
diff --git a/parser/htmlparser/src/nsExpatDriver.cpp b/parser/htmlparser/src/nsExpatDriver.cpp
index d036f851f..ae8d895ba 100644
--- a/parser/htmlparser/src/nsExpatDriver.cpp
+++ b/parser/htmlparser/src/nsExpatDriver.cpp
@@ -27,6 +27,7 @@
#include "nsError.h"
#include "nsXPCOMCIDInternal.h"
#include "nsUnicharInputStream.h"
+#include "nsIFrame.h"
#define kExpatSeparatorChar 0xFFFF
@@ -340,6 +341,9 @@ NS_IMPL_CYCLE_COLLECTING_RELEASE(nsExpatDriver)
NS_IMPL_CYCLE_COLLECTION_2(nsExpatDriver, mSink, mExtendedSink)
+// We store the tagdepth in a PRUint8, so make sure the limit fits in a PRUint8.
+PR_STATIC_ASSERT(MAX_REFLOW_DEPTH <= PR_UINT8_MAX);
+
nsExpatDriver::nsExpatDriver()
: mExpatParser(nullptr),
mInCData(false),
@@ -347,6 +351,7 @@ nsExpatDriver::nsExpatDriver()
mInExternalDTD(false),
mMadeFinalCallToExpat(false),
mIsFinalChunk(false),
+ mTagDepth(0),
mInternalState(NS_OK),
mExpatBuffered(0),
mCatalogData(nullptr),
@@ -361,7 +366,7 @@ nsExpatDriver::~nsExpatDriver()
}
}
-nsresult
+void
nsExpatDriver::HandleStartElement(const PRUnichar *aValue,
const PRUnichar **aAtts)
{
@@ -379,14 +384,17 @@ nsExpatDriver::HandleStartElement(const PRUnichar *aValue,
}
if (mSink) {
+ if (++mTagDepth == MAX_REFLOW_DEPTH) {
+ MaybeStopParser(NS_ERROR_HTMLPARSER_HIERARCHYTOODEEP);
+ return;
+ }
+
nsresult rv = mSink->
HandleStartElement(aValue, aAtts, attrArrayLength,
XML_GetIdAttributeIndex(mExpatParser),
XML_GetCurrentLineNumber(mExpatParser));
MaybeStopParser(rv);
}
-
- return NS_OK;
}
nsresult
@@ -398,6 +406,7 @@ nsExpatDriver::HandleEndElement(const PRUnichar *aValue)
if (mSink && mInternalState != NS_ERROR_HTMLPARSER_STOPPARSING) {
nsresult rv = mSink->HandleEndElement(aValue);
+ --mTagDepth;
MaybeStopParser(rv);
}
diff --git a/parser/htmlparser/src/nsExpatDriver.h b/parser/htmlparser/src/nsExpatDriver.h
index 9a709704a..82bb860ee 100644
--- a/parser/htmlparser/src/nsExpatDriver.h
+++ b/parser/htmlparser/src/nsExpatDriver.h
@@ -36,7 +36,7 @@ public:
const PRUnichar *aBase,
const PRUnichar *aSystemId,
const PRUnichar *aPublicId);
- nsresult HandleStartElement(const PRUnichar *aName, const PRUnichar **aAtts);
+ void HandleStartElement(const PRUnichar *aName, const PRUnichar **aAtts);
nsresult HandleEndElement(const PRUnichar *aName);
nsresult HandleCharacterData(const PRUnichar *aCData, const uint32_t aLength);
nsresult HandleComment(const PRUnichar *aName);
@@ -121,6 +121,8 @@ private:
// Necko
bool mIsFinalChunk;
+ PRUint8 mTagDepth;
+
nsresult mInternalState;
// The length of the data in Expat's buffer (in number of PRUnichars).