diff options
author | Nicolas Pena <npm@chromium.org> | 2017-01-03 14:33:20 -0500 |
---|---|---|
committer | Chromium commit bot <commit-bot@chromium.org> | 2017-01-03 19:50:39 +0000 |
commit | 83c5eaca106f4afed6cceb1b3f336d0146cb10d7 (patch) | |
tree | 2973a1ea01ee822806b3a2f30225ec678a0f98d6 /core | |
parent | 05f541279ec01dfdc76ad6b8b142fa5f04cd544c (diff) | |
download | pdfium-83c5eaca106f4afed6cceb1b3f336d0146cb10d7.tar.xz |
Force stop of page tree traversal when max level reached
The previous implementation, FindPDFPage, was already doing this since
the recursive call was always with return. Currently, we were trying to
keep going even after reaching max level. The problem is that if the
page tree is not a tree, we might loop forever. This could also be
solved by keeping track of the dictionaries that have been visited, but
this solution takes much less space.
BUG=672172
Change-Id: Ia37aea58e92b6068de69f26736c612aa6a0ff4b3
Reviewed-on: https://pdfium-review.googlesource.com/2138
Commit-Queue: Nicolás Peña <npm@chromium.org>
Commit-Queue: dsinclair <dsinclair@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Reviewed-by: dsinclair <dsinclair@chromium.org>
Diffstat (limited to 'core')
-rw-r--r-- | core/fpdfapi/parser/cpdf_document.cpp | 10 | ||||
-rw-r--r-- | core/fpdfapi/parser/cpdf_document.h | 1 |
2 files changed, 8 insertions, 3 deletions
diff --git a/core/fpdfapi/parser/cpdf_document.cpp b/core/fpdfapi/parser/cpdf_document.cpp index 411091ced5..a728bf5795 100644 --- a/core/fpdfapi/parser/cpdf_document.cpp +++ b/core/fpdfapi/parser/cpdf_document.cpp @@ -343,6 +343,7 @@ CPDF_Document::CPDF_Document(std::unique_ptr<CPDF_Parser> pParser) m_pRootDict(nullptr), m_pInfoDict(nullptr), m_iNextPageToTraverse(0), + m_bReachedMaxPageLevel(false), m_bLinearized(false), m_iFirstPageNo(0), m_dwFirstPageObjNum(0), @@ -399,7 +400,7 @@ void CPDF_Document::LoadPages() { CPDF_Dictionary* CPDF_Document::TraversePDFPages(int iPage, int* nPagesToGo, size_t level) { - if (*nPagesToGo < 0) + if (*nPagesToGo < 0 || m_bReachedMaxPageLevel) return nullptr; CPDF_Dictionary* pPages = m_pTreeTraversal[level].first; CPDF_Array* pKidList = pPages->GetArrayFor("Kids"); @@ -412,6 +413,7 @@ CPDF_Dictionary* CPDF_Document::TraversePDFPages(int iPage, if (level >= FX_MAX_PAGE_LEVEL) { m_pTreeTraversal.pop_back(); + m_bReachedMaxPageLevel = true; return nullptr; } @@ -447,8 +449,9 @@ CPDF_Dictionary* CPDF_Document::TraversePDFPages(int iPage, // Check if child was completely processed, i.e. it popped itself out if (m_pTreeTraversal.size() == level + 1) m_pTreeTraversal[level].second++; - // If child did not finish or if no pages to go, we are done - if (m_pTreeTraversal.size() != level + 1 || *nPagesToGo == 0) { + // If child did not finish, no pages to go, or max level reached, end + if (m_pTreeTraversal.size() != level + 1 || *nPagesToGo == 0 || + m_bReachedMaxPageLevel) { page = pageKid; break; } @@ -461,6 +464,7 @@ CPDF_Dictionary* CPDF_Document::TraversePDFPages(int iPage, void CPDF_Document::ResetTraversal() { m_iNextPageToTraverse = 0; + m_bReachedMaxPageLevel = false; m_pTreeTraversal.clear(); } diff --git a/core/fpdfapi/parser/cpdf_document.h b/core/fpdfapi/parser/cpdf_document.h index 59154d3ab3..0da6577360 100644 --- a/core/fpdfapi/parser/cpdf_document.h +++ b/core/fpdfapi/parser/cpdf_document.h @@ -138,6 +138,7 @@ class CPDF_Document : public CPDF_IndirectObjectHolder { std::vector<std::pair<CPDF_Dictionary*, size_t>> m_pTreeTraversal; // Index of the next page that will be traversed from the page tree. int m_iNextPageToTraverse; + bool m_bReachedMaxPageLevel; bool m_bLinearized; int m_iFirstPageNo; uint32_t m_dwFirstPageObjNum; |