diff options
author | Pale Moon <git-repo@palemoon.org> | 2014-11-18 10:25:39 +0100 |
---|---|---|
committer | Pale Moon <git-repo@palemoon.org> | 2014-11-18 10:25:39 +0100 |
commit | 0b32321ffd4faa2e93068f3e7c2e0bb2df3d7c6b (patch) | |
tree | ced38d60d5e627a22d3f918238d0c615b6d7ba88 /parser/htmlparser | |
parent | 6fb0a31b5bb396fa4a5a99c2316f5895b8d2843e (diff) | |
download | palemoon-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.cpp | 15 | ||||
-rw-r--r-- | parser/htmlparser/src/nsExpatDriver.h | 4 |
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). |