summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArtem Strygin <art-snake@yandex-team.ru>2017-07-26 16:53:06 +0300
committerChromium commit bot <commit-bot@chromium.org>2017-07-26 18:56:39 +0000
commite9af3798cbee81bc0093d4be024ecb6c2ea19bd9 (patch)
treec864862c40f255ae7a9b0f13bc85d685d34478db
parenta37f2f1128f1167e858b605c51dfe98308919ea6 (diff)
downloadpdfium-e9af3798cbee81bc0093d4be024ecb6c2ea19bd9.tar.xz
Remove recursion from CPDF_DataAvail::HaveResourceXXX.
Change-Id: Iacac67bce99b4b4bcc303fb388aaf03f2f99e4f3 Reviewed-on: https://pdfium-review.googlesource.com/9070 Commit-Queue: dsinclair <dsinclair@chromium.org> Reviewed-by: dsinclair <dsinclair@chromium.org>
-rw-r--r--core/fpdfapi/parser/cpdf_data_avail.cpp55
-rw-r--r--core/fpdfapi/parser/cpdf_data_avail.h3
2 files changed, 27 insertions, 31 deletions
diff --git a/core/fpdfapi/parser/cpdf_data_avail.cpp b/core/fpdfapi/parser/cpdf_data_avail.cpp
index 05f8272171..043462c3bb 100644
--- a/core/fpdfapi/parser/cpdf_data_avail.cpp
+++ b/core/fpdfapi/parser/cpdf_data_avail.cpp
@@ -28,13 +28,35 @@
#include "third_party/base/ptr_util.h"
#include "third_party/base/stl_util.h"
+namespace {
+
+// static
+CPDF_Object* GetResourceObject(CPDF_Dictionary* pDict) {
+ constexpr size_t kMaxHierarchyDepth = 64;
+ size_t depth = 0;
+
+ CPDF_Dictionary* dictionary_to_check = pDict;
+ while (dictionary_to_check) {
+ CPDF_Object* result = dictionary_to_check->GetObjectFor("Resources");
+ if (result)
+ return result;
+ const CPDF_Object* parent = dictionary_to_check->GetObjectFor("Parent");
+ dictionary_to_check = parent ? parent->GetDict() : nullptr;
+
+ if (++depth > kMaxHierarchyDepth) {
+ // We have cycle in parents hierarchy.
+ return nullptr;
+ }
+ }
+ return nullptr;
+}
+
+} // namespace
+
CPDF_DataAvail::FileAvail::~FileAvail() {}
CPDF_DataAvail::DownloadHints::~DownloadHints() {}
-// static
-int CPDF_DataAvail::s_CurrentDataAvailRecursionDepth = 0;
-
CPDF_DataAvail::CPDF_DataAvail(
FileAvail* pFileAvail,
const CFX_RetainPtr<IFX_SeekableReadStream>& pFileRead,
@@ -1404,28 +1426,6 @@ CPDF_DataAvail::DocAvailStatus CPDF_DataAvail::CheckLinearizedFirstPage(
return DataAvailable;
}
-bool CPDF_DataAvail::HaveResourceAncestor(CPDF_Dictionary* pDict) {
- CFX_AutoRestorer<int> restorer(&s_CurrentDataAvailRecursionDepth);
- if (++s_CurrentDataAvailRecursionDepth > kMaxDataAvailRecursionDepth)
- return false;
-
- CPDF_Object* pParent = pDict->GetObjectFor("Parent");
- if (!pParent)
- return false;
-
- CPDF_Dictionary* pParentDict = pParent->GetDict();
- if (!pParentDict)
- return false;
-
- CPDF_Object* pRet = pParentDict->GetObjectFor("Resources");
- if (pRet) {
- m_pPageResource = pRet;
- return true;
- }
-
- return HaveResourceAncestor(pParentDict);
-}
-
CPDF_DataAvail::DocAvailStatus CPDF_DataAvail::IsPageAvail(
uint32_t dwPage,
DownloadHints* pHints) {
@@ -1527,9 +1527,8 @@ CPDF_DataAvail::DocAvailStatus CPDF_DataAvail::IsPageAvail(
}
if (m_pPageDict && !m_bNeedDownLoadResource) {
- m_pPageResource = m_pPageDict->GetObjectFor("Resources");
- m_bNeedDownLoadResource =
- m_pPageResource || HaveResourceAncestor(m_pPageDict);
+ m_pPageResource = GetResourceObject(m_pPageDict);
+ m_bNeedDownLoadResource = !!m_pPageResource;
}
if (m_bNeedDownLoadResource) {
diff --git a/core/fpdfapi/parser/cpdf_data_avail.h b/core/fpdfapi/parser/cpdf_data_avail.h
index 596fb0bd2e..eb45c144c8 100644
--- a/core/fpdfapi/parser/cpdf_data_avail.h
+++ b/core/fpdfapi/parser/cpdf_data_avail.h
@@ -124,8 +124,6 @@ class CPDF_DataAvail final {
std::vector<std::unique_ptr<PageNode>> m_ChildNodes;
};
- static const int kMaxDataAvailRecursionDepth = 64;
- static int s_CurrentDataAvailRecursionDepth;
static const int kMaxPageRecursionDepth = 1024;
uint32_t GetObjectSize(uint32_t objnum, FX_FILESIZE& offset);
@@ -175,7 +173,6 @@ class CPDF_DataAvail final {
DocAvailStatus CheckLinearizedFirstPage(uint32_t dwPage,
DownloadHints* pHints);
- bool HaveResourceAncestor(CPDF_Dictionary* pDict);
bool CheckPage(uint32_t dwPage, DownloadHints* pHints);
bool LoadDocPages(DownloadHints* pHints);
bool LoadDocPage(uint32_t dwPage, DownloadHints* pHints);