Add FPDFSignatureObj_GetContents() API
This follows the same pattern as FPDFTextObj_GetFontName(), so the
client has to call this function twice, but allocation of the buffer
happens outside pdfium.
Change-Id: Iafc1a19dfcb81c9c7b34571ac17cc77f7d9b5da9
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/71470
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/fpdfsdk/cpdfsdk_helpers.h b/fpdfsdk/cpdfsdk_helpers.h
index 9d47ad1..6a0b4fc 100644
--- a/fpdfsdk/cpdfsdk_helpers.h
+++ b/fpdfsdk/cpdfsdk_helpers.h
@@ -215,6 +215,10 @@
CPDF_Dictionary* dictionary) {
return reinterpret_cast<FPDF_SIGNATURE>(dictionary);
}
+inline CPDF_Dictionary* CPDFDictionaryFromFPDFSignature(
+ FPDF_SIGNATURE signature) {
+ return reinterpret_cast<CPDF_Dictionary*>(signature);
+}
CPDFSDK_InteractiveForm* FormHandleToInteractiveForm(FPDF_FORMHANDLE hHandle);
diff --git a/fpdfsdk/fpdf_signature.cpp b/fpdfsdk/fpdf_signature.cpp
index 7c1353f..1d9f76a 100644
--- a/fpdfsdk/fpdf_signature.cpp
+++ b/fpdfsdk/fpdf_signature.cpp
@@ -57,3 +57,23 @@
return FPDFSignatureFromCPDFDictionary(signatures[index]);
}
+
+FPDF_EXPORT unsigned long FPDF_CALLCONV
+FPDFSignatureObj_GetContents(FPDF_SIGNATURE signature,
+ void* buffer,
+ unsigned long length) {
+ CPDF_Dictionary* signature_dict = CPDFDictionaryFromFPDFSignature(signature);
+ if (!signature_dict)
+ return 0;
+
+ CPDF_Dictionary* value_dict = signature_dict->GetDictFor("V");
+ if (!value_dict)
+ return 0;
+
+ ByteString contents = value_dict->GetStringFor("Contents");
+ unsigned long contents_len = contents.GetLength();
+ if (buffer && length >= contents_len)
+ memcpy(buffer, contents.c_str(), contents_len);
+
+ return contents_len;
+}
diff --git a/fpdfsdk/fpdf_signature_embeddertest.cpp b/fpdfsdk/fpdf_signature_embeddertest.cpp
index 851df00..3face6e 100644
--- a/fpdfsdk/fpdf_signature_embeddertest.cpp
+++ b/fpdfsdk/fpdf_signature_embeddertest.cpp
@@ -36,3 +36,32 @@
// Provide no document.
EXPECT_EQ(nullptr, FPDF_GetSignatureObject(nullptr, 0));
}
+
+TEST_F(FPDFSignatureEmbedderTest, GetContents) {
+ EXPECT_TRUE(OpenDocument("two_signatures.pdf"));
+ FPDF_SIGNATURE signature = FPDF_GetSignatureObject(document(), 0);
+ EXPECT_NE(nullptr, signature);
+
+ // FPDFSignatureObj_GetContents() positive testing.
+ unsigned long size = FPDFSignatureObj_GetContents(signature, nullptr, 0);
+ const uint8_t kExpectedContents[] = {0x30, 0x80, 0x06, 0x09, 0x2A, 0x86, 0x48,
+ 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x02, 0xA0,
+ 0x80, 0x30, 0x80, 0x02, 0x01, 0x01};
+ ASSERT_EQ(sizeof(kExpectedContents), size);
+ std::vector<char> contents(size);
+ ASSERT_EQ(size,
+ FPDFSignatureObj_GetContents(signature, contents.data(), size));
+ ASSERT_EQ(0, memcmp(kExpectedContents, contents.data(), size));
+
+ // FPDFSignatureObj_GetContents() negative testing.
+ ASSERT_EQ(0U, FPDFSignatureObj_GetContents(nullptr, nullptr, 0));
+
+ contents.resize(2);
+ contents[0] = 'x';
+ contents[1] = '\0';
+ size =
+ FPDFSignatureObj_GetContents(signature, contents.data(), contents.size());
+ ASSERT_EQ(sizeof(kExpectedContents), size);
+ EXPECT_EQ('x', contents[0]);
+ EXPECT_EQ('\0', contents[1]);
+}
diff --git a/fpdfsdk/fpdf_view_c_api_test.c b/fpdfsdk/fpdf_view_c_api_test.c
index 214fb733..3c29a89 100644
--- a/fpdfsdk/fpdf_view_c_api_test.c
+++ b/fpdfsdk/fpdf_view_c_api_test.c
@@ -316,6 +316,7 @@
CHK(FPDFText_GetTextIndexFromCharIndex);
// fpdf_signature.h
+ CHK(FPDFSignatureObj_GetContents);
CHK(FPDF_GetSignatureCount);
CHK(FPDF_GetSignatureObject);