Add RemoveTextObjectWithTwoPagesSharingContentArrayAndResources test

This is another FPDFPage_RemoveObject() test case, similar to
RemoveTextObjectWithTwoPagesSharingContentStreamAndResources, where
2 pages share the same page /Content. Except this time the /Content
points to an array of stream objects instead of a stream directly. The
test PDF added here is similar to hello_world_2_pages.pdf and
hello_world_split_streams.pdf.

Bug: pdfium:2012
Change-Id: I396d1cf0a9d3da88337c459aa7ef6f6ec189bb1d
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/105491
Reviewed-by: Nigi <nigi@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/fpdfsdk/fpdf_edit_embeddertest.cpp b/fpdfsdk/fpdf_edit_embeddertest.cpp
index a55873b..c91f092 100644
--- a/fpdfsdk/fpdf_edit_embeddertest.cpp
+++ b/fpdfsdk/fpdf_edit_embeddertest.cpp
@@ -988,6 +988,66 @@
   UnloadPage(page2);
 }
 
+TEST_F(FPDFEditEmbedderTest,
+       RemoveTextObjectWithTwoPagesSharingContentArrayAndResources) {
+  // Load document with some text.
+  ASSERT_TRUE(OpenDocument("hello_world_2_pages_split_streams.pdf"));
+  FPDF_PAGE page1 = LoadPage(0);
+  ASSERT_TRUE(page1);
+  FPDF_PAGE page2 = LoadPage(1);
+  ASSERT_TRUE(page2);
+
+  // Show what the original file looks like.
+  {
+    ScopedFPDFBitmap page1_bitmap = RenderPage(page1);
+    CompareBitmap(page1_bitmap.get(), 200, 200, HelloWorldChecksum());
+    ScopedFPDFBitmap page2_bitmap = RenderPage(page2);
+    CompareBitmap(page2_bitmap.get(), 200, 200, HelloWorldChecksum());
+  }
+
+  // Get the "Hello, world!" text object from page 1 and remove it.
+  ASSERT_EQ(2, FPDFPage_CountObjects(page1));
+  {
+    ScopedFPDFPageObject page_object(FPDFPage_GetObject(page1, 0));
+    ASSERT_TRUE(page_object);
+    ASSERT_EQ(FPDF_PAGEOBJ_TEXT, FPDFPageObj_GetType(page_object.get()));
+    EXPECT_TRUE(FPDFPage_RemoveObject(page1, page_object.get()));
+  }
+  ASSERT_EQ(1, FPDFPage_CountObjects(page1));
+
+  // Verify the "Hello, world!" text is gone from page 1.
+  {
+    ScopedFPDFBitmap page1_bitmap = RenderPage(page1);
+    CompareBitmap(page1_bitmap.get(), 200, 200, FirstRemovedChecksum());
+    ScopedFPDFBitmap page2_bitmap = RenderPage(page2);
+    CompareBitmap(page2_bitmap.get(), 200, 200, HelloWorldChecksum());
+  }
+
+  // Verify the rendering again after calling FPDFPage_GenerateContent().
+  ASSERT_TRUE(FPDFPage_GenerateContent(page1));
+  {
+    ScopedFPDFBitmap page1_bitmap = RenderPage(page1);
+    CompareBitmap(page1_bitmap.get(), 200, 200, FirstRemovedChecksum());
+    ScopedFPDFBitmap page2_bitmap = RenderPage(page2);
+    CompareBitmap(page2_bitmap.get(), 200, 200, HelloWorldChecksum());
+  }
+
+  // Save the document and verify it after reloading.
+  ASSERT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
+  ASSERT_TRUE(OpenSavedDocument());
+  FPDF_PAGE saved_page1 = LoadSavedPage(0);
+  VerifySavedRendering(saved_page1, 200, 200, FirstRemovedChecksum());
+  CloseSavedPage(saved_page1);
+  FPDF_PAGE saved_page2 = LoadSavedPage(1);
+  // TODO(crbug.com/pdfium/2012): Should be `HelloWorldChecksum()`.
+  VerifySavedRendering(saved_page2, 200, 200, FirstRemovedChecksum());
+  CloseSavedPage(saved_page2);
+  CloseSavedDocument();
+
+  UnloadPage(page1);
+  UnloadPage(page2);
+}
+
 void CheckMarkCounts(FPDF_PAGE page,
                      int start_from,
                      int expected_object_count,
diff --git a/testing/resources/hello_world_2_pages_split_streams.in b/testing/resources/hello_world_2_pages_split_streams.in
new file mode 100644
index 0000000..ef68f5c
--- /dev/null
+++ b/testing/resources/hello_world_2_pages_split_streams.in
@@ -0,0 +1,75 @@
+{{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]
+  /MediaBox [0 0 200 200]
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /Resources <<
+    /Font <<
+      /F1 5 0 R
+      /F2 6 0 R
+    >>
+  >>
+  /Contents 7 0 R
+>>
+endobj
+{{object 4 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /Resources <<
+    /Font <<
+      /F1 5 0 R
+      /F2 6 0 R
+    >>
+  >>
+  /Contents 7 0 R
+>>
+endobj
+{{object 5 0}} <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Times-Roman
+>>
+endobj
+{{object 6 0}} <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Helvetica
+>>
+endobj
+{{object 7 0}} [8 0 R 9 0 R]
+{{object 8 0}} <<
+  {{streamlen}}
+>>
+stream
+BT
+20 50 Td
+/F1 12 Tf
+(Hello, world!) Tj
+endstream
+endobj
+{{object 9 0}} <<
+  {{streamlen}}
+>>
+stream
+BT
+20 100 Td
+/F2 16 Tf
+(Goodbye, world!) Tj
+ET
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/hello_world_2_pages_split_streams.pdf b/testing/resources/hello_world_2_pages_split_streams.pdf
new file mode 100644
index 0000000..3ac829f
--- /dev/null
+++ b/testing/resources/hello_world_2_pages_split_streams.pdf
@@ -0,0 +1,91 @@
+%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]
+  /MediaBox [0 0 200 200]
+>>
+endobj
+3 0 obj <<
+  /Type /Page
+  /Parent 2 0 R
+  /Resources <<
+    /Font <<
+      /F1 5 0 R
+      /F2 6 0 R
+    >>
+  >>
+  /Contents 7 0 R
+>>
+endobj
+4 0 obj <<
+  /Type /Page
+  /Parent 2 0 R
+  /Resources <<
+    /Font <<
+      /F1 5 0 R
+      /F2 6 0 R
+    >>
+  >>
+  /Contents 7 0 R
+>>
+endobj
+5 0 obj <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Times-Roman
+>>
+endobj
+6 0 obj <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Helvetica
+>>
+endobj
+7 0 obj [8 0 R 9 0 R]
+8 0 obj <<
+  /Length 41
+>>
+stream
+BT
+20 50 Td
+/F1 12 Tf
+(Hello, world!) Tj
+endstream
+endobj
+9 0 obj <<
+  /Length 47
+>>
+stream
+BT
+20 100 Td
+/F2 16 Tf
+(Goodbye, world!) Tj
+ET
+endstream
+endobj
+xref
+0 10
+0000000000 65535 f 
+0000000015 00000 n 
+0000000068 00000 n 
+0000000163 00000 n 
+0000000305 00000 n 
+0000000447 00000 n 
+0000000525 00000 n 
+0000000601 00000 n 
+0000000623 00000 n 
+0000000715 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 10
+>>
+startxref
+813
+%%EOF