diff options
author | Artem Strygin <art-snake@yandex-team.ru> | 2017-07-26 16:53:06 +0300 |
---|---|---|
committer | Chromium commit bot <commit-bot@chromium.org> | 2017-07-26 18:56:39 +0000 |
commit | e9af3798cbee81bc0093d4be024ecb6c2ea19bd9 (patch) | |
tree | c864862c40f255ae7a9b0f13bc85d685d34478db | |
parent | a37f2f1128f1167e858b605c51dfe98308919ea6 (diff) | |
download | pdfium-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.cpp | 55 | ||||
-rw-r--r-- | core/fpdfapi/parser/cpdf_data_avail.h | 3 |
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); |