M124: Fix one more edited PDF regression
Restore some of the CPDF_Parser::LoadAllSecondaryCrossRefStreams() logic
that https://pdfium-review.googlesource.com/118571 deleted. Since the
CPDF_Parser code changed quite a bit, incorporate that logic into
FindAllCrossReferenceTablesAndStream().
With this fix in place, unsuppress the bug_2152.pdf pixel test.
Bug: 335309995, pdfium:2152
Change-Id: Ie4cf79cddca6e0f1f4a331ceea5676f62c7d4a6e
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/118756
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Thomas Sepez <tsepez@google.com>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
(cherry picked from commit 9783ba4860001b8891bb68f9fab4ee746d027ea3)
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/119056
diff --git a/core/fpdfapi/parser/cpdf_parser.cpp b/core/fpdfapi/parser/cpdf_parser.cpp
index c040bdd..7472907 100644
--- a/core/fpdfapi/parser/cpdf_parser.cpp
+++ b/core/fpdfapi/parser/cpdf_parser.cpp
@@ -676,25 +676,40 @@
}
seen_xref_offset.insert(xref_offset);
- xref_list.insert(xref_list.begin(), xref_offset);
- // SLOW ...
- LoadCrossRefTable(xref_offset, /*skip=*/true);
+ // Use a copy of `xref_offset`, as LoadCrossRefStream() may change it.
+ FX_FILESIZE xref_offset_copy = xref_offset;
+ if (LoadCrossRefStream(&xref_offset_copy, /*is_main_xref=*/false)) {
+ // Since `xref_offset` points to a cross reference stream, mark it
+ // accordingly.
+ xref_list.insert(xref_list.begin(), 0);
+ xref_stream_list.insert(xref_stream_list.begin(), xref_offset);
+ xref_offset = xref_offset_copy;
- RetainPtr<CPDF_Dictionary> trailer_dict = LoadTrailer();
- if (!trailer_dict) {
- return false;
+ // On success, LoadCrossRefStream() called CPDF_CrossRefTable::MergeUp()
+ // when `is_main_xref` is false. Thus no explicit call here.
+ } else {
+ // SLOW ...
+ LoadCrossRefTable(xref_offset, /*skip=*/true);
+
+ RetainPtr<CPDF_Dictionary> trailer_dict = LoadTrailer();
+ if (!trailer_dict) {
+ return false;
+ }
+
+ // The trailer for cross reference tables may point to a cross reference
+ // stream as well.
+ xref_list.insert(xref_list.begin(), xref_offset);
+ xref_stream_list.insert(xref_stream_list.begin(),
+ trailer_dict->GetIntegerFor("XRefStm"));
+ xref_offset = trailer_dict->GetDirectIntegerFor("Prev");
+
+ // SLOW ...
+ m_CrossRefTable = CPDF_CrossRefTable::MergeUp(
+ std::make_unique<CPDF_CrossRefTable>(std::move(trailer_dict),
+ kNoTrailerObjectNumber),
+ std::move(m_CrossRefTable));
}
-
- xref_offset = trailer_dict->GetDirectIntegerFor("Prev");
- xref_stream_list.insert(xref_stream_list.begin(),
- trailer_dict->GetIntegerFor("XRefStm"));
-
- // SLOW ...
- m_CrossRefTable = CPDF_CrossRefTable::MergeUp(
- std::make_unique<CPDF_CrossRefTable>(std::move(trailer_dict),
- kNoTrailerObjectNumber),
- std::move(m_CrossRefTable));
}
return true;
}