Add ScopedFPDFTextFind.
For calling FPDFText_FindClose() automatically.
Change-Id: Iaeda33fc7e2aa3199ab657fac88ec8410398b8e7
Reviewed-on: https://pdfium-review.googlesource.com/c/50470
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/fpdfsdk/fpdf_text_embeddertest.cpp b/fpdfsdk/fpdf_text_embeddertest.cpp
index c5a99d3..db2716a 100644
--- a/fpdfsdk/fpdf_text_embeddertest.cpp
+++ b/fpdfsdk/fpdf_text_embeddertest.cpp
@@ -209,94 +209,104 @@
std::unique_ptr<unsigned short, pdfium::FreeDeleter> world_substr =
GetFPDFWideString(L"orld");
- // No occurences of "nope" in test page.
- FPDF_SCHHANDLE search = FPDFText_FindStart(textpage, nope.get(), 0, 0);
- EXPECT_TRUE(search);
- EXPECT_EQ(0, FPDFText_GetSchResultIndex(search));
- EXPECT_EQ(0, FPDFText_GetSchCount(search));
+ {
+ // No occurences of "nope" in test page.
+ ScopedFPDFTextFind search(FPDFText_FindStart(textpage, nope.get(), 0, 0));
+ EXPECT_TRUE(search);
+ EXPECT_EQ(0, FPDFText_GetSchResultIndex(search.get()));
+ EXPECT_EQ(0, FPDFText_GetSchCount(search.get()));
- // Advancing finds nothing.
- EXPECT_FALSE(FPDFText_FindNext(search));
- EXPECT_EQ(0, FPDFText_GetSchResultIndex(search));
- EXPECT_EQ(0, FPDFText_GetSchCount(search));
+ // Advancing finds nothing.
+ EXPECT_FALSE(FPDFText_FindNext(search.get()));
+ EXPECT_EQ(0, FPDFText_GetSchResultIndex(search.get()));
+ EXPECT_EQ(0, FPDFText_GetSchCount(search.get()));
- // Retreating finds nothing.
- EXPECT_FALSE(FPDFText_FindPrev(search));
- EXPECT_EQ(0, FPDFText_GetSchResultIndex(search));
- EXPECT_EQ(0, FPDFText_GetSchCount(search));
- FPDFText_FindClose(search);
+ // Retreating finds nothing.
+ EXPECT_FALSE(FPDFText_FindPrev(search.get()));
+ EXPECT_EQ(0, FPDFText_GetSchResultIndex(search.get()));
+ EXPECT_EQ(0, FPDFText_GetSchCount(search.get()));
+ }
- // Two occurences of "world" in test page.
- search = FPDFText_FindStart(textpage, world.get(), 0, 2);
- EXPECT_TRUE(search);
+ {
+ // Two occurences of "world" in test page.
+ ScopedFPDFTextFind search(FPDFText_FindStart(textpage, world.get(), 0, 2));
+ EXPECT_TRUE(search);
- // Remains not found until advanced.
- EXPECT_EQ(0, FPDFText_GetSchResultIndex(search));
- EXPECT_EQ(0, FPDFText_GetSchCount(search));
+ // Remains not found until advanced.
+ EXPECT_EQ(0, FPDFText_GetSchResultIndex(search.get()));
+ EXPECT_EQ(0, FPDFText_GetSchCount(search.get()));
- // First occurence of "world" in this test page.
- EXPECT_TRUE(FPDFText_FindNext(search));
- EXPECT_EQ(7, FPDFText_GetSchResultIndex(search));
- EXPECT_EQ(5, FPDFText_GetSchCount(search));
+ // First occurence of "world" in this test page.
+ EXPECT_TRUE(FPDFText_FindNext(search.get()));
+ EXPECT_EQ(7, FPDFText_GetSchResultIndex(search.get()));
+ EXPECT_EQ(5, FPDFText_GetSchCount(search.get()));
- // Last occurence of "world" in this test page.
- EXPECT_TRUE(FPDFText_FindNext(search));
- EXPECT_EQ(24, FPDFText_GetSchResultIndex(search));
- EXPECT_EQ(5, FPDFText_GetSchCount(search));
+ // Last occurence of "world" in this test page.
+ EXPECT_TRUE(FPDFText_FindNext(search.get()));
+ EXPECT_EQ(24, FPDFText_GetSchResultIndex(search.get()));
+ EXPECT_EQ(5, FPDFText_GetSchCount(search.get()));
- // Found position unchanged when fails to advance.
- EXPECT_FALSE(FPDFText_FindNext(search));
- EXPECT_EQ(24, FPDFText_GetSchResultIndex(search));
- EXPECT_EQ(5, FPDFText_GetSchCount(search));
+ // Found position unchanged when fails to advance.
+ EXPECT_FALSE(FPDFText_FindNext(search.get()));
+ EXPECT_EQ(24, FPDFText_GetSchResultIndex(search.get()));
+ EXPECT_EQ(5, FPDFText_GetSchCount(search.get()));
- // Back to first occurence.
- EXPECT_TRUE(FPDFText_FindPrev(search));
- EXPECT_EQ(7, FPDFText_GetSchResultIndex(search));
- EXPECT_EQ(5, FPDFText_GetSchCount(search));
+ // Back to first occurence.
+ EXPECT_TRUE(FPDFText_FindPrev(search.get()));
+ EXPECT_EQ(7, FPDFText_GetSchResultIndex(search.get()));
+ EXPECT_EQ(5, FPDFText_GetSchCount(search.get()));
- // Found position unchanged when fails to retreat.
- EXPECT_FALSE(FPDFText_FindPrev(search));
- EXPECT_EQ(7, FPDFText_GetSchResultIndex(search));
- EXPECT_EQ(5, FPDFText_GetSchCount(search));
- FPDFText_FindClose(search);
+ // Found position unchanged when fails to retreat.
+ EXPECT_FALSE(FPDFText_FindPrev(search.get()));
+ EXPECT_EQ(7, FPDFText_GetSchResultIndex(search.get()));
+ EXPECT_EQ(5, FPDFText_GetSchCount(search.get()));
+ }
- // Exact search unaffected by case sensitiity and whole word flags.
- search = FPDFText_FindStart(textpage, world.get(),
- FPDF_MATCHCASE | FPDF_MATCHWHOLEWORD, 0);
- EXPECT_TRUE(search);
- EXPECT_TRUE(FPDFText_FindNext(search));
- EXPECT_EQ(7, FPDFText_GetSchResultIndex(search));
- EXPECT_EQ(5, FPDFText_GetSchCount(search));
- FPDFText_FindClose(search);
+ {
+ // Exact search unaffected by case sensitiity and whole word flags.
+ ScopedFPDFTextFind search(FPDFText_FindStart(
+ textpage, world.get(), FPDF_MATCHCASE | FPDF_MATCHWHOLEWORD, 0));
+ EXPECT_TRUE(search);
+ EXPECT_TRUE(FPDFText_FindNext(search.get()));
+ EXPECT_EQ(7, FPDFText_GetSchResultIndex(search.get()));
+ EXPECT_EQ(5, FPDFText_GetSchCount(search.get()));
+ }
- // Default is case-insensitive, so matching agaist caps works.
- search = FPDFText_FindStart(textpage, world_caps.get(), 0, 0);
- EXPECT_TRUE(search);
- EXPECT_TRUE(FPDFText_FindNext(search));
- EXPECT_EQ(7, FPDFText_GetSchResultIndex(search));
- EXPECT_EQ(5, FPDFText_GetSchCount(search));
- FPDFText_FindClose(search);
+ {
+ // Default is case-insensitive, so matching agaist caps works.
+ ScopedFPDFTextFind search(
+ FPDFText_FindStart(textpage, world_caps.get(), 0, 0));
+ EXPECT_TRUE(search);
+ EXPECT_TRUE(FPDFText_FindNext(search.get()));
+ EXPECT_EQ(7, FPDFText_GetSchResultIndex(search.get()));
+ EXPECT_EQ(5, FPDFText_GetSchCount(search.get()));
+ }
- // But can be made case sensitive, in which case this fails.
- search = FPDFText_FindStart(textpage, world_caps.get(), FPDF_MATCHCASE, 0);
- EXPECT_FALSE(FPDFText_FindNext(search));
- EXPECT_EQ(0, FPDFText_GetSchResultIndex(search));
- EXPECT_EQ(0, FPDFText_GetSchCount(search));
- FPDFText_FindClose(search);
+ {
+ // But can be made case sensitive, in which case this fails.
+ ScopedFPDFTextFind search(
+ FPDFText_FindStart(textpage, world_caps.get(), FPDF_MATCHCASE, 0));
+ EXPECT_FALSE(FPDFText_FindNext(search.get()));
+ EXPECT_EQ(0, FPDFText_GetSchResultIndex(search.get()));
+ EXPECT_EQ(0, FPDFText_GetSchCount(search.get()));
+ }
- // Default is match anywhere within word, so matching substirng works.
- search = FPDFText_FindStart(textpage, world_substr.get(), 0, 0);
- EXPECT_TRUE(FPDFText_FindNext(search));
- EXPECT_EQ(8, FPDFText_GetSchResultIndex(search));
- EXPECT_EQ(4, FPDFText_GetSchCount(search));
- FPDFText_FindClose(search);
+ {
+ // Default is match anywhere within word, so matching substring works.
+ ScopedFPDFTextFind search(
+ FPDFText_FindStart(textpage, world_substr.get(), 0, 0));
+ EXPECT_TRUE(FPDFText_FindNext(search.get()));
+ EXPECT_EQ(8, FPDFText_GetSchResultIndex(search.get()));
+ EXPECT_EQ(4, FPDFText_GetSchCount(search.get()));
+ }
- // But can be made to mach word boundaries, in which case this fails.
- search =
- FPDFText_FindStart(textpage, world_substr.get(), FPDF_MATCHWHOLEWORD, 0);
- EXPECT_FALSE(FPDFText_FindNext(search));
- // TODO(tsepez): investigate strange index/count values in this state.
- FPDFText_FindClose(search);
+ {
+ // But can be made to mach word boundaries, in which case this fails.
+ ScopedFPDFTextFind search(FPDFText_FindStart(textpage, world_substr.get(),
+ FPDF_MATCHWHOLEWORD, 0));
+ EXPECT_FALSE(FPDFText_FindNext(search.get()));
+ // TODO(tsepez): investigate strange index/count values in this state.
+ }
FPDFText_ClosePage(textpage);
UnloadPage(page);
diff --git a/public/cpp/fpdf_deleters.h b/public/cpp/fpdf_deleters.h
index 5275381..5cc0fb6 100644
--- a/public/cpp/fpdf_deleters.h
+++ b/public/cpp/fpdf_deleters.h
@@ -61,6 +61,10 @@
inline void operator()(FPDF_STRUCTTREE tree) { FPDF_StructTree_Close(tree); }
};
+struct FPDFTextFindDeleter {
+ inline void operator()(FPDF_SCHHANDLE handle) { FPDFText_FindClose(handle); }
+};
+
struct FPDFTextPageDeleter {
inline void operator()(FPDF_TEXTPAGE text) { FPDFText_ClosePage(text); }
};
diff --git a/public/cpp/fpdf_scopers.h b/public/cpp/fpdf_scopers.h
index 3fe63e3..7d9cbc0 100644
--- a/public/cpp/fpdf_scopers.h
+++ b/public/cpp/fpdf_scopers.h
@@ -55,6 +55,10 @@
std::unique_ptr<std::remove_pointer<FPDF_STRUCTTREE>::type,
FPDFStructTreeDeleter>;
+using ScopedFPDFTextFind =
+ std::unique_ptr<std::remove_pointer<FPDF_SCHHANDLE>::type,
+ FPDFTextFindDeleter>;
+
using ScopedFPDFTextPage =
std::unique_ptr<std::remove_pointer<FPDF_TEXTPAGE>::type,
FPDFTextPageDeleter>;