From 07520f6e9cfd1c1f304d18af614d83938e382adb Mon Sep 17 00:00:00 2001 From: Henrique Nakashima Date: Thu, 12 Jul 2018 19:45:29 +0000 Subject: Create API to set and get blob values from a mark dict. The new functions are: - FPDFPageObjMark_GetParamBlobValue - FPDFPageObjMark_SetBlobParam Bug: pdfium:1037 Change-Id: Ie04df04c64c6cf517a8cde182d7e9a38c3c78d1b Reviewed-on: https://pdfium-review.googlesource.com/37570 Commit-Queue: Henrique Nakashima Reviewed-by: Lei Zhang --- fpdfsdk/fpdf_edit_embeddertest.cpp | 16 ++++++++++++- fpdfsdk/fpdf_editpage.cpp | 48 ++++++++++++++++++++++++++++++++++++++ fpdfsdk/fpdf_view_c_api_test.c | 2 ++ public/fpdf_edit.h | 41 +++++++++++++++++++++++++++++++- 4 files changed, 105 insertions(+), 2 deletions(-) diff --git a/fpdfsdk/fpdf_edit_embeddertest.cpp b/fpdfsdk/fpdf_edit_embeddertest.cpp index 800fc70076..e47f3db360 100644 --- a/fpdfsdk/fpdf_edit_embeddertest.cpp +++ b/fpdfsdk/fpdf_edit_embeddertest.cpp @@ -2175,11 +2175,17 @@ TEST_F(FPDFEditEmbeddertest, AddMarkedText) { // Add parameters: // - int "IntKey" : 42 // - string "StringKey": "StringValue" + // - blob "BlobKey": "\x01\x02\x03\0BlobValue1\0\0\0BlobValue2\0" + constexpr const size_t kBlobLen = 28; + char kBlobValue[kBlobLen]; + memcpy(kBlobValue, "\x01\x02\x03\0BlobValue1\0\0\0BlobValue2\0", kBlobLen); EXPECT_EQ(0, FPDFPageObjMark_CountParams(mark)); EXPECT_TRUE(FPDFPageObjMark_SetIntParam(document(), mark, "IntKey", 42)); EXPECT_TRUE(FPDFPageObjMark_SetStringParam(document(), mark, "StringKey", "StringValue")); - EXPECT_EQ(2, FPDFPageObjMark_CountParams(mark)); + EXPECT_TRUE(FPDFPageObjMark_SetBlobParam(document(), mark, "BlobKey", + kBlobValue, kBlobLen)); + EXPECT_EQ(3, FPDFPageObjMark_CountParams(mark)); // Check the two parameters can be retrieved. EXPECT_EQ(FPDF_OBJECT_NUMBER, @@ -2197,6 +2203,14 @@ TEST_F(FPDFEditEmbeddertest, AddMarkedText) { name = GetPlatformWString(reinterpret_cast(buffer)); EXPECT_EQ(L"StringValue", name); + EXPECT_EQ(FPDF_OBJECT_STRING, + FPDFPageObjMark_GetParamValueType(mark, "BlobKey")); + out_buffer_len = 0; + EXPECT_TRUE(FPDFPageObjMark_GetParamBlobValue(mark, "BlobKey", buffer, 256, + &out_buffer_len)); + EXPECT_EQ(kBlobLen, out_buffer_len); + EXPECT_EQ(0, memcmp(kBlobValue, buffer, kBlobLen)); + // Render and check the bitmap is the expected one. #if _FX_PLATFORM_ == _FX_PLATFORM_APPLE_ const char md5[] = "17d2b6cd574cf66170b09c8927529a94"; diff --git a/fpdfsdk/fpdf_editpage.cpp b/fpdfsdk/fpdf_editpage.cpp index 4df5505cca..02c07d1724 100644 --- a/fpdfsdk/fpdf_editpage.cpp +++ b/fpdfsdk/fpdf_editpage.cpp @@ -402,6 +402,9 @@ FPDFPageObjMark_GetParamStringValue(FPDF_PAGEOBJECTMARK mark, void* buffer, unsigned long buflen, unsigned long* out_buflen) { + if (!out_buflen) + return false; + const CPDF_Dictionary* pParams = GetMarkParamDict(mark); if (!pParams) return false; @@ -415,6 +418,33 @@ FPDFPageObjMark_GetParamStringValue(FPDF_PAGEOBJECTMARK mark, return true; } +FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV +FPDFPageObjMark_GetParamBlobValue(FPDF_PAGEOBJECTMARK mark, + FPDF_BYTESTRING key, + void* buffer, + unsigned long buflen, + unsigned long* out_buflen) { + if (!out_buflen) + return false; + + const CPDF_Dictionary* pParams = GetMarkParamDict(mark); + if (!pParams) + return false; + + const CPDF_Object* pObj = pParams->GetObjectFor(key); + if (!pObj || !pObj->IsString()) + return false; + + ByteString result = pObj->GetString(); + unsigned long len = result.GetLength(); + + if (buffer && len <= buflen) + memcpy(buffer, result.c_str(), len); + + *out_buflen = len; + return true; +} + FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFPageObj_HasTransparency(FPDF_PAGEOBJECT pageObject) { if (!pageObject) @@ -475,6 +505,24 @@ FPDFPageObjMark_SetStringParam(FPDF_DOCUMENT document, return true; } +FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV +FPDFPageObjMark_SetBlobParam(FPDF_DOCUMENT document, + FPDF_PAGEOBJECTMARK mark, + FPDF_BYTESTRING key, + void* value, + unsigned long value_len) { + CPDF_Dictionary* pParams = GetOrCreateMarkParamsDict(document, mark); + if (!pParams) + return false; + + if (!value && value_len > 0) + return false; + + pParams->SetNewFor( + key, ByteString(static_cast(value), value_len), true); + return true; +} + FPDF_EXPORT int FPDF_CALLCONV FPDFPageObj_GetType(FPDF_PAGEOBJECT pageObject) { if (!pageObject) return FPDF_PAGEOBJ_UNKNOWN; diff --git a/fpdfsdk/fpdf_view_c_api_test.c b/fpdfsdk/fpdf_view_c_api_test.c index 70db94fe96..a89bc2e775 100644 --- a/fpdfsdk/fpdf_view_c_api_test.c +++ b/fpdfsdk/fpdf_view_c_api_test.c @@ -139,10 +139,12 @@ int CheckPDFiumCApi() { CHK(FPDFImageObj_SetMatrix); CHK(FPDFPageObjMark_CountParams); CHK(FPDFPageObjMark_GetName); + CHK(FPDFPageObjMark_GetParamBlobValue); CHK(FPDFPageObjMark_GetParamIntValue); CHK(FPDFPageObjMark_GetParamKey); CHK(FPDFPageObjMark_GetParamStringValue); CHK(FPDFPageObjMark_GetParamValueType); + CHK(FPDFPageObjMark_SetBlobParam); CHK(FPDFPageObjMark_SetIntParam); CHK(FPDFPageObjMark_SetStringParam); CHK(FPDFPageObj_AddMark); diff --git a/public/fpdf_edit.h b/public/fpdf_edit.h index e7f6cc4a70..677bce80b1 100644 --- a/public/fpdf_edit.h +++ b/public/fpdf_edit.h @@ -407,7 +407,7 @@ FPDFPageObjMark_GetParamIntValue(FPDF_PAGEOBJECTMARK mark, // out_buflen - pointer to variable that will receive the length of the value. // Not filled if false is returned. // -// Returns TRUE if the key maps to a string value, FALSE otherwise. +// Returns TRUE if the key maps to a string/blob value, FALSE otherwise. FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFPageObjMark_GetParamStringValue(FPDF_PAGEOBJECTMARK mark, FPDF_BYTESTRING key, @@ -415,6 +415,26 @@ FPDFPageObjMark_GetParamStringValue(FPDF_PAGEOBJECTMARK mark, unsigned long buflen, unsigned long* out_buflen); +// Experimental API. +// Get the value of a blob property in a content mark by key. +// |buffer| is only modified if |buflen| is longer than or equal to the length +// of the value. +// +// mark - handle to a content mark. +// key - string key of the property. +// buffer - buffer for holding the returned value. +// buflen - length of the buffer. +// out_buflen - pointer to variable that will receive the length of the value. +// Not filled if false is returned. +// +// Returns TRUE if the key maps to a string/blob value, FALSE otherwise. +FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV +FPDFPageObjMark_GetParamBlobValue(FPDF_PAGEOBJECTMARK mark, + FPDF_BYTESTRING key, + void* buffer, + unsigned long buflen, + unsigned long* out_buflen); + // Experimental API. // Set the value of an int property in a content mark by key. If a parameter // with key |key| exists, its value is set to |value|. Otherwise, it is added as @@ -449,6 +469,25 @@ FPDFPageObjMark_SetStringParam(FPDF_DOCUMENT document, FPDF_BYTESTRING key, FPDF_BYTESTRING value); +// Experimental API. +// Set the value of a blob property in a content mark by key. If a parameter +// with key |key| exists, its value is set to |value|. Otherwise, it is added as +// a new parameter. +// +// document - handle to the document. +// mark - handle to a content mark. +// key - string key of the property. +// value - pointer to blob value to set. +// value_len - size in bytes of |value|. +// +// Returns TRUE if the operation succeeded, FALSE otherwise. +FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV +FPDFPageObjMark_SetBlobParam(FPDF_DOCUMENT document, + FPDF_PAGEOBJECTMARK mark, + FPDF_BYTESTRING key, + void* value, + unsigned long value_len); + // Load an image from a JPEG image file and then set it into |image_object|. // // pages - pointer to the start of all loaded pages, may be NULL. -- cgit v1.2.3