From e9af3798cbee81bc0093d4be024ecb6c2ea19bd9 Mon Sep 17 00:00:00 2001 From: Artem Strygin Date: Wed, 26 Jul 2017 16:53:06 +0300 Subject: Remove recursion from CPDF_DataAvail::HaveResourceXXX. Change-Id: Iacac67bce99b4b4bcc303fb388aaf03f2f99e4f3 Reviewed-on: https://pdfium-review.googlesource.com/9070 Commit-Queue: dsinclair Reviewed-by: dsinclair --- core/fpdfapi/parser/cpdf_data_avail.cpp | 55 ++++++++++++++++----------------- core/fpdfapi/parser/cpdf_data_avail.h | 3 -- 2 files changed, 27 insertions(+), 31 deletions(-) (limited to 'core') 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& pFileRead, @@ -1404,28 +1426,6 @@ CPDF_DataAvail::DocAvailStatus CPDF_DataAvail::CheckLinearizedFirstPage( return DataAvailable; } -bool CPDF_DataAvail::HaveResourceAncestor(CPDF_Dictionary* pDict) { - CFX_AutoRestorer 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> 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); -- cgit v1.2.3