mirror of
https://github.com/qpdf/qpdf.git
synced 2024-12-22 10:58:58 +00:00
Improve use of std::unique_ptr
* Use unique_ptr in place of shared_ptr in some cases * unique_ptr for arrays does not require a custom deleter * use std::make_unique (c++14) where possible
This commit is contained in:
parent
88c3d556d5
commit
5f3f78822b
@ -1,3 +1,9 @@
|
|||||||
|
2022-02-05 Jay Berkenbilt <ejb@ql.org>
|
||||||
|
|
||||||
|
* Add QUtil::make_unique_cstr to return a std::unique_ptr<char[]>
|
||||||
|
as an alternative to QUtil::copy_string and
|
||||||
|
QUtil::make_shared_cstr.
|
||||||
|
|
||||||
2022-02-04 Jay Berkenbilt <ejb@ql.org>
|
2022-02-04 Jay Berkenbilt <ejb@ql.org>
|
||||||
|
|
||||||
* New preprocessor symbols QPDF_MAJOR_VERSION, QPDF_MINOR_VERSION,
|
* New preprocessor symbols QPDF_MAJOR_VERSION, QPDF_MINOR_VERSION,
|
||||||
|
10
TODO
10
TODO
@ -1,6 +1,9 @@
|
|||||||
10.6
|
10.6
|
||||||
====
|
====
|
||||||
|
|
||||||
|
* Expose emptyPDF to the C API. Ensure that qpdf_get_qpdf_version is
|
||||||
|
always static.
|
||||||
|
|
||||||
* Consider doing one big commit to reformat the entire codebase using
|
* Consider doing one big commit to reformat the entire codebase using
|
||||||
clang-format or a similar tool. Consider using blame.ignoreRevsFile
|
clang-format or a similar tool. Consider using blame.ignoreRevsFile
|
||||||
or similar (or otherwise study git blame to see how to minimize the
|
or similar (or otherwise study git blame to see how to minimize the
|
||||||
@ -364,6 +367,13 @@ auto x_ph = std::make_shared<X>(); X* x = x_ph.get();
|
|||||||
Derived* x = new Derived(); PointerHolder<Base> x_ph(x) -->
|
Derived* x = new Derived(); PointerHolder<Base> x_ph(x) -->
|
||||||
Derived* x = new Derived(); auto x_ph = std::shared_pointer<Base>(x);
|
Derived* x = new Derived(); auto x_ph = std::shared_pointer<Base>(x);
|
||||||
|
|
||||||
|
Also remember
|
||||||
|
|
||||||
|
auto x = std::shared_ptr(new T[5], std::default_delete<T[]>())
|
||||||
|
vs.
|
||||||
|
auto x = std::make_unique<T[]>(5)
|
||||||
|
|
||||||
|
|
||||||
PointerHolder in public API:
|
PointerHolder in public API:
|
||||||
|
|
||||||
QUtil::read_file_into_memory(
|
QUtil::read_file_into_memory(
|
||||||
|
@ -161,6 +161,10 @@ namespace QUtil
|
|||||||
QPDF_DLL
|
QPDF_DLL
|
||||||
std::shared_ptr<char> make_shared_cstr(std::string const&);
|
std::shared_ptr<char> make_shared_cstr(std::string const&);
|
||||||
|
|
||||||
|
// Copy string as a unique_ptr to an array.
|
||||||
|
QPDF_DLL
|
||||||
|
std::unique_ptr<char[]> make_unique_cstr(std::string const&);
|
||||||
|
|
||||||
// Returns lower-case hex-encoded version of the string, treating
|
// Returns lower-case hex-encoded version of the string, treating
|
||||||
// each character in the input string as unsigned. The output
|
// each character in the input string as unsigned. The output
|
||||||
// string will be twice as long as the input string.
|
// string will be twice as long as the input string.
|
||||||
|
@ -19,12 +19,8 @@ AES_PDF_native::AES_PDF_native(bool encrypt, unsigned char const* key,
|
|||||||
nrounds(0)
|
nrounds(0)
|
||||||
{
|
{
|
||||||
size_t keybits = 8 * key_bytes;
|
size_t keybits = 8 * key_bytes;
|
||||||
this->key = std::unique_ptr<unsigned char[]>(
|
this->key = std::make_unique<unsigned char[]>(key_bytes);
|
||||||
new unsigned char[key_bytes],
|
this->rk = std::make_unique<uint32_t[]>(RKLENGTH(keybits));
|
||||||
std::default_delete<unsigned char[]>());
|
|
||||||
this->rk = std::unique_ptr<uint32_t[]>(
|
|
||||||
new uint32_t[RKLENGTH(keybits)],
|
|
||||||
std::default_delete<uint32_t[]>());
|
|
||||||
size_t rk_bytes = RKLENGTH(keybits) * sizeof(uint32_t);
|
size_t rk_bytes = RKLENGTH(keybits) * sizeof(uint32_t);
|
||||||
std::memcpy(this->key.get(), key, key_bytes);
|
std::memcpy(this->key.get(), key, key_bytes);
|
||||||
std::memset(this->rk.get(), 0, rk_bytes);
|
std::memset(this->rk.get(), 0, rk_bytes);
|
||||||
|
@ -25,9 +25,7 @@ Pl_AES_PDF::Pl_AES_PDF(char const* identifier, Pipeline* next,
|
|||||||
use_specified_iv(false),
|
use_specified_iv(false),
|
||||||
disable_padding(false)
|
disable_padding(false)
|
||||||
{
|
{
|
||||||
this->key = std::unique_ptr<unsigned char[]>(
|
this->key = std::make_unique<unsigned char[]>(key_bytes);
|
||||||
new unsigned char[key_bytes],
|
|
||||||
std::default_delete<unsigned char[]>());
|
|
||||||
std::memcpy(this->key.get(), key, key_bytes);
|
std::memcpy(this->key.get(), key, key_bytes);
|
||||||
std::memset(this->inbuf, 0, this->buf_size);
|
std::memset(this->inbuf, 0, this->buf_size);
|
||||||
std::memset(this->outbuf, 0, this->buf_size);
|
std::memset(this->outbuf, 0, this->buf_size);
|
||||||
|
@ -20,7 +20,7 @@ QPDFArgParser::Members::Members(
|
|||||||
option_table(nullptr),
|
option_table(nullptr),
|
||||||
final_check_handler(nullptr)
|
final_check_handler(nullptr)
|
||||||
{
|
{
|
||||||
auto tmp = QUtil::make_shared_cstr(argv[0]);
|
auto tmp = QUtil::make_unique_cstr(argv[0]);
|
||||||
char* p = QUtil::getWhoami(tmp.get());
|
char* p = QUtil::getWhoami(tmp.get());
|
||||||
// Remove prefix added by libtool for consistency during testing.
|
// Remove prefix added by libtool for consistency during testing.
|
||||||
if (strncmp(p, "lt-", 3) == 0)
|
if (strncmp(p, "lt-", 3) == 0)
|
||||||
|
@ -3379,7 +3379,7 @@ QPDFJob::setEncryptionOptions(QPDF& pdf, QPDFWriter& w)
|
|||||||
static void parse_version(std::string const& full_version_string,
|
static void parse_version(std::string const& full_version_string,
|
||||||
std::string& version, int& extension_level)
|
std::string& version, int& extension_level)
|
||||||
{
|
{
|
||||||
auto vp = QUtil::make_shared_cstr(full_version_string);
|
auto vp = QUtil::make_unique_cstr(full_version_string);
|
||||||
char* v = vp.get();
|
char* v = vp.get();
|
||||||
char* p1 = strchr(v, '.');
|
char* p1 = strchr(v, '.');
|
||||||
char* p2 = (p1 ? strchr(1 + p1, '.') : 0);
|
char* p2 = (p1 ? strchr(1 + p1, '.') : 0);
|
||||||
|
@ -1919,7 +1919,7 @@ QPDFWriter::unparseObject(QPDFObjectHandle object, int level,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto tmp_ph = QUtil::make_shared_cstr(val);
|
auto tmp_ph = QUtil::make_unique_cstr(val);
|
||||||
char* tmp = tmp_ph.get();
|
char* tmp = tmp_ph.get();
|
||||||
size_t vlen = val.length();
|
size_t vlen = val.length();
|
||||||
RC4 rc4(QUtil::unsigned_char_pointer(this->m->cur_data_key),
|
RC4 rc4(QUtil::unsigned_char_pointer(this->m->cur_data_key),
|
||||||
|
@ -1211,7 +1211,7 @@ QPDF::decryptString(std::string& str, int objid, int generation)
|
|||||||
size_t vlen = str.length();
|
size_t vlen = str.length();
|
||||||
// Using PointerHolder guarantees that tmp will
|
// Using PointerHolder guarantees that tmp will
|
||||||
// be freed even if rc4.process throws an exception.
|
// be freed even if rc4.process throws an exception.
|
||||||
auto tmp = QUtil::make_shared_cstr(str);
|
auto tmp = QUtil::make_unique_cstr(str);
|
||||||
RC4 rc4(QUtil::unsigned_char_pointer(key), toI(key.length()));
|
RC4 rc4(QUtil::unsigned_char_pointer(key), toI(key.length()));
|
||||||
rc4.process(QUtil::unsigned_char_pointer(tmp.get()), vlen);
|
rc4.process(QUtil::unsigned_char_pointer(tmp.get()), vlen);
|
||||||
str = std::string(tmp.get(), vlen);
|
str = std::string(tmp.get(), vlen);
|
||||||
|
@ -744,6 +744,16 @@ QUtil::make_shared_cstr(std::string const& str)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<char[]>
|
||||||
|
QUtil::make_unique_cstr(std::string const& str)
|
||||||
|
{
|
||||||
|
auto result = std::make_unique<char[]>(str.length() + 1);
|
||||||
|
// Use memcpy in case string contains nulls
|
||||||
|
result.get()[str.length()] = '\0';
|
||||||
|
memcpy(result.get(), str.c_str(), str.length());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
std::string
|
std::string
|
||||||
QUtil::hex_encode(std::string const& input)
|
QUtil::hex_encode(std::string const& input)
|
||||||
{
|
{
|
||||||
@ -2625,7 +2635,7 @@ call_main_from_wmain(bool, int argc, wchar_t const* const argv[],
|
|||||||
// other systems. That way the rest of qpdf.cc can just act like
|
// other systems. That way the rest of qpdf.cc can just act like
|
||||||
// arguments are UTF-8.
|
// arguments are UTF-8.
|
||||||
|
|
||||||
std::vector<std::shared_ptr<char>> utf8_argv;
|
std::vector<std::unique_ptr<char[]>> utf8_argv;
|
||||||
for (int i = 0; i < argc; ++i)
|
for (int i = 0; i < argc; ++i)
|
||||||
{
|
{
|
||||||
std::string utf16;
|
std::string utf16;
|
||||||
@ -2638,11 +2648,9 @@ call_main_from_wmain(bool, int argc, wchar_t const* const argv[],
|
|||||||
QIntC::to_uchar(codepoint & 0xff)));
|
QIntC::to_uchar(codepoint & 0xff)));
|
||||||
}
|
}
|
||||||
std::string utf8 = QUtil::utf16_to_utf8(utf16);
|
std::string utf8 = QUtil::utf16_to_utf8(utf16);
|
||||||
utf8_argv.push_back(QUtil::make_shared_cstr(utf8));
|
utf8_argv.push_back(QUtil::make_unique_cstr(utf8));
|
||||||
}
|
}
|
||||||
auto utf8_argv_sp =
|
auto utf8_argv_sp = std::make_unique<char*[]>(1+utf8_argv.size());
|
||||||
std::shared_ptr<char*>(
|
|
||||||
new char*[1+utf8_argv.size()], std::default_delete<char*[]>());
|
|
||||||
char** new_argv = utf8_argv_sp.get();
|
char** new_argv = utf8_argv_sp.get();
|
||||||
for (size_t i = 0; i < utf8_argv.size(); ++i)
|
for (size_t i = 0; i < utf8_argv.size(); ++i)
|
||||||
{
|
{
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
int qpdfjob_run_from_argv(char const* const argv[])
|
int qpdfjob_run_from_argv(char const* const argv[])
|
||||||
{
|
{
|
||||||
auto whoami_p = QUtil::make_shared_cstr(argv[0]);
|
auto whoami_p = QUtil::make_unique_cstr(argv[0]);
|
||||||
auto whoami = QUtil::getWhoami(whoami_p.get());
|
auto whoami = QUtil::getWhoami(whoami_p.get());
|
||||||
QUtil::setLineBuf(stdout);
|
QUtil::setLineBuf(stdout);
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@ one
|
|||||||
7
|
7
|
||||||
compare okay
|
compare okay
|
||||||
compare okay
|
compare okay
|
||||||
|
compare okay
|
||||||
-2147483648 to int: PASSED
|
-2147483648 to int: PASSED
|
||||||
2147483647 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
|
2147483648 to int threw (integer out of range converting 2147483648 from a 8-byte signed type to a 4-byte signed type): PASSED
|
||||||
|
@ -150,7 +150,7 @@ void string_conversion_test()
|
|||||||
std::cout << "compare failed" << std::endl;
|
std::cout << "compare failed" << std::endl;
|
||||||
}
|
}
|
||||||
delete [] tmp;
|
delete [] tmp;
|
||||||
// Also test with make_shared_cstr
|
// Also test with make_shared_cstr and make_unique_cstr
|
||||||
auto tmp2 = QUtil::make_shared_cstr(embedded_null);
|
auto tmp2 = QUtil::make_shared_cstr(embedded_null);
|
||||||
if (memcmp(tmp2.get(), embedded_null.c_str(), 7) == 0)
|
if (memcmp(tmp2.get(), embedded_null.c_str(), 7) == 0)
|
||||||
{
|
{
|
||||||
@ -160,6 +160,15 @@ void string_conversion_test()
|
|||||||
{
|
{
|
||||||
std::cout << "compare failed" << std::endl;
|
std::cout << "compare failed" << std::endl;
|
||||||
}
|
}
|
||||||
|
auto tmp3 = QUtil::make_unique_cstr(embedded_null);
|
||||||
|
if (memcmp(tmp3.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_max_str = QUtil::int_to_string(INT_MAX);
|
||||||
std::string int_min_str = QUtil::int_to_string(INT_MIN);
|
std::string int_min_str = QUtil::int_to_string(INT_MIN);
|
||||||
@ -417,7 +426,7 @@ void transcoding_test()
|
|||||||
|
|
||||||
void print_whoami(char const* str)
|
void print_whoami(char const* str)
|
||||||
{
|
{
|
||||||
auto dup = QUtil::make_shared_cstr(str);
|
auto dup = QUtil::make_unique_cstr(str);
|
||||||
std::cout << QUtil::getWhoami(dup.get()) << std::endl;
|
std::cout << QUtil::getWhoami(dup.get()) << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,8 +14,7 @@ static void other_tests()
|
|||||||
// Test cases not covered by the pipeline: string as key, convert
|
// Test cases not covered by the pipeline: string as key, convert
|
||||||
// in place
|
// in place
|
||||||
RC4 r(reinterpret_cast<unsigned char const*>("quack"));
|
RC4 r(reinterpret_cast<unsigned char const*>("quack"));
|
||||||
auto data = std::unique_ptr<unsigned char[]>(
|
auto data = std::make_unique<unsigned char[]>(6);
|
||||||
new unsigned char[6], std::default_delete<unsigned char[]>());
|
|
||||||
memcpy(data.get(), "potato", 6);
|
memcpy(data.get(), "potato", 6);
|
||||||
r.process(data.get(), 6);
|
r.process(data.get(), 6);
|
||||||
assert(memcmp(data.get(), "\xa5\x6f\xe7\x27\x2b\x5c", 6) == 0);
|
assert(memcmp(data.get(), "\xa5\x6f\xe7\x27\x2b\x5c", 6) == 0);
|
||||||
|
Loading…
Reference in New Issue
Block a user