Add QUtil::make_shared_cstr

Replace most of the calls to QUtil::copy_string with this instead.
This commit is contained in:
Jay Berkenbilt 2022-01-22 17:33:53 -05:00
parent 67f9d0b7d5
commit 76c4f78b5c
7 changed files with 41 additions and 9 deletions

View File

@ -1,5 +1,8 @@
2022-01-22 Jay Berkenbilt <ejb@ql.org>
* Add QUtil::make_shared_cstr to return a std::shared_ptr<char>
instead of a char* like QUtil::copy_string
* JSON: for (qpdf-specific, not official) "schema" checking, add
the ability to treat missing fields as optional. Also ensure that
values in the schema are dictionary, array, or string.

View File

@ -30,6 +30,7 @@
#include <vector>
#include <stdexcept>
#include <functional>
#include <memory>
#include <stdio.h>
#include <time.h>
@ -151,9 +152,15 @@ namespace QUtil
QPDF_DLL
std::string path_basename(std::string const& filename);
// Returns a dynamically allocated copy of a string that the
// caller has to delete with delete[].
QPDF_DLL
char* copy_string(std::string const&);
// Returns a shared_ptr<char> with the correct deleter.
QPDF_DLL
std::shared_ptr<char> make_shared_cstr(std::string const&);
// Returns lower-case hex-encoded version of the string, treating
// each character in the input string as unsigned. The output
// string will be twice as long as the input string.

View File

@ -1915,9 +1915,8 @@ QPDFWriter::unparseObject(QPDFObjectHandle object, int level,
}
else
{
PointerHolder<char> tmp_ph =
PointerHolder<char>(true, QUtil::copy_string(val));
char* tmp = tmp_ph.getPointer();
auto tmp_ph = QUtil::make_shared_cstr(val);
char* tmp = tmp_ph.get();
size_t vlen = val.length();
RC4 rc4(QUtil::unsigned_char_pointer(this->m->cur_data_key),
QIntC::to_int(this->m->cur_data_key.length()));

View File

@ -1211,10 +1211,10 @@ QPDF::decryptString(std::string& str, int objid, int generation)
size_t vlen = str.length();
// Using PointerHolder guarantees that tmp will
// be freed even if rc4.process throws an exception.
PointerHolder<char> tmp(true, QUtil::copy_string(str));
auto tmp = QUtil::make_shared_cstr(str);
RC4 rc4(QUtil::unsigned_char_pointer(key), toI(key.length()));
rc4.process(QUtil::unsigned_char_pointer(tmp.getPointer()), vlen);
str = std::string(tmp.getPointer(), vlen);
rc4.process(QUtil::unsigned_char_pointer(tmp.get()), vlen);
str = std::string(tmp.get(), vlen);
}
}
catch (QPDFExc&)

View File

@ -731,6 +731,18 @@ QUtil::copy_string(std::string const& str)
return result;
}
std::shared_ptr<char>
QUtil::make_shared_cstr(std::string const& str)
{
auto result = std::shared_ptr<char>(
new char[str.length() + 1],
std::default_delete<char[]>());
// Use memcpy in case string contains nulls
result.get()[str.length()] = '\0';
memcpy(result.get(), str.c_str(), str.length());
return result;
}
std::string
QUtil::hex_encode(std::string const& input)
{
@ -2625,7 +2637,7 @@ QUtil::call_main_from_wmain(int argc, wchar_t* argv[],
QIntC::to_uchar(codepoint & 0xff)));
}
std::string utf8 = QUtil::utf16_to_utf8(utf16);
utf8_argv.push_back(std::shared_ptr<char>(QUtil::copy_string(utf8.c_str()), std::default_delete<char[]>()));
utf8_argv.push_back(QUtil::make_shared_cstr(utf8));
}
auto utf8_argv_sp =
std::shared_ptr<char*>(new char*[1+utf8_argv.size()], std::default_delete<char*[]>());

View File

@ -22,6 +22,7 @@
one
7
compare okay
compare okay
-2147483648 to int: PASSED
2147483647 to int: PASSED
2147483648 to int threw (integer out of range converting 2147483648 from a 8-byte signed type to a 4-byte signed type): PASSED

View File

@ -150,6 +150,16 @@ void string_conversion_test()
std::cout << "compare failed" << std::endl;
}
delete [] tmp;
// Also test with make_shared_cstr
auto tmp2 = QUtil::make_shared_cstr(embedded_null);
if (memcmp(tmp2.get(), embedded_null.c_str(), 7) == 0)
{
std::cout << "compare okay" << std::endl;
}
else
{
std::cout << "compare failed" << std::endl;
}
std::string int_max_str = QUtil::int_to_string(INT_MAX);
std::string int_min_str = QUtil::int_to_string(INT_MIN);
@ -407,8 +417,8 @@ void transcoding_test()
void print_whoami(char const* str)
{
PointerHolder<char> dup(true, QUtil::copy_string(str));
std::cout << QUtil::getWhoami(dup.getPointer()) << std::endl;
auto dup = QUtil::make_shared_cstr(str);
std::cout << QUtil::getWhoami(dup.get()) << std::endl;
}
void get_whoami_test()