summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorLei Zhang <thestig@chromium.org>2017-04-28 13:44:31 -0700
committerChromium commit bot <commit-bot@chromium.org>2017-04-28 21:58:06 +0000
commit84faa032e327ad61e38197114a164e969051b5af (patch)
tree12839bd4a16e77b9ad489c56caf85e8709e7261e /core
parent9ebdfcb1cb8f7498afa4a2680b944d13a9fac6a5 (diff)
downloadpdfium-84faa032e327ad61e38197114a164e969051b5af.tar.xz
Limit recursion in CXML_Parser::ParseElement().
BUG=chromium:716526 Change-Id: Idbe4624ab2193cee2931c69ed023dd2c1679d124 Reviewed-on: https://pdfium-review.googlesource.com/4615 Reviewed-by: Tom Sepez <tsepez@chromium.org> Commit-Queue: Lei Zhang <thestig@chromium.org>
Diffstat (limited to 'core')
-rw-r--r--core/fxcrt/xml/cxml_element.cpp9
-rw-r--r--core/fxcrt/xml/cxml_parser.cpp24
-rw-r--r--core/fxcrt/xml/cxml_parser.h4
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> CXML_Element::Parse(const void* pBuffer,
+ size_t size) {
+ CXML_Parser parser;
+ if (!parser.Init(static_cast<const uint8_t*>(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_Element> CXML_Parser::ParseElement(CXML_Element* pParent,
bool bStartTag) {
+ return ParseElementInternal(pParent, bStartTag, 0);
+}
+
+std::unique_ptr<CXML_Element> CXML_Parser::ParseElementInternal(
+ CXML_Element* pParent,
+ bool bStartTag,
+ int nDepth) {
+ if (nDepth > kMaxDepth)
+ return nullptr;
+
m_nOffset = m_nBufferOffset + static_cast<FX_FILESIZE>(m_dwIndex);
if (IsEOF())
return nullptr;
@@ -476,8 +488,8 @@ std::unique_ptr<CXML_Element> CXML_Parser::ParseElement(CXML_Element* pParent,
bCDATA = false;
iState = 0;
m_dwIndex--;
- std::unique_ptr<CXML_Element> pSubElement(
- ParseElement(pElement.get(), true));
+ std::unique_ptr<CXML_Element> 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> CXML_Element::Parse(const void* pBuffer,
- size_t size) {
- CXML_Parser parser;
- if (!parser.Init(static_cast<const uint8_t*>(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<CXML_Element> ParseElementInternal(CXML_Element* pParent,
+ bool bStartTag,
+ int nDepth);
+
std::unique_ptr<CXML_DataBufAcc> m_pDataAcc;
FX_FILESIZE m_nOffset;
const uint8_t* m_pBuffer;