summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/fpdfapi/parser/cpdf_data_avail.cpp3
-rw-r--r--core/fpdfapi/parser/cpdf_data_avail.h1
-rw-r--r--fpdfsdk/fpdfview_embeddertest.cpp7
3 files changed, 10 insertions, 1 deletions
diff --git a/core/fpdfapi/parser/cpdf_data_avail.cpp b/core/fpdfapi/parser/cpdf_data_avail.cpp
index 76190fa9a9..b7ea238507 100644
--- a/core/fpdfapi/parser/cpdf_data_avail.cpp
+++ b/core/fpdfapi/parser/cpdf_data_avail.cpp
@@ -943,8 +943,9 @@ bool CPDF_DataAvail::CheckTrailer() {
return true;
}
+ // Prevent infinite-looping between Prev entries.
uint32_t xrefpos = GetDirectInteger(pTrailerDict, "Prev");
- if (!xrefpos) {
+ if (!xrefpos || !m_SeenPrevPositions.insert(xrefpos).second) {
m_dwPrevXRefOffset = 0;
m_docStatus = PDF_DATAAVAIL_LOADALLCROSSREF;
return true;
diff --git a/core/fpdfapi/parser/cpdf_data_avail.h b/core/fpdfapi/parser/cpdf_data_avail.h
index 1fcdaf034e..e2a4a20aa1 100644
--- a/core/fpdfapi/parser/cpdf_data_avail.h
+++ b/core/fpdfapi/parser/cpdf_data_avail.h
@@ -230,6 +230,7 @@ class CPDF_DataAvail final {
PageNode m_PageNode;
std::set<uint32_t> m_pageMapCheckState;
std::set<uint32_t> m_pagesLoadState;
+ std::set<uint32_t> m_SeenPrevPositions;
std::unique_ptr<CPDF_HintTables> m_pHintTables;
bool m_bSupportHintTable;
};
diff --git a/fpdfsdk/fpdfview_embeddertest.cpp b/fpdfsdk/fpdfview_embeddertest.cpp
index 0e478b448f..8576104c2e 100644
--- a/fpdfsdk/fpdfview_embeddertest.cpp
+++ b/fpdfsdk/fpdfview_embeddertest.cpp
@@ -318,6 +318,13 @@ TEST_F(FPDFViewEmbeddertest, Hang_298) {
// reference loop. Cross references will be rebuilt successfully.
TEST_F(FPDFViewEmbeddertest, CrossRefV4Loop) {
EXPECT_TRUE(OpenDocument("bug_xrefv4_loop.pdf"));
+
+ // Make sure calling FPDFAvail_IsDocAvail() on this file does not infinite
+ // loop either. See bug 875.
+ int ret = PDF_DATA_NOTAVAIL;
+ while (ret == PDF_DATA_NOTAVAIL)
+ ret = FPDFAvail_IsDocAvail(avail_, &hints_);
+ EXPECT_EQ(PDF_DATA_AVAIL, ret);
}
// The test should pass when circular references to ParseIndirectObject will not