Avoid using void* in experimental APIs in fpdf_edit.h
Instead of taking buffers of type void*, specify the proper type. e.g.
FPDF_WCHAR*, or const unsigned char*. Then adjust tests to match and
avoid having to do casts. Also:
- Improve documentation in fpdf_edit.h.
- Remove an UNSAFE_TODO() along the way.
Change-Id: Ifd1efafd2944385497ac87379914b419bd271766
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/124950
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Tom Sepez <tsepez@google.com>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/fpdfsdk/fpdf_edit_embeddertest.cpp b/fpdfsdk/fpdf_edit_embeddertest.cpp
index 57680a1..8d3512d 100644
--- a/fpdfsdk/fpdf_edit_embeddertest.cpp
+++ b/fpdfsdk/fpdf_edit_embeddertest.cpp
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stdint.h>
+
#include <limits>
#include <memory>
#include <ostream>
@@ -23,6 +25,7 @@
#include "core/fxcrt/fx_codepage.h"
#include "core/fxcrt/fx_memcpy_wrappers.h"
#include "core/fxcrt/fx_system.h"
+#include "core/fxcrt/span_util.h"
#include "core/fxge/cfx_defaultrenderdevice.h"
#include "core/fxge/fx_font.h"
#include "fpdfsdk/cpdfsdk_helpers.h"
@@ -1318,14 +1321,13 @@
for (int j = 0; j < mark_count; ++j) {
FPDF_PAGEOBJECTMARK mark = FPDFPageObj_GetMark(page_object, j);
- char buffer[256];
+ FPDF_WCHAR buffer[128];
unsigned long name_len = 999u;
ASSERT_TRUE(
FPDFPageObjMark_GetName(mark, buffer, sizeof(buffer), &name_len));
EXPECT_GT(name_len, 0u);
EXPECT_NE(999u, name_len);
- std::wstring name =
- GetPlatformWString(reinterpret_cast<unsigned short*>(buffer));
+ std::wstring name = GetPlatformWString(buffer);
if (name == L"Prime") {
prime_count++;
} else if (name == L"Square") {
@@ -1337,8 +1339,7 @@
ASSERT_TRUE(FPDFPageObjMark_GetParamKey(mark, 0, buffer, sizeof(buffer),
&get_param_key_return));
EXPECT_EQ((6u + 1u) * 2u, get_param_key_return);
- std::wstring key =
- GetPlatformWString(reinterpret_cast<unsigned short*>(buffer));
+ std::wstring key = GetPlatformWString(buffer);
EXPECT_EQ(L"Factor", key);
EXPECT_EQ(FPDF_OBJECT_NUMBER,
@@ -1357,8 +1358,7 @@
ASSERT_TRUE(FPDFPageObjMark_GetParamKey(mark, 0, buffer, sizeof(buffer),
&get_param_key_return));
EXPECT_EQ((8u + 1u) * 2u, get_param_key_return);
- std::wstring key =
- GetPlatformWString(reinterpret_cast<unsigned short*>(buffer));
+ std::wstring key = GetPlatformWString(buffer);
EXPECT_EQ(L"Position", key);
EXPECT_EQ(FPDF_OBJECT_STRING,
@@ -1367,8 +1367,7 @@
EXPECT_TRUE(FPDFPageObjMark_GetParamStringValue(
mark, "Position", buffer, sizeof(buffer), &length));
ASSERT_GT(length, 0u);
- std::wstring value =
- GetPlatformWString(reinterpret_cast<unsigned short*>(buffer));
+ std::wstring value = GetPlatformWString(buffer);
// "Position" can be "First", "Last", or "End".
if (i == 0) {
@@ -1470,14 +1469,13 @@
for (int j = 0; j < mark_count; ++j) {
FPDF_PAGEOBJECTMARK mark = FPDFPageObj_GetMark(page_object, j);
- char buffer[256];
+ FPDF_WCHAR buffer[128];
unsigned long name_len = 999u;
ASSERT_TRUE(
FPDFPageObjMark_GetName(mark, buffer, sizeof(buffer), &name_len));
EXPECT_GT(name_len, 0u);
EXPECT_NE(999u, name_len);
- std::wstring name =
- GetPlatformWString(reinterpret_cast<unsigned short*>(buffer));
+ std::wstring name = GetPlatformWString(buffer);
if (name == L"Prime") {
primes.push_back(page_object);
}
@@ -1572,14 +1570,13 @@
for (int j = mark_count - 1; j >= 0; --j) {
FPDF_PAGEOBJECTMARK mark = FPDFPageObj_GetMark(page_object, j);
- char buffer[256];
+ FPDF_WCHAR buffer[128];
unsigned long name_len = 999u;
ASSERT_TRUE(
FPDFPageObjMark_GetName(mark, buffer, sizeof(buffer), &name_len));
EXPECT_GT(name_len, 0u);
EXPECT_NE(999u, name_len);
- std::wstring name =
- GetPlatformWString(reinterpret_cast<unsigned short*>(buffer));
+ std::wstring name = GetPlatformWString(buffer);
if (name == L"Prime") {
// Remove mark.
EXPECT_TRUE(FPDFPageObj_RemoveMark(page_object, mark));
@@ -1625,14 +1622,13 @@
for (int j = 0; j < mark_count; ++j) {
FPDF_PAGEOBJECTMARK mark = FPDFPageObj_GetMark(page_object, j);
- char buffer[256];
+ FPDF_WCHAR buffer[128];
unsigned long name_len = 999u;
ASSERT_TRUE(
FPDFPageObjMark_GetName(mark, buffer, sizeof(buffer), &name_len));
EXPECT_GT(name_len, 0u);
EXPECT_NE(999u, name_len);
- std::wstring name =
- GetPlatformWString(reinterpret_cast<unsigned short*>(buffer));
+ std::wstring name = GetPlatformWString(buffer);
if (name == L"Square") {
// Show the mark has a "Factor" parameter.
int out_value;
@@ -1666,14 +1662,13 @@
for (int j = 0; j < mark_count; ++j) {
FPDF_PAGEOBJECTMARK mark = FPDFPageObj_GetMark(page_object, j);
- char buffer[256];
+ FPDF_WCHAR buffer[128];
unsigned long name_len = 999u;
ASSERT_TRUE(
FPDFPageObjMark_GetName(mark, buffer, sizeof(buffer), &name_len));
EXPECT_GT(name_len, 0u);
EXPECT_NE(999u, name_len);
- std::wstring name =
- GetPlatformWString(reinterpret_cast<unsigned short*>(buffer));
+ std::wstring name = GetPlatformWString(buffer);
if (name == L"Square") {
// Verify the "Factor" parameter is still gone.
int out_value;
@@ -3957,17 +3952,15 @@
FPDF_PAGEOBJECT page_object = FPDFPage_GetObject(page.get(), 18);
FPDF_PAGEOBJECTMARK mark = FPDFPageObj_GetMark(page_object, 1);
ASSERT_TRUE(mark);
- char buffer[256];
+ FPDF_WCHAR buffer[128];
unsigned long name_len = 999u;
ASSERT_TRUE(FPDFPageObjMark_GetName(mark, buffer, sizeof(buffer), &name_len));
EXPECT_EQ((6u + 1u) * 2u, name_len);
- ASSERT_EQ(L"Bounds",
- GetPlatformWString(reinterpret_cast<unsigned short*>(buffer)));
+ ASSERT_EQ(L"Bounds", GetPlatformWString(buffer));
unsigned long out_buffer_len;
ASSERT_TRUE(FPDFPageObjMark_GetParamStringValue(
mark, "Position", buffer, sizeof(buffer), &out_buffer_len));
- ASSERT_EQ(L"Last",
- GetPlatformWString(reinterpret_cast<unsigned short*>(buffer)));
+ ASSERT_EQ(L"Last", GetPlatformWString(buffer));
// Set is to "End".
EXPECT_TRUE(FPDFPageObjMark_SetStringParam(document(), page_object, mark,
@@ -3984,8 +3977,7 @@
// Verify "Position" now maps to "End".
EXPECT_TRUE(FPDFPageObjMark_GetParamStringValue(
mark, "Position", buffer, sizeof(buffer), &out_buffer_len));
- EXPECT_EQ(L"End",
- GetPlatformWString(reinterpret_cast<unsigned short*>(buffer)));
+ EXPECT_EQ(L"End", GetPlatformWString(buffer));
// Save the file
EXPECT_TRUE(FPDFPage_GenerateContent(page.get()));
@@ -4001,8 +3993,7 @@
mark = FPDFPageObj_GetMark(page_object, 1);
EXPECT_TRUE(FPDFPageObjMark_GetParamStringValue(
mark, "Position", buffer, sizeof(buffer), &out_buffer_len));
- EXPECT_EQ(L"End",
- GetPlatformWString(reinterpret_cast<unsigned short*>(buffer)));
+ EXPECT_EQ(L"End", GetPlatformWString(buffer));
CloseSavedPage(saved_page);
CloseSavedDocument();
@@ -4035,29 +4026,27 @@
EXPECT_TRUE(mark);
EXPECT_EQ(1, FPDFPageObj_CountMarks(text_object));
EXPECT_EQ(mark, FPDFPageObj_GetMark(text_object, 0));
- char buffer[256];
+ FPDF_WCHAR buffer[128];
unsigned long name_len = 999u;
ASSERT_TRUE(FPDFPageObjMark_GetName(mark, buffer, sizeof(buffer), &name_len));
EXPECT_EQ((14u + 1u) * 2, name_len);
- std::wstring name =
- GetPlatformWString(reinterpret_cast<unsigned short*>(buffer));
+ std::wstring name = GetPlatformWString(buffer);
EXPECT_EQ(L"Test Mark Name", name);
// Add parameters:
// - int "IntKey" : 42
// - string "StringKey": "StringValue"
// - blob "BlobKey": "\x01\x02\x03\0BlobValue1\0\0\0BlobValue2\0"
- constexpr size_t kBlobLen = 28;
- char block_value[kBlobLen];
- UNSAFE_TODO(FXSYS_memcpy(
- block_value, "\x01\x02\x03\0BlobValue1\0\0\0BlobValue2\0", kBlobLen));
+ //
+ // Note that the trailing NUL is in `kBlobData` implicitly.
+ constexpr uint8_t kBlobData[] = "\x01\x02\x03\0BlobValue1\0\0\0BlobValue2";
EXPECT_EQ(0, FPDFPageObjMark_CountParams(mark));
EXPECT_TRUE(
FPDFPageObjMark_SetIntParam(document(), text_object, mark, "IntKey", 42));
EXPECT_TRUE(FPDFPageObjMark_SetStringParam(document(), text_object, mark,
"StringKey", "StringValue"));
- EXPECT_TRUE(FPDFPageObjMark_SetBlobParam(document(), text_object, mark,
- "BlobKey", block_value, kBlobLen));
+ EXPECT_TRUE(FPDFPageObjMark_SetBlobParam(
+ document(), text_object, mark, "BlobKey", kBlobData, sizeof(kBlobData)));
EXPECT_EQ(3, FPDFPageObjMark_CountParams(mark));
// Check the two parameters can be retrieved.
@@ -4074,16 +4063,19 @@
mark, "StringKey", buffer, sizeof(buffer), &out_buffer_len));
EXPECT_GT(out_buffer_len, 0u);
EXPECT_NE(999u, out_buffer_len);
- name = GetPlatformWString(reinterpret_cast<unsigned short*>(buffer));
+ name = GetPlatformWString(buffer);
EXPECT_EQ(L"StringValue", name);
EXPECT_EQ(FPDF_OBJECT_STRING,
FPDFPageObjMark_GetParamValueType(mark, "BlobKey"));
out_buffer_len = 0;
+ constexpr size_t kBlobLen = 28;
+ unsigned char blob_buffer[kBlobLen];
EXPECT_TRUE(FPDFPageObjMark_GetParamBlobValue(
- mark, "BlobKey", buffer, sizeof(buffer), &out_buffer_len));
+ mark, "BlobKey", blob_buffer, sizeof(blob_buffer), &out_buffer_len));
EXPECT_EQ(kBlobLen, out_buffer_len);
- EXPECT_EQ(0, memcmp(block_value, buffer, kBlobLen));
+ EXPECT_TRUE(fxcrt::span_equals(pdfium::make_span(kBlobData),
+ pdfium::make_span(blob_buffer)));
// Render and check the bitmap is the expected one.
{
@@ -4113,7 +4105,7 @@
name_len = 999u;
ASSERT_TRUE(FPDFPageObjMark_GetName(mark, buffer, sizeof(buffer), &name_len));
EXPECT_EQ((14u + 1u) * 2, name_len);
- name = GetPlatformWString(reinterpret_cast<unsigned short*>(buffer));
+ name = GetPlatformWString(buffer);
EXPECT_EQ(L"Test Mark Name", name);
CloseSavedPage(saved_page);
@@ -4128,7 +4120,7 @@
FPDF_PAGEOBJECTMARK mark = FPDFPageObj_GetMark(page_object, 1);
ASSERT_TRUE(mark);
- char buffer[256];
+ FPDF_WCHAR buffer[128];
unsigned long out_len;
// Show the positive cases of FPDFPageObjMark_GetName.
@@ -4138,8 +4130,7 @@
out_len = 999u;
EXPECT_TRUE(FPDFPageObjMark_GetName(mark, buffer, sizeof(buffer), &out_len));
- EXPECT_EQ(L"Bounds",
- GetPlatformWString(reinterpret_cast<unsigned short*>(buffer)));
+ EXPECT_EQ(L"Bounds", GetPlatformWString(buffer));
EXPECT_EQ((6u + 1u) * 2u, out_len);
// Show the negative cases of FPDFPageObjMark_GetName.
@@ -4159,7 +4150,7 @@
FPDF_PAGEOBJECTMARK mark = FPDFPageObj_GetMark(page_object, 1);
ASSERT_TRUE(mark);
- char buffer[256];
+ FPDF_WCHAR buffer[128];
unsigned long out_len;
// Show the positive cases of FPDFPageObjMark_GetParamKey.
@@ -4170,8 +4161,7 @@
out_len = 999u;
EXPECT_TRUE(
FPDFPageObjMark_GetParamKey(mark, 0, buffer, sizeof(buffer), &out_len));
- EXPECT_EQ(L"Position",
- GetPlatformWString(reinterpret_cast<unsigned short*>(buffer)));
+ EXPECT_EQ(L"Position", GetPlatformWString(buffer));
EXPECT_EQ((8u + 1u) * 2u, out_len);
// Show the negative cases of FPDFPageObjMark_GetParamKey.
@@ -4231,7 +4221,7 @@
FPDF_PAGEOBJECTMARK mark = FPDFPageObj_GetMark(page_object, 1);
ASSERT_TRUE(mark);
- char buffer[256];
+ FPDF_WCHAR buffer[128];
unsigned long out_len;
// Show the positive cases of FPDFPageObjMark_GetParamStringValue.
@@ -4243,8 +4233,7 @@
out_len = 999u;
EXPECT_TRUE(FPDFPageObjMark_GetParamStringValue(mark, "Position", buffer,
sizeof(buffer), &out_len));
- EXPECT_EQ(L"Last",
- GetPlatformWString(reinterpret_cast<unsigned short*>(buffer)));
+ EXPECT_EQ(L"Last", GetPlatformWString(buffer));
EXPECT_EQ((4u + 1u) * 2u, out_len);
// Show the negative cases of FPDFPageObjMark_GetParamStringValue.
diff --git a/fpdfsdk/fpdf_editpage.cpp b/fpdfsdk/fpdf_editpage.cpp
index 0309278..d41b12a 100644
--- a/fpdfsdk/fpdf_editpage.cpp
+++ b/fpdfsdk/fpdf_editpage.cpp
@@ -369,7 +369,7 @@
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
FPDFPageObjMark_GetName(FPDF_PAGEOBJECTMARK mark,
- void* buffer,
+ FPDF_WCHAR* buffer,
unsigned long buflen,
unsigned long* out_buflen) {
const CPDF_ContentMarkItem* pMarkItem =
@@ -398,7 +398,7 @@
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
FPDFPageObjMark_GetParamKey(FPDF_PAGEOBJECTMARK mark,
unsigned long index,
- void* buffer,
+ FPDF_WCHAR* buffer,
unsigned long buflen,
unsigned long* out_buflen) {
if (!out_buflen)
@@ -456,7 +456,7 @@
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
FPDFPageObjMark_GetParamStringValue(FPDF_PAGEOBJECTMARK mark,
FPDF_BYTESTRING key,
- void* buffer,
+ FPDF_WCHAR* buffer,
unsigned long buflen,
unsigned long* out_buflen) {
if (!out_buflen)
@@ -480,7 +480,7 @@
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
FPDFPageObjMark_GetParamBlobValue(FPDF_PAGEOBJECTMARK mark,
FPDF_BYTESTRING key,
- void* buffer,
+ unsigned char* buffer,
unsigned long buflen,
unsigned long* out_buflen) {
if (!out_buflen)
@@ -579,7 +579,7 @@
FPDF_PAGEOBJECT page_object,
FPDF_PAGEOBJECTMARK mark,
FPDF_BYTESTRING key,
- void* value,
+ const unsigned char* value,
unsigned long value_len) {
if (!value && value_len > 0) {
return false;
@@ -598,9 +598,7 @@
// SAFETY: required from caller.
pParams->SetNewFor<CPDF_String>(
- key,
- UNSAFE_BUFFERS(
- pdfium::make_span(static_cast<const uint8_t*>(value), value_len)),
+ key, UNSAFE_BUFFERS(pdfium::make_span(value, value_len)),
CPDF_String::DataType::kIsHex);
pPageObj->SetDirty(true);
return true;
diff --git a/public/fpdf_edit.h b/public/fpdf_edit.h
index f4e08c7..6ab72cb 100644
--- a/public/fpdf_edit.h
+++ b/public/fpdf_edit.h
@@ -424,17 +424,18 @@
//
// mark - handle to a content mark.
// buffer - buffer for holding the returned name in UTF-16LE. This is only
-// modified if |buflen| is longer than the length of the name.
+// modified if |buflen| is large enough to store the name.
// Optional, pass null to just retrieve the size of the buffer
// needed.
-// buflen - length of the buffer.
+// buflen - length of the buffer in bytes.
// out_buflen - pointer to variable that will receive the minimum buffer size
-// to contain the name. Not filled if FALSE is returned.
+// in bytes to contain the name. This is a required parameter.
+// Not filled if FALSE is returned.
//
// Returns TRUE if the operation succeeded, FALSE if it failed.
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
FPDFPageObjMark_GetName(FPDF_PAGEOBJECTMARK mark,
- void* buffer,
+ FPDF_WCHAR* buffer,
unsigned long buflen,
unsigned long* out_buflen);
@@ -454,18 +455,19 @@
// mark - handle to a content mark.
// index - index of the property.
// buffer - buffer for holding the returned key in UTF-16LE. This is only
-// modified if |buflen| is longer than the length of the key.
+// modified if |buflen| is large enough to store the key.
// Optional, pass null to just retrieve the size of the buffer
// needed.
-// buflen - length of the buffer.
+// buflen - length of the buffer in bytes.
// out_buflen - pointer to variable that will receive the minimum buffer size
-// to contain the key. Not filled if FALSE is returned.
+// in bytes to contain the name. This is a required parameter.
+// Not filled if FALSE is returned.
//
// Returns TRUE if the operation was successful, FALSE otherwise.
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
FPDFPageObjMark_GetParamKey(FPDF_PAGEOBJECTMARK mark,
unsigned long index,
- void* buffer,
+ FPDF_WCHAR* buffer,
unsigned long buflen,
unsigned long* out_buflen);
@@ -502,19 +504,19 @@
// mark - handle to a content mark.
// key - string key of the property.
// buffer - buffer for holding the returned value in UTF-16LE. This is
-// only modified if |buflen| is longer than the length of the
-// value.
+// only modified if |buflen| is large enough to store the value.
// Optional, pass null to just retrieve the size of the buffer
// needed.
-// buflen - length of the buffer.
+// buflen - length of the buffer in bytes.
// out_buflen - pointer to variable that will receive the minimum buffer size
-// to contain the value. Not filled if FALSE is returned.
+// in bytes to contain the name. This is a required parameter.
+// 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_GetParamStringValue(FPDF_PAGEOBJECTMARK mark,
FPDF_BYTESTRING key,
- void* buffer,
+ FPDF_WCHAR* buffer,
unsigned long buflen,
unsigned long* out_buflen);
@@ -524,18 +526,19 @@
// mark - handle to a content mark.
// key - string key of the property.
// buffer - buffer for holding the returned value. This is only modified
-// if |buflen| is at least as long as the length of the value.
+// if |buflen| is large enough to store the value.
// Optional, pass null to just retrieve the size of the buffer
// needed.
-// buflen - length of the buffer.
+// buflen - length of the buffer in bytes.
// out_buflen - pointer to variable that will receive the minimum buffer size
-// to contain the value. Not filled if FALSE is returned.
+// in bytes to contain the name. This is a required parameter.
+// 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 char* buffer,
unsigned long buflen,
unsigned long* out_buflen);
@@ -595,7 +598,7 @@
FPDF_PAGEOBJECT page_object,
FPDF_PAGEOBJECTMARK mark,
FPDF_BYTESTRING key,
- void* value,
+ const unsigned char* value,
unsigned long value_len);
// Experimental API.