From 93c886b7ce59f6e65fe885330558c52f51cfcab9 Mon Sep 17 00:00:00 2001 From: Artem Strygin Date: Mon, 14 Aug 2017 23:28:58 +0300 Subject: Refactoring of CPDF_DataAvail::AreObjectsAvailable. Use ReadValidator to request exact data on object read. Change-Id: Ie6c3f452e119fa3514e77f1824473c33bb6b855a Reviewed-on: https://pdfium-review.googlesource.com/10491 Commit-Queue: Art Snake Reviewed-by: dsinclair --- core/fpdfapi/parser/cpdf_data_avail.cpp | 87 ++++++++++++++++++--------------- core/fpdfapi/parser/cpdf_data_avail.h | 11 ++--- 2 files changed, 52 insertions(+), 46 deletions(-) (limited to 'core/fpdfapi/parser') diff --git a/core/fpdfapi/parser/cpdf_data_avail.cpp b/core/fpdfapi/parser/cpdf_data_avail.cpp index 46c71a5ab9..2f17345ab6 100644 --- a/core/fpdfapi/parser/cpdf_data_avail.cpp +++ b/core/fpdfapi/parser/cpdf_data_avail.cpp @@ -52,17 +52,17 @@ CPDF_Object* GetResourceObject(CPDF_Dictionary* pDict) { return nullptr; } -class HintsAssigner { +class HintsScope { public: - HintsAssigner(CPDF_ReadValidator* validator, - CPDF_DataAvail::DownloadHints* hints) + HintsScope(CPDF_ReadValidator* validator, + CPDF_DataAvail::DownloadHints* hints) : validator_(validator) { ASSERT(validator_); validator_->ResetErrors(); validator_->SetDownloadHints(hints); } - ~HintsAssigner() { validator_->SetDownloadHints(nullptr); } + ~HintsScope() { validator_->SetDownloadHints(nullptr); } private: CFX_UnownedPtr validator_; @@ -155,7 +155,6 @@ uint32_t CPDF_DataAvail::GetObjectSize(uint32_t objnum, FX_FILESIZE& offset) { bool CPDF_DataAvail::AreObjectsAvailable(std::vector& obj_array, bool bParsePage, - DownloadHints* pHints, std::vector& ret_array) { if (obj_array.empty()) return true; @@ -188,24 +187,25 @@ bool CPDF_DataAvail::AreObjectsAvailable(std::vector& obj_array, break; } case CPDF_Object::REFERENCE: { + const CPDF_ReadValidator::Session read_session(GetValidator().Get()); + CPDF_Reference* pRef = pObj->AsReference(); - uint32_t dwNum = pRef->GetRefObjNum(); + const uint32_t dwNum = pRef->GetRefObjNum(); - FX_FILESIZE offset; - uint32_t size = GetObjectSize(dwNum, offset); - if (size == 0 || offset < 0 || offset >= m_dwFileLen) + if (pdfium::ContainsKey(m_ObjectSet, dwNum)) break; - if (!IsDataAvail(offset, size, pHints)) { + CPDF_Object* pReferred = m_pDocument->GetOrParseIndirectObject(dwNum); + if (GetValidator()->has_read_problems()) { + ASSERT(!pReferred); ret_array.push_back(pObj); - count++; - } else if (!pdfium::ContainsKey(m_ObjectSet, dwNum)) { - m_ObjectSet.insert(dwNum); - CPDF_Object* pReferred = - m_pDocument->GetOrParseIndirectObject(pRef->GetRefObjNum()); - if (pReferred) - new_obj_array.push_back(pReferred); + ++count; + break; } + m_ObjectSet.insert(dwNum); + if (pReferred) + new_obj_array.push_back(pReferred); + break; } } @@ -222,7 +222,7 @@ bool CPDF_DataAvail::AreObjectsAvailable(std::vector& obj_array, } obj_array = new_obj_array; - return AreObjectsAvailable(obj_array, false, pHints, ret_array); + return AreObjectsAvailable(obj_array, false, ret_array); } CPDF_DataAvail::DocAvailStatus CPDF_DataAvail::IsDocAvail( @@ -230,7 +230,7 @@ CPDF_DataAvail::DocAvailStatus CPDF_DataAvail::IsDocAvail( if (!m_dwFileLen) return DataError; - const HintsAssigner hints_assigner(m_pFileRead.Get(), pHints); + const HintsScope hints_scope(m_pFileRead.Get(), pHints); while (!m_bDocAvail) { if (!CheckDocStatus(pHints)) @@ -240,7 +240,7 @@ CPDF_DataAvail::DocAvailStatus CPDF_DataAvail::IsDocAvail( return DataAvailable; } -bool CPDF_DataAvail::CheckAcroFormSubObject(DownloadHints* pHints) { +bool CPDF_DataAvail::CheckAcroFormSubObject() { if (m_objs_array.empty()) { std::vector obj_array(m_Acroforms.size()); std::transform( @@ -248,7 +248,7 @@ bool CPDF_DataAvail::CheckAcroFormSubObject(DownloadHints* pHints) { [](const std::unique_ptr& pObj) { return pObj.get(); }); m_ObjectSet.clear(); - if (!AreObjectsAvailable(obj_array, false, pHints, m_objs_array)) + if (!AreObjectsAvailable(obj_array, false, m_objs_array)) return false; m_objs_array.clear(); @@ -256,7 +256,7 @@ bool CPDF_DataAvail::CheckAcroFormSubObject(DownloadHints* pHints) { } std::vector new_objs_array; - if (!AreObjectsAvailable(m_objs_array, false, pHints, new_objs_array)) { + if (!AreObjectsAvailable(m_objs_array, false, new_objs_array)) { m_objs_array = new_objs_array; return false; } @@ -1392,7 +1392,7 @@ CPDF_DataAvail::DocAvailStatus CPDF_DataAvail::CheckLinearizedData( return m_bLinearedDataOK ? DataAvailable : DataNotAvailable; } -bool CPDF_DataAvail::CheckPageAnnots(uint32_t dwPage, DownloadHints* pHints) { +bool CPDF_DataAvail::CheckPageAnnots(uint32_t dwPage) { if (m_objs_array.empty()) { m_ObjectSet.clear(); @@ -1407,7 +1407,7 @@ bool CPDF_DataAvail::CheckPageAnnots(uint32_t dwPage, DownloadHints* pHints) { std::vector obj_array; obj_array.push_back(pAnnots); - if (!AreObjectsAvailable(obj_array, false, pHints, m_objs_array)) + if (!AreObjectsAvailable(obj_array, false, m_objs_array)) return false; m_objs_array.clear(); @@ -1415,7 +1415,7 @@ bool CPDF_DataAvail::CheckPageAnnots(uint32_t dwPage, DownloadHints* pHints) { } std::vector new_objs_array; - if (!AreObjectsAvailable(m_objs_array, false, pHints, new_objs_array)) { + if (!AreObjectsAvailable(m_objs_array, false, new_objs_array)) { m_objs_array = new_objs_array; return false; } @@ -1424,10 +1424,9 @@ bool CPDF_DataAvail::CheckPageAnnots(uint32_t dwPage, DownloadHints* pHints) { } CPDF_DataAvail::DocAvailStatus CPDF_DataAvail::CheckLinearizedFirstPage( - uint32_t dwPage, - DownloadHints* pHints) { + uint32_t dwPage) { if (!m_bAnnotsLoad) { - if (!CheckPageAnnots(dwPage, pHints)) + if (!CheckPageAnnots(dwPage)) return DataNotAvailable; m_bAnnotsLoad = true; } @@ -1454,9 +1453,11 @@ CPDF_DataAvail::DocAvailStatus CPDF_DataAvail::IsPageAvail( if (pdfium::ContainsKey(m_pagesLoadState, dwPage)) return DataAvailable; + const HintsScope hints_scope(GetValidator().Get(), pHints); + if (m_pLinearized) { if (dwPage == m_pLinearized->GetFirstPageNo()) { - DocAvailStatus nRet = CheckLinearizedFirstPage(dwPage, pHints); + DocAvailStatus nRet = CheckLinearizedFirstPage(dwPage); if (nRet == DataAvailable) m_pagesLoadState.insert(dwPage); return nRet; @@ -1496,7 +1497,7 @@ CPDF_DataAvail::DocAvailStatus CPDF_DataAvail::IsPageAvail( } if (m_bHaveAcroForm && !m_bAcroFormLoad) { - if (!CheckAcroFormSubObject(pHints)) + if (!CheckAcroFormSubObject()) return DataNotAvailable; m_bAcroFormLoad = true; } @@ -1515,13 +1516,13 @@ CPDF_DataAvail::DocAvailStatus CPDF_DataAvail::IsPageAvail( std::vector obj_array; obj_array.push_back(m_pPageDict); - if (!AreObjectsAvailable(obj_array, true, pHints, m_objs_array)) + if (!AreObjectsAvailable(obj_array, true, m_objs_array)) return DataNotAvailable; m_objs_array.clear(); } else { std::vector new_objs_array; - if (!AreObjectsAvailable(m_objs_array, false, pHints, new_objs_array)) { + if (!AreObjectsAvailable(m_objs_array, false, new_objs_array)) { m_objs_array = new_objs_array; return DataNotAvailable; } @@ -1531,7 +1532,7 @@ CPDF_DataAvail::DocAvailStatus CPDF_DataAvail::IsPageAvail( } if (!m_bAnnotsLoad) { - if (!CheckPageAnnots(dwPage, pHints)) + if (!CheckPageAnnots(dwPage)) return DataNotAvailable; m_bAnnotsLoad = true; } @@ -1542,7 +1543,7 @@ CPDF_DataAvail::DocAvailStatus CPDF_DataAvail::IsPageAvail( } if (m_bNeedDownLoadResource) { - if (!CheckResources(pHints)) + if (!CheckResources()) return DataNotAvailable; m_bNeedDownLoadResource = false; } @@ -1558,18 +1559,18 @@ CPDF_DataAvail::DocAvailStatus CPDF_DataAvail::IsPageAvail( return DataAvailable; } -bool CPDF_DataAvail::CheckResources(DownloadHints* pHints) { +bool CPDF_DataAvail::CheckResources() { if (m_objs_array.empty()) { std::vector obj_array; obj_array.push_back(m_pPageResource); - if (!AreObjectsAvailable(obj_array, true, pHints, m_objs_array)) + if (!AreObjectsAvailable(obj_array, true, m_objs_array)) return false; m_objs_array.clear(); return true; } std::vector new_objs_array; - if (!AreObjectsAvailable(m_objs_array, false, pHints, new_objs_array)) { + if (!AreObjectsAvailable(m_objs_array, false, new_objs_array)) { m_objs_array = new_objs_array; return false; } @@ -1581,6 +1582,10 @@ CFX_RetainPtr CPDF_DataAvail::GetFileRead() const { return m_pFileRead; } +CFX_RetainPtr CPDF_DataAvail::GetValidator() const { + return m_pFileRead; +} + int CPDF_DataAvail::GetPageCount() const { if (m_pLinearized) return m_pLinearized->GetPageCount(); @@ -1623,6 +1628,8 @@ CPDF_DataAvail::DocFormStatus CPDF_DataAvail::IsFormAvail( DownloadHints* pHints) { if (!m_pDocument) return FormAvailable; + + const HintsScope hints_scope(GetValidator().Get(), pHints); if (m_pLinearized) { DocAvailStatus nDocStatus = CheckLinearizedData(pHints); if (nDocStatus == DataError) @@ -1645,7 +1652,7 @@ CPDF_DataAvail::DocFormStatus CPDF_DataAvail::IsFormAvail( } std::vector new_objs_array; - if (!AreObjectsAvailable(m_objs_array, false, pHints, new_objs_array)) { + if (!AreObjectsAvailable(m_objs_array, false, new_objs_array)) { m_objs_array = new_objs_array; return FormNotAvailable; } @@ -1664,7 +1671,7 @@ bool CPDF_DataAvail::ValidatePage(uint32_t dwPage) { std::vector obj_array; obj_array.push_back(pPageDict); std::vector dummy; - return AreObjectsAvailable(obj_array, true, nullptr, dummy); + return AreObjectsAvailable(obj_array, true, dummy); } bool CPDF_DataAvail::ValidateForm() { @@ -1677,7 +1684,7 @@ bool CPDF_DataAvail::ValidateForm() { std::vector obj_array; obj_array.push_back(pAcroForm); std::vector dummy; - return AreObjectsAvailable(obj_array, true, nullptr, dummy); + return AreObjectsAvailable(obj_array, true, dummy); } CPDF_DataAvail::PageNode::PageNode() : m_type(PDF_PAGENODE_UNKNOWN) {} diff --git a/core/fpdfapi/parser/cpdf_data_avail.h b/core/fpdfapi/parser/cpdf_data_avail.h index f19b36d375..b857c659d9 100644 --- a/core/fpdfapi/parser/cpdf_data_avail.h +++ b/core/fpdfapi/parser/cpdf_data_avail.h @@ -111,6 +111,7 @@ class CPDF_DataAvail final { CFX_RetainPtr GetFileRead() const; int GetPageCount() const; CPDF_Dictionary* GetPage(int index); + CFX_RetainPtr GetValidator() const; protected: class PageNode { @@ -128,7 +129,6 @@ class CPDF_DataAvail final { uint32_t GetObjectSize(uint32_t objnum, FX_FILESIZE& offset); bool AreObjectsAvailable(std::vector& obj_array, bool bParsePage, - DownloadHints* pHints, std::vector& ret_array); bool CheckDocStatus(DownloadHints* pHints); bool CheckHeader(DownloadHints* pHints); @@ -142,10 +142,10 @@ class CPDF_DataAvail final { bool CheckInfo(DownloadHints* pHints); bool CheckPages(DownloadHints* pHints); bool CheckPage(DownloadHints* pHints); - bool CheckResources(DownloadHints* pHints); + bool CheckResources(); bool CheckAnnots(DownloadHints* pHints); bool CheckAcroForm(DownloadHints* pHints); - bool CheckAcroFormSubObject(DownloadHints* pHints); + bool CheckAcroFormSubObject(); bool CheckTrailerAppend(DownloadHints* pHints); bool CheckPageStatus(DownloadHints* pHints); bool CheckAllCrossRefStream(DownloadHints* pHints); @@ -168,10 +168,9 @@ class CPDF_DataAvail final { bool LoadAllXref(DownloadHints* pHints); bool LoadAllFile(DownloadHints* pHints); DocAvailStatus CheckLinearizedData(DownloadHints* pHints); - bool CheckPageAnnots(uint32_t dwPage, DownloadHints* pHints); + bool CheckPageAnnots(uint32_t dwPage); - DocAvailStatus CheckLinearizedFirstPage(uint32_t dwPage, - DownloadHints* pHints); + DocAvailStatus CheckLinearizedFirstPage(uint32_t dwPage); bool CheckPage(uint32_t dwPage, DownloadHints* pHints); bool LoadDocPages(DownloadHints* pHints); bool LoadDocPage(uint32_t dwPage, DownloadHints* pHints); -- cgit v1.2.3