Commit 4630b8567c853e0a05d41f15b701c370f660250f
1 parent
ce7db05d
Ensure qpdf_oh handles returned by C-API functions are unique.
Return new qpdf_oh from qpdf_oh_wrap_in_array when input is already an array. Update some doc comments in qpdf-c.h.
Showing
3 changed files
with
26 additions
and
20 deletions
include/qpdf/qpdf-c.h
| @@ -134,7 +134,7 @@ extern "C" { | @@ -134,7 +134,7 @@ extern "C" { | ||
| 134 | 134 | ||
| 135 | /* Returns the error condition, if any. The return value is a | 135 | /* Returns the error condition, if any. The return value is a |
| 136 | * pointer to data that will become invalid after the next call to | 136 | * pointer to data that will become invalid after the next call to |
| 137 | - * this function, qpdf_next_warning, or qpdf_destroy. After this | 137 | + * this function, qpdf_next_warning, or qpdf_cleanup. After this |
| 138 | * function is called, qpdf_has_error will return QPDF_FALSE until | 138 | * function is called, qpdf_has_error will return QPDF_FALSE until |
| 139 | * the next error condition occurs. If there is no error | 139 | * the next error condition occurs. If there is no error |
| 140 | * condition, this function returns a null pointer. | 140 | * condition, this function returns a null pointer. |
| @@ -201,7 +201,7 @@ extern "C" { | @@ -201,7 +201,7 @@ extern "C" { | ||
| 201 | /* Calling qpdf_read causes processFile to be called in the C++ | 201 | /* Calling qpdf_read causes processFile to be called in the C++ |
| 202 | * API. Basic parsing is performed, but data from the file is | 202 | * API. Basic parsing is performed, but data from the file is |
| 203 | * only read as needed. For files without passwords, pass a null | 203 | * only read as needed. For files without passwords, pass a null |
| 204 | - * pointer as the password. | 204 | + * pointer or an empty string as the password. |
| 205 | */ | 205 | */ |
| 206 | QPDF_DLL | 206 | QPDF_DLL |
| 207 | QPDF_ERROR_CODE qpdf_read(qpdf_data qpdf, char const* filename, | 207 | QPDF_ERROR_CODE qpdf_read(qpdf_data qpdf, char const* filename, |
| @@ -489,16 +489,19 @@ extern "C" { | @@ -489,16 +489,19 @@ extern "C" { | ||
| 489 | 489 | ||
| 490 | /* Object handling. | 490 | /* Object handling. |
| 491 | * | 491 | * |
| 492 | - * These methods take and return a qpdf_oh, which is just an | ||
| 493 | - * unsigned integer. The value 0 is never returned, which makes it | ||
| 494 | - * usable as an uninitialized value. | 492 | + * These functions take and return a qpdf_oh object handle, which |
| 493 | + * is just an unsigned integer. The value 0 is never returned, which | ||
| 494 | + * makes it usable as an uninitialized value. The handles returned by | ||
| 495 | + * these functions are guaranteed to be unique, i.e. two calls to | ||
| 496 | + * (the same of different) functions will return distinct handles | ||
| 497 | + * even when they refer to the same object. | ||
| 495 | * | 498 | * |
| 496 | * Each function below, starting with qpdf_oh, corresponds to a | 499 | * Each function below, starting with qpdf_oh, corresponds to a |
| 497 | * specific method of QPDFObjectHandler. For example, | 500 | * specific method of QPDFObjectHandler. For example, |
| 498 | * qpdf_oh_is_bool corresponds to QPDFObjectHandle::isBool. If the | 501 | * qpdf_oh_is_bool corresponds to QPDFObjectHandle::isBool. If the |
| 499 | * C++ method is overloaded, the C function's name will be | 502 | * C++ method is overloaded, the C function's name will be |
| 500 | * disambiguated. If the C++ method takes optional argumens, the C | 503 | * disambiguated. If the C++ method takes optional argumens, the C |
| 501 | - * method will have required arguments in those positions. For | 504 | + * function will have required arguments in those positions. For |
| 502 | * details about the method, please see comments in | 505 | * details about the method, please see comments in |
| 503 | * QPDFObjectHandle.hh. Comments here only explain things that are | 506 | * QPDFObjectHandle.hh. Comments here only explain things that are |
| 504 | * specific to the "C" API. | 507 | * specific to the "C" API. |
| @@ -514,25 +517,26 @@ extern "C" { | @@ -514,25 +517,26 @@ extern "C" { | ||
| 514 | * To refer to a specific QPDFObjectHandle, you need a pair | 517 | * To refer to a specific QPDFObjectHandle, you need a pair |
| 515 | * consisting of a qpdf_data and a qpdf_oh, which is just an index | 518 | * consisting of a qpdf_data and a qpdf_oh, which is just an index |
| 516 | * into an internal table of objects. All memory allocated by any | 519 | * into an internal table of objects. All memory allocated by any |
| 517 | - * of these methods is returned when qpdf_cleanup is called. | 520 | + * of these functions is returned when qpdf_cleanup is called. |
| 518 | * | 521 | * |
| 519 | * Regarding memory, the same rules apply as the above functions. | 522 | * Regarding memory, the same rules apply as the above functions. |
| 520 | - * Specifically, if a method returns a char*, the memory is | 523 | + * Specifically, if a function returns a char*, the memory is |
| 521 | * managed by the library and, unless otherwise specified, is not | 524 | * managed by the library and, unless otherwise specified, is not |
| 522 | * expected to be valid after the next qpdf call. | 525 | * expected to be valid after the next qpdf call. |
| 523 | * | 526 | * |
| 524 | - * The qpdf_data object keeps a cache of objects returned by these | ||
| 525 | - * methods. Once you are finished referencing an object, you can | ||
| 526 | - * optionally release it. Releasing objects is optional since they | 527 | + * The qpdf_data object keeps a cache of handles returned by these |
| 528 | + * functions. Once you are finished referencing an handle, you can | ||
| 529 | + * optionally release it. Releasing handles is optional since they | ||
| 527 | * will all get released by qpdf_cleanup, but it can help to | 530 | * will all get released by qpdf_cleanup, but it can help to |
| 528 | * reduce the memory footprint of the qpdf_data object to release | 531 | * reduce the memory footprint of the qpdf_data object to release |
| 529 | - * them when you're done. Releasing an object does not destroy the | 532 | + * them when you're done. Releasing a handle does not destroy the |
| 530 | * object. All QPDFObjectHandle objects are deleted when they are | 533 | * object. All QPDFObjectHandle objects are deleted when they are |
| 531 | - * no longer referenced. Releasing an object simply invalidates | ||
| 532 | - * the qpdf_oh handle to it. For example, if you create an object, | ||
| 533 | - * add it to an existing dictionary or array, and then release it, | ||
| 534 | - * the object is safely part of the dictionary or array. | ||
| 535 | - * Explicitly releasing an object is essentially the same as | 534 | + * no longer referenced. Releasing an object handle simply |
| 535 | + * invalidates it. For example, if you create an object, | ||
| 536 | + * add it to an existing dictionary or array, and then release it's | ||
| 537 | + * handle, the object is safely part of the dictionary or array. | ||
| 538 | + * Similarly, any other object handle refering to the object remains | ||
| 539 | + * valid. Explicitly releasing an object is essentially the same as | ||
| 536 | * letting a QPDFObjectHandle go out of scope in the C++ API. | 540 | * letting a QPDFObjectHandle go out of scope in the C++ API. |
| 537 | */ | 541 | */ |
| 538 | 542 | ||
| @@ -540,7 +544,7 @@ extern "C" { | @@ -540,7 +544,7 @@ extern "C" { | ||
| 540 | 544 | ||
| 541 | typedef unsigned int qpdf_oh; | 545 | typedef unsigned int qpdf_oh; |
| 542 | 546 | ||
| 543 | - /* Releasing objects -- see comments above. These methods have no | 547 | + /* Releasing objects -- see comments above. These functions have no |
| 544 | * equivalent in the C++ API. | 548 | * equivalent in the C++ API. |
| 545 | */ | 549 | */ |
| 546 | QPDF_DLL | 550 | QPDF_DLL |
libqpdf/qpdf-c.cc
| @@ -987,7 +987,7 @@ qpdf_oh qpdf_oh_wrap_in_array(qpdf_data qpdf, qpdf_oh oh) | @@ -987,7 +987,7 @@ qpdf_oh qpdf_oh_wrap_in_array(qpdf_data qpdf, qpdf_oh oh) | ||
| 987 | if (qoh->isArray()) | 987 | if (qoh->isArray()) |
| 988 | { | 988 | { |
| 989 | QTC::TC("qpdf", "qpdf-c array to wrap_in_array"); | 989 | QTC::TC("qpdf", "qpdf-c array to wrap_in_array"); |
| 990 | - return oh; | 990 | + return new_object(qpdf, *qoh); |
| 991 | } | 991 | } |
| 992 | else | 992 | else |
| 993 | { | 993 | { |
qpdf/qpdf-ctest.c
| @@ -530,7 +530,9 @@ static void test24(char const* infile, | @@ -530,7 +530,9 @@ static void test24(char const* infile, | ||
| 530 | assert(! qpdf_oh_is_scalar(qpdf, mediabox)); | 530 | assert(! qpdf_oh_is_scalar(qpdf, mediabox)); |
| 531 | assert(qpdf_oh_is_array(qpdf, mediabox)); | 531 | assert(qpdf_oh_is_array(qpdf, mediabox)); |
| 532 | assert(qpdf_oh_get_array_n_items(qpdf, mediabox) == 4); | 532 | assert(qpdf_oh_get_array_n_items(qpdf, mediabox) == 4); |
| 533 | - assert(qpdf_oh_wrap_in_array(qpdf, mediabox) == mediabox); | 533 | + qpdf_oh wrapped_mediabox = qpdf_oh_wrap_in_array(qpdf, mediabox); |
| 534 | + assert(wrapped_mediabox != mediabox); | ||
| 535 | + assert(qpdf_oh_get_array_n_items(qpdf, wrapped_mediabox) == 4); | ||
| 534 | for (int i = 0; i < 4; ++i) | 536 | for (int i = 0; i < 4; ++i) |
| 535 | { | 537 | { |
| 536 | qpdf_oh item = qpdf_oh_get_array_item(qpdf, mediabox, i); | 538 | qpdf_oh item = qpdf_oh_get_array_item(qpdf, mediabox, i); |