Avoid generating PDFs with unreferenced objects
In CPDF_Creator::WriteOldObjs(), check to see if objects have references
to them before writing them out.
Bug: chromium:1428724,pdfium:1409
Change-Id: I4c9d447ab745732909c4f7b5c6061886428a92dd
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/105612
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfapi/edit/cpdf_creator.cpp b/core/fpdfapi/edit/cpdf_creator.cpp
index 3c9675e..9a2b88b 100644
--- a/core/fpdfapi/edit/cpdf_creator.cpp
+++ b/core/fpdfapi/edit/cpdf_creator.cpp
@@ -9,6 +9,7 @@
#include <stdint.h>
#include <algorithm>
+#include <set>
#include <utility>
#include "core/fpdfapi/parser/cpdf_array.h"
@@ -22,6 +23,7 @@
#include "core/fpdfapi/parser/cpdf_security_handler.h"
#include "core/fpdfapi/parser/cpdf_string.h"
#include "core/fpdfapi/parser/fpdf_parser_utility.h"
+#include "core/fpdfapi/parser/object_tree_traversal_util.h"
#include "core/fxcrt/data_vector.h"
#include "core/fxcrt/fx_extension.h"
#include "core/fxcrt/fx_random.h"
@@ -163,13 +165,30 @@
}
bool CPDF_Creator::WriteOldObjs() {
- uint32_t nLastObjNum = m_pParser->GetLastObjNum();
- if (!m_pParser->IsValidObjectNumber(nLastObjNum))
+ const uint32_t nLastObjNum = m_pParser->GetLastObjNum();
+ if (!m_pParser->IsValidObjectNumber(nLastObjNum)) {
return true;
+ }
+ if (m_CurObjNum > nLastObjNum) {
+ return true;
+ }
+ const std::set<uint32_t> objects_with_refs =
+ GetObjectsWithReferences(m_pDocument);
+ uint32_t last_object_number_written = 0;
for (uint32_t objnum = m_CurObjNum; objnum <= nLastObjNum; ++objnum) {
- if (!WriteOldIndirectObject(objnum))
+ if (!pdfium::Contains(objects_with_refs, objnum)) {
+ continue;
+ }
+ if (!WriteOldIndirectObject(objnum)) {
return false;
+ }
+ last_object_number_written = objnum;
+ }
+ // If there are no new objects to write, then adjust `m_dwLastObjNum` if
+ // needed to reflect the actual last object number.
+ if (m_NewObjNumArray.empty()) {
+ m_dwLastObjNum = last_object_number_written;
}
return true;
}
diff --git a/fpdfsdk/fpdf_save_embeddertest.cpp b/fpdfsdk/fpdf_save_embeddertest.cpp
index 1289a1f..c18566a 100644
--- a/fpdfsdk/fpdf_save_embeddertest.cpp
+++ b/fpdfsdk/fpdf_save_embeddertest.cpp
@@ -113,12 +113,12 @@
EXPECT_THAT(GetString(), StartsWith("%PDF-1.6\r\n"));
EXPECT_THAT(GetString(), HasSubstr("/Root "));
EXPECT_THAT(GetString(), HasSubstr("/Info "));
- EXPECT_THAT(GetString(), HasSubstr("/Size 38"));
+ EXPECT_THAT(GetString(), HasSubstr("/Size 37"));
EXPECT_THAT(GetString(), HasSubstr("35 0 obj"));
EXPECT_THAT(GetString(), HasSubstr("36 0 obj"));
- EXPECT_THAT(GetString(), HasSubstr("37 0 obj"));
+ EXPECT_THAT(GetString(), Not(HasSubstr("37 0 obj")));
EXPECT_THAT(GetString(), Not(HasSubstr("38 0 obj")));
- EXPECT_EQ(8219u, GetString().size());
+ EXPECT_EQ(7908u, GetString().size());
// Make sure new document renders the same as the old one.
ASSERT_TRUE(OpenSavedDocument());