From 8c1cde4ec3f060ef0ddeff634ce7aaa645044fd6 Mon Sep 17 00:00:00 2001 From: "Chao Li(VISION)" Date: Thu, 19 Sep 2024 12:18:26 +0000 Subject: [PATCH] Add C API qpdf_free_buffer to release memory allocated by stream data functions --- include/qpdf/qpdf-c.h | 8 ++++++++ libqpdf/qpdf-c.cc | 10 ++++++++++ qpdf/qpdf-ctest.c | 6 +++--- qpdf/qpdf.testcov | 1 + 4 files changed, 22 insertions(+), 3 deletions(-) diff --git a/include/qpdf/qpdf-c.h b/include/qpdf/qpdf-c.h index fba952f2..d6428a20 100644 --- a/include/qpdf/qpdf-c.h +++ b/include/qpdf/qpdf-c.h @@ -927,6 +927,14 @@ extern "C" { QPDF_ERROR_CODE qpdf_oh_get_page_content_data( qpdf_data qpdf, qpdf_oh page_oh, unsigned char** bufp, size_t* len); + /* Call free to release the buffer allocated with malloc. This function can be used to free + * buffers that were dynamically allocated by qpdf functions such as qpdf_oh_get_stream_data + * or qpdf_oh_get_page_content_data. The caller is responsible for calling qpdf_free_buffer + * to manage memory properly and avoid memory leaks. + */ + QPDF_DLL + void qpdf_free_buffer(unsigned char** bufp); + /* The data pointed to by bufp will be copied by the library. It does not need to remain valid * after the call returns. */ diff --git a/libqpdf/qpdf-c.cc b/libqpdf/qpdf-c.cc index e2b9d821..9b04ad68 100644 --- a/libqpdf/qpdf-c.cc +++ b/libqpdf/qpdf-c.cc @@ -1771,6 +1771,16 @@ qpdf_oh_get_page_content_data(qpdf_data qpdf, qpdf_oh page_oh, unsigned char** b }); } +void +qpdf_free_buffer(unsigned char** bufp) +{ + QTC::TC("qpdf", "qpdf-c called qpdf_free_buffer"); + if (bufp && *bufp) { + free(*bufp); + *bufp = nullptr; + } +} + void qpdf_oh_replace_stream_data( qpdf_data qpdf, diff --git a/qpdf/qpdf-ctest.c b/qpdf/qpdf-ctest.c index d0c60558..69b4dcde 100644 --- a/qpdf/qpdf-ctest.c +++ b/qpdf/qpdf-ctest.c @@ -1151,7 +1151,7 @@ test38(char const* infile, char const* password, char const* outfile, char const assert(qpdf_oh_get_stream_data(qpdf, stream, qpdf_dl_none, 0, &buf, &len) == 0); assert(len == 53); assert(((int)buf[0] == 'x') && ((int)buf[1] == 0234)); - free(buf); + qpdf_free_buffer(&buf); /* Test whether filterable */ QPDF_BOOL filtered = QPDF_FALSE; @@ -1169,8 +1169,8 @@ test38(char const* infile, char const* password, char const* outfile, char const assert(qpdf_oh_get_page_content_data(qpdf, page2, &buf2, &len) == 0); assert(len == 47); assert(memcmp(buf, buf2, len) == 0); - free(buf); - free(buf2); + qpdf_free_buffer(&buf); + qpdf_free_buffer(&buf2); /* errors */ printf("page content on broken page\n"); diff --git a/qpdf/qpdf.testcov b/qpdf/qpdf.testcov index b66ba83f..104e40bb 100644 --- a/qpdf/qpdf.testcov +++ b/qpdf/qpdf.testcov @@ -626,6 +626,7 @@ qpdf-c stream data filtered set 1 qpdf-c stream data buf set 1 qpdf-c called qpdf_oh_get_page_content_data 0 qpdf-c called qpdf_oh_replace_stream_data 0 +qpdf-c called qpdf_free_buffer 0 qpdf-c silence oh errors 0 qpdf-c called qpdf_oh_get_binary_string_value 0 qpdf-c called qpdf_oh_get_binary_utf8_value 0