From bef2c2222a0b9429276b34d8f5024f31b8e86495 Mon Sep 17 00:00:00 2001 From: Jay Berkenbilt Date: Thu, 2 Dec 2021 07:54:33 -0500 Subject: [PATCH] C API: qpdf_get_last_string_length --- ChangeLog | 6 ++++++ TODO | 6 ------ include/qpdf/qpdf-c.h | 23 +++++++++++++++++------ libqpdf/qpdf-c.cc | 5 +++++ manual/qpdf-manual.xml | 22 ++++++++++++++++++++++ qpdf/qpdf-ctest.c | 7 +++++++ 6 files changed, 57 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0d1ed3d9..201b5465 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2021-12-02 Jay Berkenbilt + + * C API: Add qpdf_get_last_string_length to return the length of + the last string returned. This is necessary in order to fully + retrieve values of strings that may contain embedded null characters. + 2021-11-16 Jay Berkenbilt * 10.4.0: release diff --git a/TODO b/TODO index 4bc8cf92..47c6644c 100644 --- a/TODO +++ b/TODO @@ -1,9 +1,3 @@ -Next -==== - -* Add a method to the C API that returns the length of tmp_str so that - we can handle strings with embedded null characters. - Documentation ============= diff --git a/include/qpdf/qpdf-c.h b/include/qpdf/qpdf-c.h index 0e5071cb..16d1ba64 100644 --- a/include/qpdf/qpdf-c.h +++ b/include/qpdf/qpdf-c.h @@ -49,14 +49,17 @@ * itself, is managed by the library. You must create a qpdf_data * object using qpdf_init and free it using qpdf_cleanup. * - * Many functions return char*. In all cases, the char* values - * returned are pointers to data inside the qpdf_data object. As - * such, they are always freed by qpdf_cleanup. In most cases, + * Many functions return char*. In all cases, the char* values + * returned are pointers to data inside the qpdf_data object. As + * such, they are always freed by qpdf_cleanup. In most cases, * strings returned by functions here may be invalidated by * subsequent function calls, sometimes even to different - * functions. If you want a string to last past the next qpdf - * call or after a call to qpdf_cleanup, you should make a copy of - * it. + * functions. If you want a string to last past the next qpdf call + * or after a call to qpdf_cleanup, you should make a copy of it. + * It is possible for the internal string data to contain null + * characters. To handle that case, you call + * qpdf_get_last_string_length() to get the length of whatever + * string was just returned. * * Many functions defined here merely set parameters and therefore * never return error conditions. Functions that may cause PDF @@ -126,6 +129,14 @@ extern "C" { QPDF_DLL void qpdf_cleanup(qpdf_data* qpdf); + /* Return the length of the last string returned. This enables you + * to retrieve the entire string for cases in which a char* + * returned by one of the functions below points to a string with + * embedded null characters. + */ + QPDF_DLL + size_t qpdf_get_last_string_length(qpdf_data qpdf); + /* ERROR REPORTING */ /* Returns 1 if there is an error condition. The error condition diff --git a/libqpdf/qpdf-c.cc b/libqpdf/qpdf-c.cc index fa6d46d6..618b926d 100644 --- a/libqpdf/qpdf-c.cc +++ b/libqpdf/qpdf-c.cc @@ -172,6 +172,11 @@ void qpdf_cleanup(qpdf_data* qpdf) *qpdf = 0; } +size_t qpdf_get_last_string_length(qpdf_data qpdf) +{ + return qpdf->tmp_string.length(); +} + QPDF_BOOL qpdf_more_warnings(qpdf_data qpdf) { QTC::TC("qpdf", "qpdf-c called qpdf_more_warnings"); diff --git a/manual/qpdf-manual.xml b/manual/qpdf-manual.xml index 853e114b..217542b8 100644 --- a/manual/qpdf-manual.xml +++ b/manual/qpdf-manual.xml @@ -5116,6 +5116,28 @@ print "\n"; --> + + 10.5.0: XXX Month dd, YYYY + + + + + Library Enhancements + + + + + Add qpdf_get_last_string_length to the + C API to get the length of the last string that was + returned. This is needed to handle strings that contain + embedded null characters. + + + + + + + 10.4.0: November 16, 2021 diff --git a/qpdf/qpdf-ctest.c b/qpdf/qpdf-ctest.c index f5160f84..a57ea44f 100644 --- a/qpdf/qpdf-ctest.c +++ b/qpdf/qpdf-ctest.c @@ -613,6 +613,13 @@ static void test24(char const* infile, (strcmp(qpdf_oh_get_string_value(qpdf, p_string), "3\xf7") == 0) && (strcmp(qpdf_oh_get_utf8_value(qpdf, p_string), "3\xc3\xb7") == 0) && (strcmp(qpdf_oh_unparse_binary(qpdf, p_string), "<33f7>") == 0)); + qpdf_oh p_string_with_null = qpdf_oh_parse(qpdf, "<6f6e650074776f>"); + assert(qpdf_oh_is_string(qpdf, p_string_with_null) && + (strcmp(qpdf_oh_get_string_value(qpdf, p_string_with_null), + "one") == 0) && + (qpdf_get_last_string_length(qpdf) == 7) && + (memcmp(qpdf_oh_get_string_value(qpdf, p_string_with_null), + "one\000two", 7) == 0)); assert(qpdf_oh_is_dictionary(qpdf, p_dict)); qpdf_oh p_five = qpdf_oh_get_key(qpdf, p_dict, "/Four"); assert(qpdf_oh_is_or_has_name(qpdf, p_five, "/Five"));