diff options
author | art-snake <art-snake@yandex-team.ru> | 2016-11-09 15:20:59 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-11-09 15:20:59 -0800 |
commit | c0a47773d6dadeb8a39a6ced4ebbb1795e2e411f (patch) | |
tree | 79efdd2dd00f19294a44a3b4fe5e851221ea5dc0 | |
parent | 335cf093231c984a23cb9ea113148ea1f19621ba (diff) | |
download | pdfium-c0a47773d6dadeb8a39a6ced4ebbb1795e2e411f.tar.xz |
Fix receiving page, if it have not obj num.
In some PDF's the page may not have the obj num.
For example: testing\corpus\fx\other\jetman_std.pdf in pdfium repository.
And CPDF_Document::GetPage failed on second call for this page.
Restart the traversing of pages, to fix this
Also added test.
Review-Url: https://codereview.chromium.org/2491583002
-rw-r--r-- | core/fpdfapi/parser/cpdf_document.cpp | 11 | ||||
-rw-r--r-- | core/fpdfapi/parser/cpdf_document_unittest.cpp | 33 |
2 files changed, 43 insertions, 1 deletions
diff --git a/core/fpdfapi/parser/cpdf_document.cpp b/core/fpdfapi/parser/cpdf_document.cpp index 1c73ce1015..6788394118 100644 --- a/core/fpdfapi/parser/cpdf_document.cpp +++ b/core/fpdfapi/parser/cpdf_document.cpp @@ -492,9 +492,18 @@ CPDF_Dictionary* CPDF_Document::GetPage(int iPage) { if (!pPages) return nullptr; + if (iPage - m_iNextPageToTraverse + 1 <= 0) { + // This can happen when the page does not have an object number. On repeated + // calls to this function for the same page index, this condition causes + // TraversePDFPages() to incorrectly return nullptr. + // Example "testing/corpus/fx/other/jetman_std.pdf" + // We should restart traversing in this case. + // TODO(art-snake): optimize this. + ResetTraversal(); + } + int nPagesToGo = iPage - m_iNextPageToTraverse + 1; if (m_pTreeTraversal.empty()) m_pTreeTraversal.push_back(std::make_pair(pPages, 0)); - int nPagesToGo = iPage - m_iNextPageToTraverse + 1; CPDF_Dictionary* pPage = TraversePDFPages(iPage, &nPagesToGo, 0); m_iNextPageToTraverse = iPage + 1; return pPage; diff --git a/core/fpdfapi/parser/cpdf_document_unittest.cpp b/core/fpdfapi/parser/cpdf_document_unittest.cpp index 7b5ab43b5c..f27e7403f6 100644 --- a/core/fpdfapi/parser/cpdf_document_unittest.cpp +++ b/core/fpdfapi/parser/cpdf_document_unittest.cpp @@ -76,6 +76,27 @@ class CPDF_TestDocumentForPages : public CPDF_Document { std::unique_ptr<CPDF_Dictionary> m_pOwnedRootDict; }; +class CPDF_TestDocumentWithPageWithoutPageNum : public CPDF_Document { + public: + CPDF_TestDocumentWithPageWithoutPageNum() : CPDF_Document(nullptr) { + // Set up test + CPDF_Array* allPages = new CPDF_Array(); + allPages->AddReference(this, AddIndirectObject(CreateNumberedPage(0))); + allPages->AddReference(this, AddIndirectObject(CreateNumberedPage(1))); + // Page without pageNum. + allPages->Add(CreateNumberedPage(2)); + CPDF_Dictionary* pagesDict = CreatePageTreeNode(allPages, this, 3); + + m_pOwnedRootDict.reset(new CPDF_Dictionary()); + m_pOwnedRootDict->SetReferenceFor("Pages", this, pagesDict->GetObjNum()); + m_pRootDict = m_pOwnedRootDict.get(); + m_PageList.SetSize(3); + } + + private: + std::unique_ptr<CPDF_Dictionary> m_pOwnedRootDict; +}; + class TestLinearized : public CPDF_LinearizedHeader { public: explicit TestLinearized(CPDF_Dictionary* dict) @@ -105,6 +126,18 @@ TEST_F(cpdf_document_test, GetPages) { EXPECT_FALSE(page); } +TEST_F(cpdf_document_test, GetPageWithoutObjNumTwice) { + std::unique_ptr<CPDF_TestDocumentWithPageWithoutPageNum> document = + pdfium::MakeUnique<CPDF_TestDocumentWithPageWithoutPageNum>(); + const CPDF_Dictionary* page = document->GetPage(2); + ASSERT_TRUE(page); + // This is page without obj num. + ASSERT_EQ(0ul, page->GetObjNum()); + const CPDF_Dictionary* second_call_page = document->GetPage(2); + EXPECT_TRUE(second_call_page); + EXPECT_EQ(page, second_call_page); +} + TEST_F(cpdf_document_test, GetPagesReverseOrder) { std::unique_ptr<CPDF_TestDocumentForPages> document = pdfium::MakeUnique<CPDF_TestDocumentForPages>(); |