From cbed949bee845d6ab3e38b3d9b7e832620b64b51 Mon Sep 17 00:00:00 2001 From: Henrique Nakashima Date: Tue, 10 Jul 2018 21:54:26 +0000 Subject: Add test for reading marked content with an indirect dict. Bug: pdfium:1118 Change-Id: I2e9adaae64cba5b3915c19f3c99743cddbe58736 Reviewed-on: https://pdfium-review.googlesource.com/37371 Reviewed-by: Lei Zhang Commit-Queue: Henrique Nakashima --- fpdfsdk/fpdf_edit_embeddertest.cpp | 132 ++++++++++++----- testing/resources/text_in_page_marked_indirect.in | 144 ++++++++++++++++++ testing/resources/text_in_page_marked_indirect.pdf | 161 +++++++++++++++++++++ 3 files changed, 398 insertions(+), 39 deletions(-) create mode 100644 testing/resources/text_in_page_marked_indirect.in create mode 100644 testing/resources/text_in_page_marked_indirect.pdf diff --git a/fpdfsdk/fpdf_edit_embeddertest.cpp b/fpdfsdk/fpdf_edit_embeddertest.cpp index a9eca92a4e..be872ee186 100644 --- a/fpdfsdk/fpdf_edit_embeddertest.cpp +++ b/fpdfsdk/fpdf_edit_embeddertest.cpp @@ -519,34 +519,20 @@ TEST_F(FPDFEditEmbeddertest, RemovePageObject) { FPDFPageObj_Destroy(page_object); } -TEST_F(FPDFEditEmbeddertest, RemoveMarkedObjectsPrime) { - // Load document with some text. - EXPECT_TRUE(OpenDocument("text_in_page_marked.pdf")); - FPDF_PAGE page = LoadPage(0); - ASSERT_TRUE(page); - - // Show what the original file looks like. - { -#if _FX_PLATFORM_ == _FX_PLATFORM_APPLE_ - const char kOriginalMD5[] = "5a5eb63cb21cc15084fea1f14284b8df"; -#elif _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_ - const char kOriginalMD5[] = "587c507a40f613f9c530b2ce2d58d655"; -#else - const char kOriginalMD5[] = "2edc6e70d54889aa0c0b7bdf3e168f86"; -#endif - ScopedFPDFBitmap page_bitmap = RenderPageWithFlags(page, nullptr, 0); - CompareBitmap(page_bitmap.get(), 200, 200, kOriginalMD5); - } - - // Iterate over all objects, counting the number of times each content mark - // name appears. +void CheckMarkCounts(FPDF_PAGE page, + int start_from, + int expected_object_count, + size_t expected_prime_count, + size_t expected_square_count, + size_t expected_greater_than_ten_count, + size_t expected_bounds_count) { int object_count = FPDFPage_CountObjects(page); - ASSERT_EQ(19, object_count); + ASSERT_EQ(expected_object_count, object_count); - unsigned long prime_count = 0; - unsigned long square_count = 0; - unsigned long greater_than_ten_count = 0; - std::vector primes; + size_t prime_count = 0; + size_t square_count = 0; + size_t greater_than_ten_count = 0; + size_t bounds_count = 0; for (int i = 0; i < object_count; ++i) { FPDF_PAGEOBJECT page_object = FPDFPage_GetObject(page, i); @@ -560,42 +546,55 @@ TEST_F(FPDFEditEmbeddertest, RemoveMarkedObjectsPrime) { GetPlatformWString(reinterpret_cast(buffer)); if (name == L"Prime") { prime_count++; - EXPECT_EQ(0, FPDFPageObjMark_CountParams(mark)); - primes.push_back(page_object); } else if (name == L"Square") { square_count++; + int expected_square = start_from + i; EXPECT_EQ(1, FPDFPageObjMark_CountParams(mark)); - ASSERT_GT(FPDFPageObjMark_GetParamKey(mark, 0, buffer, 256), 0u); + + unsigned long get_param_key_return = + FPDFPageObjMark_GetParamKey(mark, 0, buffer, 256); + ASSERT_GT(get_param_key_return, 0u); + EXPECT_EQ((6u + 1u) * 2u, get_param_key_return); std::wstring key = GetPlatformWString(reinterpret_cast(buffer)); EXPECT_EQ(L"Factor", key); + EXPECT_EQ(FPDF_OBJECT_NUMBER, FPDFPageObjMark_GetParamValueType(mark, 0)); int square_root = FPDFPageObjMark_GetParamIntValue(mark, 0); - EXPECT_EQ(i + 1, square_root * square_root); + EXPECT_EQ(expected_square, square_root * square_root); EXPECT_EQ(FPDF_OBJECT_NUMBER, FPDFPageObjMark_GetParamValueTypeByKey(mark, "Factor")); EXPECT_TRUE(FPDFPageObjMark_GetParamIntValueByKey(mark, "Factor", &square_root)); - EXPECT_EQ(i + 1, square_root * square_root); + EXPECT_EQ(expected_square, square_root * square_root); } else if (name == L"GreaterThanTen") { greater_than_ten_count++; - EXPECT_EQ(0, FPDFPageObjMark_CountParams(mark)); } else if (name == L"Bounds") { + bounds_count++; EXPECT_EQ(1, FPDFPageObjMark_CountParams(mark)); - ASSERT_GT(FPDFPageObjMark_GetParamKey(mark, 0, buffer, 256), 0u); + + unsigned long get_param_key_return = + FPDFPageObjMark_GetParamKey(mark, 0, buffer, 256); + ASSERT_GT(get_param_key_return, 0u); + EXPECT_EQ((8u + 1u) * 2u, get_param_key_return); std::wstring key = GetPlatformWString(reinterpret_cast(buffer)); EXPECT_EQ(L"Position", key); + EXPECT_EQ(FPDF_OBJECT_STRING, FPDFPageObjMark_GetParamValueType(mark, 0)); - ASSERT_GT(FPDFPageObjMark_GetParamStringValue(mark, 0, buffer, 256), - 0u); + unsigned long get_param_value_return = + FPDFPageObjMark_GetParamStringValue(mark, 0, buffer, 256); + ASSERT_GT(get_param_value_return, 0u); + EXPECT_EQ((4u + 1u) * 2u, get_param_value_return); std::wstring value = GetPlatformWString(reinterpret_cast(buffer)); EXPECT_EQ(L"Last", value); - EXPECT_EQ(18, i); + + // Should be the last object. + EXPECT_EQ(object_count - 1, i); EXPECT_EQ(FPDF_OBJECT_STRING, FPDFPageObjMark_GetParamValueTypeByKey(mark, "Position")); @@ -603,6 +602,7 @@ TEST_F(FPDFEditEmbeddertest, RemoveMarkedObjectsPrime) { EXPECT_TRUE(FPDFPageObjMark_GetParamStringValueByKey( mark, "Position", buffer, 256, &length)); ASSERT_GT(length, 0u); + EXPECT_EQ((4u + 1u) * 2u, length); value = GetPlatformWString(reinterpret_cast(buffer)); EXPECT_EQ(L"Last", value); } else { @@ -613,9 +613,63 @@ TEST_F(FPDFEditEmbeddertest, RemoveMarkedObjectsPrime) { // Expect certain number of tagged objects. The test file contains strings // from 1 to 19. - EXPECT_EQ(8u, prime_count); - EXPECT_EQ(4u, square_count); - EXPECT_EQ(9u, greater_than_ten_count); + EXPECT_EQ(expected_prime_count, prime_count); + EXPECT_EQ(expected_square_count, square_count); + EXPECT_EQ(expected_greater_than_ten_count, greater_than_ten_count); + EXPECT_EQ(expected_bounds_count, bounds_count); +} + +TEST_F(FPDFEditEmbeddertest, ReadMarkedObjectsIndirectDict) { + // Load document with some text marked with an indirect property. + EXPECT_TRUE(OpenDocument("text_in_page_marked_indirect.pdf")); + FPDF_PAGE page = LoadPage(0); + ASSERT_TRUE(page); + + CheckMarkCounts(page, 1, 19, 8, 4, 9, 1); + + UnloadPage(page); +} + +TEST_F(FPDFEditEmbeddertest, RemoveMarkedObjectsPrime) { + // Load document with some text. + EXPECT_TRUE(OpenDocument("text_in_page_marked.pdf")); + FPDF_PAGE page = LoadPage(0); + ASSERT_TRUE(page); + + // Show what the original file looks like. + { +#if _FX_PLATFORM_ == _FX_PLATFORM_APPLE_ + const char kOriginalMD5[] = "5a5eb63cb21cc15084fea1f14284b8df"; +#elif _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_ + const char kOriginalMD5[] = "587c507a40f613f9c530b2ce2d58d655"; +#else + const char kOriginalMD5[] = "2edc6e70d54889aa0c0b7bdf3e168f86"; +#endif + ScopedFPDFBitmap page_bitmap = RenderPageWithFlags(page, nullptr, 0); + CompareBitmap(page_bitmap.get(), 200, 200, kOriginalMD5); + } + + constexpr int expected_object_count = 19; + CheckMarkCounts(page, 1, expected_object_count, 8, 4, 9, 1); + + // Get all objects marked with "Prime" + std::vector primes; + for (int i = 0; i < expected_object_count; ++i) { + FPDF_PAGEOBJECT page_object = FPDFPage_GetObject(page, i); + + int mark_count = FPDFPageObj_CountMarks(page_object); + for (int j = 0; j < mark_count; ++j) { + FPDF_PAGEOBJECTMARK mark = FPDFPageObj_GetMark(page_object, j); + + char buffer[256]; + ASSERT_GT(FPDFPageObjMark_GetName(mark, buffer, 256), 0u); + std::wstring name = + GetPlatformWString(reinterpret_cast(buffer)); + if (name == L"Prime") { + primes.push_back(page_object); + } + } + } // Remove all objects marked with "Prime". for (FPDF_PAGEOBJECT page_object : primes) { diff --git a/testing/resources/text_in_page_marked_indirect.in b/testing/resources/text_in_page_marked_indirect.in new file mode 100644 index 0000000000..1f989f6f73 --- /dev/null +++ b/testing/resources/text_in_page_marked_indirect.in @@ -0,0 +1,144 @@ +{{header}} +{{object 1 0}} +<< /Pages 2 0 R /Type /Catalog >> +endobj +{{object 2 0}} +<< /Count 1 /Kids [ 3 0 R ] /MediaBox [ 0 0 200 200 ] /Type /Pages >> +endobj +{{object 3 0}} +<< + /Contents 4 0 R + /Parent 2 0 R + /Resources << + /ExtGState << /FXE1 5 0 R /FXE2 6 0 R >> + /Font << /F1 7 0 R /F2 8 0 R /FXF1 9 0 R /FXF2 10 0 R >> + /Properties << + /LastBoundsProperty 13 0 R + >> + >> + /Type /Page +>> +endobj +{{object 4 0}} +[ 12 0 R ] +endobj +{{object 5 0}} +<< /BM /Normal /CA 1 /ca 1 >> +endobj +{{object 6 0}} +<< /ca 0.705882 >> +endobj +{{object 7 0}} +<< /BaseFont /Times-Roman /Subtype /Type1 /Type /Font >> +endobj +{{object 8 0}} +<< /BaseFont /Helvetica /Subtype /Type1 /Type /Font >> +endobj +{{object 9 0}} +<< /BaseFont /Courier-Bold /Subtype /Type1 /Type /Font >> +endobj +{{object 10 0}} +<< /BaseFont /Times-Bold /Subtype /Type1 /Type /Font >> +endobj +{{object 12 0}} +<< {{streamlen}} >> +stream +q +0 0 0 RG 0 0 0 rg 1 w 0 J 0 j +/FXE1 gs +/Square <> BDC +q 0 0 0 rg /FXE2 gs BT 1 0 0 1 120 100 Tm /FXF1 9 Tf (Test 1) Tj ET Q +EMC +/Prime BMC +q 0 0 0.0509804 rg /FXE2 gs +BT 0.995597 -0.341789 0.341789 0.995597 119.912 93.1642 +Tm /FXF2 9 Tf (Test 2) Tj ET Q +q 0 0 0.101961 rg /FXE2 gs +BT 0.872208 -0.678867 0.678867 0.872208 117.444 86.4227 +Tm /FXF1 9 Tf (Test 3) Tj ET Q +EMC +/Square <> BDC +q 0 0 0.156863 rg /FXE2 gs +BT 0.633308 -0.969351 0.969351 0.633308 112.666 80.613 +Tm /FXF2 9 Tf (Test 4) Tj ET Q +EMC +/Prime BMC +q 0 0 0.207843 rg /FXE2 gs +BT 0.297167 -1.17348 1.17348 0.297167 105.943 76.5303 +Tm /FXF1 9 Tf (Test 5) Tj ET Q +EMC +q 0 0 0.262745 rg /FXE2 gs +BT -0.104311 -1.25884 1.25884 -0.104311 97.9138 74.8231 +Tm /FXF2 9 Tf (Test 6) Tj ET Q +/Prime BMC +q 0 0 0.313726 rg /FXE2 gs +BT -0.528547 -1.20496 1.20496 -0.528547 89.4291 75.9007 +Tm /FXF1 9 Tf (Test 7) Tj ET Q +EMC +q 0 0 0.364706 rg /FXE2 gs +BT -0.926806 -1.00678 1.00678 -0.926806 81.4639 79.8644 +Tm /FXF2 9 Tf (Test 8) Tj ET Q +/Square <> BDC +q 0 0 0.419608 rg /FXE2 gs +BT -1.24978 -0.676346 0.676346 -1.24978 75.0044 86.4731 +Tm /FXF1 9 Tf (Test 9) Tj ET Q +EMC +q 0 0 0.470588 rg /FXE2 gs +BT -1.45359 -0.24256 0.24256 -1.45359 70.9283 95.1488 +Tm /FXF2 9 Tf (Test 10) Tj ET Q +/GreaterThanTen BMC +/Prime BMC +q 0 0 0.52549 rg /FXE2 gs +BT -1.5055 0.251223 -0.251223 -1.5055 69.89 105.024 +Tm /FXF1 9 Tf (Test 11) Tj ET Q +EMC +q 0 0 0.576471 rg /FXE2 gs +BT -1.38864 0.751496 -0.751496 -1.38864 72.2271 115.03 +Tm /FXF2 9 Tf (Test 12) Tj ET Q +/Prime BMC +q 0 0 0.631373 rg /FXE2 gs +BT -1.10504 1.20039 -1.20039 -1.10504 77.8992 124.008 +Tm /FXF1 9 Tf (Test 13) Tj ET Q +EMC +q 0 0 0.682353 rg /FXE2 gs +BT -0.67654 1.54236 -1.54236 -0.67654 86.4692 130.847 +Tm /FXF2 9 Tf (Test 14) Tj ET Q +q 0 0 0.733333 rg /FXE2 gs +BT -0.143427 1.73091 -1.73091 -0.143427 97.1315 134.618 +Tm /FXF1 9 Tf (Test 15) Tj ET Q +/Square <> BDC +q 0 0 0.788235 rg /FXE2 gs +BT 0.43929 1.73472 -1.73472 0.43929 108.786 134.694 +Tm /FXF2 9 Tf (Test 16) Tj ET Q +EMC +/Prime BMC +q 0 0 0.839216 rg /FXE2 gs +BT 1.00754 1.54215 -1.54215 1.00754 120.151 130.843 +Tm /FXF1 9 Tf (Test 17) Tj ET Q +EMC +q 0 0 0.894118 rg /FXE2 gs +BT 1.49521 1.16377 -1.16377 1.49521 129.904 123.275 +Tm /FXF2 9 Tf (Test 18) Tj ET Q +/Bounds /LastBoundsProperty BDC +/Prime BMC +q 0 0 0.945098 rg /FXE2 gs +BT 1.84185 0.632309 -0.632309 1.84185 136.837 112.646 +Tm /FXF1 9 Tf (Test 19) Tj ET Q +EMC +EMC +EMC +Q +endstream +endobj +{{object 13 0}} +<< /Position (Last) >> +endobj + +{{xref}} +trailer << + /Root 1 0 R + /Size 14 + /ID [] +>> +{{startxref}} +%%EOF diff --git a/testing/resources/text_in_page_marked_indirect.pdf b/testing/resources/text_in_page_marked_indirect.pdf new file mode 100644 index 0000000000..8756291e1e --- /dev/null +++ b/testing/resources/text_in_page_marked_indirect.pdf @@ -0,0 +1,161 @@ +%PDF-1.7 +% ò¤ô +1 0 obj +<< /Pages 2 0 R /Type /Catalog >> +endobj +2 0 obj +<< /Count 1 /Kids [ 3 0 R ] /MediaBox [ 0 0 200 200 ] /Type /Pages >> +endobj +3 0 obj +<< + /Contents 4 0 R + /Parent 2 0 R + /Resources << + /ExtGState << /FXE1 5 0 R /FXE2 6 0 R >> + /Font << /F1 7 0 R /F2 8 0 R /FXF1 9 0 R /FXF2 10 0 R >> + /Properties << + /LastBoundsProperty 13 0 R + >> + >> + /Type /Page +>> +endobj +4 0 obj +[ 12 0 R ] +endobj +5 0 obj +<< /BM /Normal /CA 1 /ca 1 >> +endobj +6 0 obj +<< /ca 0.705882 >> +endobj +7 0 obj +<< /BaseFont /Times-Roman /Subtype /Type1 /Type /Font >> +endobj +8 0 obj +<< /BaseFont /Helvetica /Subtype /Type1 /Type /Font >> +endobj +9 0 obj +<< /BaseFont /Courier-Bold /Subtype /Type1 /Type /Font >> +endobj +10 0 obj +<< /BaseFont /Times-Bold /Subtype /Type1 /Type /Font >> +endobj +12 0 obj +<< /Length 2432 >> +stream +q +0 0 0 RG 0 0 0 rg 1 w 0 J 0 j +/FXE1 gs +/Square <> BDC +q 0 0 0 rg /FXE2 gs BT 1 0 0 1 120 100 Tm /FXF1 9 Tf (Test 1) Tj ET Q +EMC +/Prime BMC +q 0 0 0.0509804 rg /FXE2 gs +BT 0.995597 -0.341789 0.341789 0.995597 119.912 93.1642 +Tm /FXF2 9 Tf (Test 2) Tj ET Q +q 0 0 0.101961 rg /FXE2 gs +BT 0.872208 -0.678867 0.678867 0.872208 117.444 86.4227 +Tm /FXF1 9 Tf (Test 3) Tj ET Q +EMC +/Square <> BDC +q 0 0 0.156863 rg /FXE2 gs +BT 0.633308 -0.969351 0.969351 0.633308 112.666 80.613 +Tm /FXF2 9 Tf (Test 4) Tj ET Q +EMC +/Prime BMC +q 0 0 0.207843 rg /FXE2 gs +BT 0.297167 -1.17348 1.17348 0.297167 105.943 76.5303 +Tm /FXF1 9 Tf (Test 5) Tj ET Q +EMC +q 0 0 0.262745 rg /FXE2 gs +BT -0.104311 -1.25884 1.25884 -0.104311 97.9138 74.8231 +Tm /FXF2 9 Tf (Test 6) Tj ET Q +/Prime BMC +q 0 0 0.313726 rg /FXE2 gs +BT -0.528547 -1.20496 1.20496 -0.528547 89.4291 75.9007 +Tm /FXF1 9 Tf (Test 7) Tj ET Q +EMC +q 0 0 0.364706 rg /FXE2 gs +BT -0.926806 -1.00678 1.00678 -0.926806 81.4639 79.8644 +Tm /FXF2 9 Tf (Test 8) Tj ET Q +/Square <> BDC +q 0 0 0.419608 rg /FXE2 gs +BT -1.24978 -0.676346 0.676346 -1.24978 75.0044 86.4731 +Tm /FXF1 9 Tf (Test 9) Tj ET Q +EMC +q 0 0 0.470588 rg /FXE2 gs +BT -1.45359 -0.24256 0.24256 -1.45359 70.9283 95.1488 +Tm /FXF2 9 Tf (Test 10) Tj ET Q +/GreaterThanTen BMC +/Prime BMC +q 0 0 0.52549 rg /FXE2 gs +BT -1.5055 0.251223 -0.251223 -1.5055 69.89 105.024 +Tm /FXF1 9 Tf (Test 11) Tj ET Q +EMC +q 0 0 0.576471 rg /FXE2 gs +BT -1.38864 0.751496 -0.751496 -1.38864 72.2271 115.03 +Tm /FXF2 9 Tf (Test 12) Tj ET Q +/Prime BMC +q 0 0 0.631373 rg /FXE2 gs +BT -1.10504 1.20039 -1.20039 -1.10504 77.8992 124.008 +Tm /FXF1 9 Tf (Test 13) Tj ET Q +EMC +q 0 0 0.682353 rg /FXE2 gs +BT -0.67654 1.54236 -1.54236 -0.67654 86.4692 130.847 +Tm /FXF2 9 Tf (Test 14) Tj ET Q +q 0 0 0.733333 rg /FXE2 gs +BT -0.143427 1.73091 -1.73091 -0.143427 97.1315 134.618 +Tm /FXF1 9 Tf (Test 15) Tj ET Q +/Square <> BDC +q 0 0 0.788235 rg /FXE2 gs +BT 0.43929 1.73472 -1.73472 0.43929 108.786 134.694 +Tm /FXF2 9 Tf (Test 16) Tj ET Q +EMC +/Prime BMC +q 0 0 0.839216 rg /FXE2 gs +BT 1.00754 1.54215 -1.54215 1.00754 120.151 130.843 +Tm /FXF1 9 Tf (Test 17) Tj ET Q +EMC +q 0 0 0.894118 rg /FXE2 gs +BT 1.49521 1.16377 -1.16377 1.49521 129.904 123.275 +Tm /FXF2 9 Tf (Test 18) Tj ET Q +/Bounds /LastBoundsProperty BDC +/Prime BMC +q 0 0 0.945098 rg /FXE2 gs +BT 1.84185 0.632309 -0.632309 1.84185 136.837 112.646 +Tm /FXF1 9 Tf (Test 19) Tj ET Q +EMC +EMC +EMC +Q +endstream +endobj +13 0 obj +<< /Position (Last) >> +endobj + +xref +0 14 +0000000000 65535 f +0000000015 00000 n +0000000064 00000 n +0000000149 00000 n +0000000404 00000 n +0000000430 00000 n +0000000475 00000 n +0000000509 00000 n +0000000581 00000 n +0000000651 00000 n +0000000724 00000 n +0000000000 65535 f +0000000796 00000 n +0000003280 00000 n +trailer << + /Root 1 0 R + /Size 14 + /ID [] +>> +startxref +3320 +%%EOF -- cgit v1.2.3