Commit 76c4f78b5cfd786b90069f7256252229444fdecd
1 parent
67f9d0b7
Add QUtil::make_shared_cstr
Replace most of the calls to QUtil::copy_string with this instead.
Showing
7 changed files
with
41 additions
and
9 deletions
ChangeLog
| 1 | 2022-01-22 Jay Berkenbilt <ejb@ql.org> | 1 | 2022-01-22 Jay Berkenbilt <ejb@ql.org> |
| 2 | 2 | ||
| 3 | + * Add QUtil::make_shared_cstr to return a std::shared_ptr<char> | ||
| 4 | + instead of a char* like QUtil::copy_string | ||
| 5 | + | ||
| 3 | * JSON: for (qpdf-specific, not official) "schema" checking, add | 6 | * JSON: for (qpdf-specific, not official) "schema" checking, add |
| 4 | the ability to treat missing fields as optional. Also ensure that | 7 | the ability to treat missing fields as optional. Also ensure that |
| 5 | values in the schema are dictionary, array, or string. | 8 | values in the schema are dictionary, array, or string. |
include/qpdf/QUtil.hh
| @@ -30,6 +30,7 @@ | @@ -30,6 +30,7 @@ | ||
| 30 | #include <vector> | 30 | #include <vector> |
| 31 | #include <stdexcept> | 31 | #include <stdexcept> |
| 32 | #include <functional> | 32 | #include <functional> |
| 33 | +#include <memory> | ||
| 33 | #include <stdio.h> | 34 | #include <stdio.h> |
| 34 | #include <time.h> | 35 | #include <time.h> |
| 35 | 36 | ||
| @@ -151,9 +152,15 @@ namespace QUtil | @@ -151,9 +152,15 @@ namespace QUtil | ||
| 151 | QPDF_DLL | 152 | QPDF_DLL |
| 152 | std::string path_basename(std::string const& filename); | 153 | std::string path_basename(std::string const& filename); |
| 153 | 154 | ||
| 155 | + // Returns a dynamically allocated copy of a string that the | ||
| 156 | + // caller has to delete with delete[]. | ||
| 154 | QPDF_DLL | 157 | QPDF_DLL |
| 155 | char* copy_string(std::string const&); | 158 | char* copy_string(std::string const&); |
| 156 | 159 | ||
| 160 | + // Returns a shared_ptr<char> with the correct deleter. | ||
| 161 | + QPDF_DLL | ||
| 162 | + std::shared_ptr<char> make_shared_cstr(std::string const&); | ||
| 163 | + | ||
| 157 | // Returns lower-case hex-encoded version of the string, treating | 164 | // Returns lower-case hex-encoded version of the string, treating |
| 158 | // each character in the input string as unsigned. The output | 165 | // each character in the input string as unsigned. The output |
| 159 | // string will be twice as long as the input string. | 166 | // string will be twice as long as the input string. |
libqpdf/QPDFWriter.cc
| @@ -1915,9 +1915,8 @@ QPDFWriter::unparseObject(QPDFObjectHandle object, int level, | @@ -1915,9 +1915,8 @@ QPDFWriter::unparseObject(QPDFObjectHandle object, int level, | ||
| 1915 | } | 1915 | } |
| 1916 | else | 1916 | else |
| 1917 | { | 1917 | { |
| 1918 | - PointerHolder<char> tmp_ph = | ||
| 1919 | - PointerHolder<char>(true, QUtil::copy_string(val)); | ||
| 1920 | - char* tmp = tmp_ph.getPointer(); | 1918 | + auto tmp_ph = QUtil::make_shared_cstr(val); |
| 1919 | + char* tmp = tmp_ph.get(); | ||
| 1921 | size_t vlen = val.length(); | 1920 | size_t vlen = val.length(); |
| 1922 | RC4 rc4(QUtil::unsigned_char_pointer(this->m->cur_data_key), | 1921 | RC4 rc4(QUtil::unsigned_char_pointer(this->m->cur_data_key), |
| 1923 | QIntC::to_int(this->m->cur_data_key.length())); | 1922 | QIntC::to_int(this->m->cur_data_key.length())); |
libqpdf/QPDF_encryption.cc
| @@ -1211,10 +1211,10 @@ QPDF::decryptString(std::string& str, int objid, int generation) | @@ -1211,10 +1211,10 @@ QPDF::decryptString(std::string& str, int objid, int generation) | ||
| 1211 | size_t vlen = str.length(); | 1211 | size_t vlen = str.length(); |
| 1212 | // Using PointerHolder guarantees that tmp will | 1212 | // Using PointerHolder guarantees that tmp will |
| 1213 | // be freed even if rc4.process throws an exception. | 1213 | // be freed even if rc4.process throws an exception. |
| 1214 | - PointerHolder<char> tmp(true, QUtil::copy_string(str)); | 1214 | + auto tmp = QUtil::make_shared_cstr(str); |
| 1215 | RC4 rc4(QUtil::unsigned_char_pointer(key), toI(key.length())); | 1215 | RC4 rc4(QUtil::unsigned_char_pointer(key), toI(key.length())); |
| 1216 | - rc4.process(QUtil::unsigned_char_pointer(tmp.getPointer()), vlen); | ||
| 1217 | - str = std::string(tmp.getPointer(), vlen); | 1216 | + rc4.process(QUtil::unsigned_char_pointer(tmp.get()), vlen); |
| 1217 | + str = std::string(tmp.get(), vlen); | ||
| 1218 | } | 1218 | } |
| 1219 | } | 1219 | } |
| 1220 | catch (QPDFExc&) | 1220 | catch (QPDFExc&) |
libqpdf/QUtil.cc
| @@ -731,6 +731,18 @@ QUtil::copy_string(std::string const& str) | @@ -731,6 +731,18 @@ QUtil::copy_string(std::string const& str) | ||
| 731 | return result; | 731 | return result; |
| 732 | } | 732 | } |
| 733 | 733 | ||
| 734 | +std::shared_ptr<char> | ||
| 735 | +QUtil::make_shared_cstr(std::string const& str) | ||
| 736 | +{ | ||
| 737 | + auto result = std::shared_ptr<char>( | ||
| 738 | + new char[str.length() + 1], | ||
| 739 | + std::default_delete<char[]>()); | ||
| 740 | + // Use memcpy in case string contains nulls | ||
| 741 | + result.get()[str.length()] = '\0'; | ||
| 742 | + memcpy(result.get(), str.c_str(), str.length()); | ||
| 743 | + return result; | ||
| 744 | +} | ||
| 745 | + | ||
| 734 | std::string | 746 | std::string |
| 735 | QUtil::hex_encode(std::string const& input) | 747 | QUtil::hex_encode(std::string const& input) |
| 736 | { | 748 | { |
| @@ -2625,7 +2637,7 @@ QUtil::call_main_from_wmain(int argc, wchar_t* argv[], | @@ -2625,7 +2637,7 @@ QUtil::call_main_from_wmain(int argc, wchar_t* argv[], | ||
| 2625 | QIntC::to_uchar(codepoint & 0xff))); | 2637 | QIntC::to_uchar(codepoint & 0xff))); |
| 2626 | } | 2638 | } |
| 2627 | std::string utf8 = QUtil::utf16_to_utf8(utf16); | 2639 | std::string utf8 = QUtil::utf16_to_utf8(utf16); |
| 2628 | - utf8_argv.push_back(std::shared_ptr<char>(QUtil::copy_string(utf8.c_str()), std::default_delete<char[]>())); | 2640 | + utf8_argv.push_back(QUtil::make_shared_cstr(utf8)); |
| 2629 | } | 2641 | } |
| 2630 | auto utf8_argv_sp = | 2642 | auto utf8_argv_sp = |
| 2631 | std::shared_ptr<char*>(new char*[1+utf8_argv.size()], std::default_delete<char*[]>()); | 2643 | std::shared_ptr<char*>(new char*[1+utf8_argv.size()], std::default_delete<char*[]>()); |
libtests/qtest/qutil/qutil.out
| @@ -22,6 +22,7 @@ | @@ -22,6 +22,7 @@ | ||
| 22 | one | 22 | one |
| 23 | 7 | 23 | 7 |
| 24 | compare okay | 24 | compare okay |
| 25 | +compare okay | ||
| 25 | -2147483648 to int: PASSED | 26 | -2147483648 to int: PASSED |
| 26 | 2147483647 to int: PASSED | 27 | 2147483647 to int: PASSED |
| 27 | 2147483648 to int threw (integer out of range converting 2147483648 from a 8-byte signed type to a 4-byte signed type): PASSED | 28 | 2147483648 to int threw (integer out of range converting 2147483648 from a 8-byte signed type to a 4-byte signed type): PASSED |
libtests/qutil.cc
| @@ -150,6 +150,16 @@ void string_conversion_test() | @@ -150,6 +150,16 @@ void string_conversion_test() | ||
| 150 | std::cout << "compare failed" << std::endl; | 150 | std::cout << "compare failed" << std::endl; |
| 151 | } | 151 | } |
| 152 | delete [] tmp; | 152 | delete [] tmp; |
| 153 | + // Also test with make_shared_cstr | ||
| 154 | + auto tmp2 = QUtil::make_shared_cstr(embedded_null); | ||
| 155 | + if (memcmp(tmp2.get(), embedded_null.c_str(), 7) == 0) | ||
| 156 | + { | ||
| 157 | + std::cout << "compare okay" << std::endl; | ||
| 158 | + } | ||
| 159 | + else | ||
| 160 | + { | ||
| 161 | + std::cout << "compare failed" << std::endl; | ||
| 162 | + } | ||
| 153 | 163 | ||
| 154 | std::string int_max_str = QUtil::int_to_string(INT_MAX); | 164 | std::string int_max_str = QUtil::int_to_string(INT_MAX); |
| 155 | std::string int_min_str = QUtil::int_to_string(INT_MIN); | 165 | std::string int_min_str = QUtil::int_to_string(INT_MIN); |
| @@ -407,8 +417,8 @@ void transcoding_test() | @@ -407,8 +417,8 @@ void transcoding_test() | ||
| 407 | 417 | ||
| 408 | void print_whoami(char const* str) | 418 | void print_whoami(char const* str) |
| 409 | { | 419 | { |
| 410 | - PointerHolder<char> dup(true, QUtil::copy_string(str)); | ||
| 411 | - std::cout << QUtil::getWhoami(dup.getPointer()) << std::endl; | 420 | + auto dup = QUtil::make_shared_cstr(str); |
| 421 | + std::cout << QUtil::getWhoami(dup.get()) << std::endl; | ||
| 412 | } | 422 | } |
| 413 | 423 | ||
| 414 | void get_whoami_test() | 424 | void get_whoami_test() |