Add FPDFPPOEmbedderTest.ImportIntoDocWithWrongPageType test case

This CL adds testing/resources/bad_page_type.pdf, which deliberately has
the wrong /Type for one of its page objects. This violates the spec, but
most PDF viewers will still correctly render this PDF without
complaining.

Add an embedder test to show that importing into bad_page_type.pdf with
FPDF_ImportPagesByIndex() does not work correctly.

Bug: pdfium:2098
Change-Id: Ibf8be444b2d63ee1c286544c3427ac3f28c02636
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/113890
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Nigi <nigi@chromium.org>
diff --git a/fpdfsdk/fpdf_ppo_embeddertest.cpp b/fpdfsdk/fpdf_ppo_embeddertest.cpp
index 67e0cc2..3b93eb7 100644
--- a/fpdfsdk/fpdf_ppo_embeddertest.cpp
+++ b/fpdfsdk/fpdf_ppo_embeddertest.cpp
@@ -651,3 +651,64 @@
   EXPECT_TRUE(FPDF_ImportPages(document(), src_doc.get(), "1", 0));
   EXPECT_EQ(3, FPDF_GetPageCount(document()));
 }
+
+TEST_F(FPDFPPOEmbedderTest, ImportIntoDocWithWrongPageType) {
+  ASSERT_TRUE(OpenDocument("bad_page_type.pdf"));
+  EXPECT_EQ(2, FPDF_GetPageCount(document()));
+
+  std::string file_path = PathService::GetTestFilePath("rectangles.pdf");
+  ASSERT_FALSE(file_path.empty());
+  std::vector<uint8_t> file_contents = GetFileContents(file_path.c_str());
+  ASSERT_FALSE(file_contents.empty());
+
+  ScopedFPDFDocument src_doc(FPDF_LoadMemDocument(
+      file_contents.data(), file_contents.size(), nullptr));
+  ASSERT_TRUE(src_doc);
+  EXPECT_EQ(1, FPDF_GetPageCount(src_doc.get()));
+
+  FPDFPage_Delete(document(), 0);
+  EXPECT_EQ(1, FPDF_GetPageCount(document()));
+
+  static constexpr int kPageIndices[] = {0};
+  ASSERT_TRUE(FPDF_ImportPagesByIndex(document(), src_doc.get(), kPageIndices,
+                                      std::size(kPageIndices), 0));
+  EXPECT_EQ(2, FPDF_GetPageCount(document()));
+  const char* const new_page_1_checksum = []() {
+    if (CFX_DefaultRenderDevice::UseSkiaRenderer()) {
+      return "b4e411a6b5ffa59a50efede2efece597";
+    }
+    return "0a90de37f52127619c3dfb642b5fa2fe";
+  }();
+  {
+    FPDF_PAGE page = LoadPage(0);
+    ASSERT_TRUE(page);
+    ScopedFPDFBitmap bitmap = RenderPage(page);
+    CompareBitmap(bitmap.get(), 200, 300, new_page_1_checksum);
+    UnloadPage(page);
+  }
+  {
+    FPDF_PAGE page = LoadPage(1);
+    // TODO(crbug.com/pdfium/2098): This page should be valid.
+    EXPECT_FALSE(page);
+  }
+
+  EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
+
+  ASSERT_TRUE(OpenSavedDocument());
+  // TODO(crbug.com/pdfium/2098): The saved doc should have 2 pages.
+  EXPECT_EQ(1, FPDF_GetPageCount(saved_document()));
+  {
+    FPDF_PAGE page = LoadSavedPage(0);
+    ASSERT_TRUE(page);
+    ScopedFPDFBitmap bitmap = RenderPage(page);
+    // TODO(crbug.com/pdfium/2098): This bitmap's checksum should be
+    // `new_page_1_checksum`.
+    CompareBitmap(bitmap.get(), 200, 100, "39336760026e7f3d26135e3b765125c3");
+    CloseSavedPage(page);
+  }
+  {
+    FPDF_PAGE page = LoadSavedPage(1);
+    // TODO(crbug.com/pdfium/2098): This page should be valid.
+    EXPECT_FALSE(page);
+  }
+}
diff --git a/testing/resources/bad_page_type.in b/testing/resources/bad_page_type.in
new file mode 100644
index 0000000..0c35be1
--- /dev/null
+++ b/testing/resources/bad_page_type.in
@@ -0,0 +1,50 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /Count 2
+  /Kids [3 0 R 4 0 R]
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /MediaBox [0 0 100 200]
+  /Contents 5 0 R
+>>
+endobj
+{{object 4 0}} <<
+  /Type /Template % Note that this is deliberately wrong.
+  /Parent 2 0 R
+  /MediaBox [0 0 200 100]
+  /Contents 6 0 R
+>>
+endobj
+{{object 5 0}} <<
+  {{streamlen}}
+>>
+stream
+q
+0 0 1 rg
+50 60 10 10 re f
+Q
+endstream
+endobj
+{{object 6 0}} <<
+  {{streamlen}}
+>>
+stream
+q
+1 0 0 rg
+50 60 10 10 re f
+Q
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/bad_page_type.pdf b/testing/resources/bad_page_type.pdf
new file mode 100644
index 0000000..a6aae03
--- /dev/null
+++ b/testing/resources/bad_page_type.pdf
@@ -0,0 +1,63 @@
+%PDF-1.7
+% ò¤ô
+1 0 obj <<
+  /Type /Catalog
+  /Pages 2 0 R
+>>
+endobj
+2 0 obj <<
+  /Type /Pages
+  /Count 2
+  /Kids [3 0 R 4 0 R]
+>>
+endobj
+3 0 obj <<
+  /Type /Page
+  /Parent 2 0 R
+  /MediaBox [0 0 100 200]
+  /Contents 5 0 R
+>>
+endobj
+4 0 obj <<
+  /Type /Template % Note that this is deliberately wrong.
+  /Parent 2 0 R
+  /MediaBox [0 0 200 100]
+  /Contents 6 0 R
+>>
+endobj
+5 0 obj <<
+  /Length 30
+>>
+stream
+q
+0 0 1 rg
+50 60 10 10 re f
+Q
+endstream
+endobj
+6 0 obj <<
+  /Length 30
+>>
+stream
+q
+1 0 0 rg
+50 60 10 10 re f
+Q
+endstream
+endobj
+xref
+0 7
+0000000000 65535 f 
+0000000015 00000 n 
+0000000068 00000 n 
+0000000137 00000 n 
+0000000232 00000 n 
+0000000371 00000 n 
+0000000452 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 7
+>>
+startxref
+533
+%%EOF