From 84faa032e327ad61e38197114a164e969051b5af Mon Sep 17 00:00:00 2001 From: Lei Zhang Date: Fri, 28 Apr 2017 13:44:31 -0700 Subject: Limit recursion in CXML_Parser::ParseElement(). BUG=chromium:716526 Change-Id: Idbe4624ab2193cee2931c69ed023dd2c1679d124 Reviewed-on: https://pdfium-review.googlesource.com/4615 Reviewed-by: Tom Sepez Commit-Queue: Lei Zhang --- core/fxcrt/xml/cxml_element.cpp | 9 +++++++++ core/fxcrt/xml/cxml_parser.cpp | 24 ++++++++++++++---------- core/fxcrt/xml/cxml_parser.h | 4 ++++ 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/core/fxcrt/xml/cxml_element.cpp b/core/fxcrt/xml/cxml_element.cpp index 17caebfa14..95a6dba147 100644 --- a/core/fxcrt/xml/cxml_element.cpp +++ b/core/fxcrt/xml/cxml_element.cpp @@ -9,6 +9,15 @@ #include "core/fxcrt/xml/cxml_content.h" #include "core/fxcrt/xml/cxml_parser.h" +// static +std::unique_ptr CXML_Element::Parse(const void* pBuffer, + size_t size) { + CXML_Parser parser; + if (!parser.Init(static_cast(pBuffer), size)) + return nullptr; + return parser.ParseElement(nullptr, false); +} + CXML_Element::CXML_Element(const CXML_Element* pParent, const CFX_ByteStringC& qSpace, const CFX_ByteStringC& tagname) diff --git a/core/fxcrt/xml/cxml_parser.cpp b/core/fxcrt/xml/cxml_parser.cpp index 691a86eaf6..dc3978e2d2 100644 --- a/core/fxcrt/xml/cxml_parser.cpp +++ b/core/fxcrt/xml/cxml_parser.cpp @@ -53,6 +53,8 @@ const uint8_t g_FXCRT_XML_ByteTypes[256] = { 0x1A, 0x1A, 0x01, 0x01, }; +constexpr int kMaxDepth = 1024; + bool g_FXCRT_XML_IsWhiteSpace(uint8_t ch) { return !!(g_FXCRT_XML_ByteTypes[ch] & FXCRTM_XML_CHARTYPE_SpaceChar); } @@ -369,6 +371,16 @@ void CXML_Parser::GetTagName(bool bStartTag, std::unique_ptr CXML_Parser::ParseElement(CXML_Element* pParent, bool bStartTag) { + return ParseElementInternal(pParent, bStartTag, 0); +} + +std::unique_ptr CXML_Parser::ParseElementInternal( + CXML_Element* pParent, + bool bStartTag, + int nDepth) { + if (nDepth > kMaxDepth) + return nullptr; + m_nOffset = m_nBufferOffset + static_cast(m_dwIndex); if (IsEOF()) return nullptr; @@ -476,8 +488,8 @@ std::unique_ptr CXML_Parser::ParseElement(CXML_Element* pParent, bCDATA = false; iState = 0; m_dwIndex--; - std::unique_ptr pSubElement( - ParseElement(pElement.get(), true)); + std::unique_ptr pSubElement = + ParseElementInternal(pElement.get(), true, nDepth + 1); if (!pSubElement) break; @@ -529,11 +541,3 @@ void CXML_Parser::InsertContentSegment(bool bCDATA, pContent->Set(bCDATA, content); pElement->m_Children.push_back({CXML_Element::Content, pContent}); } - -std::unique_ptr CXML_Element::Parse(const void* pBuffer, - size_t size) { - CXML_Parser parser; - if (!parser.Init(static_cast(pBuffer), size)) - return nullptr; - return parser.ParseElement(nullptr, false); -} diff --git a/core/fxcrt/xml/cxml_parser.h b/core/fxcrt/xml/cxml_parser.h index 371edf2ebb..33bd711ee1 100644 --- a/core/fxcrt/xml/cxml_parser.h +++ b/core/fxcrt/xml/cxml_parser.h @@ -42,6 +42,10 @@ class CXML_Parser { void InsertCDATASegment(CFX_UTF8Decoder& decoder, CXML_Element* pElement); private: + std::unique_ptr ParseElementInternal(CXML_Element* pParent, + bool bStartTag, + int nDepth); + std::unique_ptr m_pDataAcc; FX_FILESIZE m_nOffset; const uint8_t* m_pBuffer; -- cgit v1.2.3