diff options
Diffstat (limited to 'libtests/qutil.cc')
-rw-r--r-- | libtests/qutil.cc | 408 |
1 files changed, 193 insertions, 215 deletions
diff --git a/libtests/qutil.cc b/libtests/qutil.cc index c3a9b163..fea9fca1 100644 --- a/libtests/qutil.cc +++ b/libtests/qutil.cc @@ -1,16 +1,16 @@ -#include <iostream> -#include <stdio.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <qpdf/QUtil.hh> +#include <qpdf/Pl_Buffer.hh> #include <qpdf/PointerHolder.hh> #include <qpdf/QPDFSystemError.hh> -#include <qpdf/Pl_Buffer.hh> -#include <string.h> -#include <limits.h> +#include <qpdf/QUtil.hh> +#include <fcntl.h> #include <fstream> +#include <iostream> +#include <limits.h> #include <locale> +#include <stdio.h> +#include <string.h> +#include <sys/stat.h> +#include <sys/types.h> #ifdef _WIN32 # include <io.h> @@ -25,96 +25,86 @@ #include <cassert> template <class int_T> -void test_to_number(char const* str, int_T wanted, bool error, - int_T (*fn)(char const*)) +void +test_to_number( + char const* str, int_T wanted, bool error, int_T (*fn)(char const*)) { bool threw = false; bool worked = false; int_T result = 0; std::string msg; - try - { + try { result = fn(str); worked = (wanted == result); - } - catch (std::runtime_error const& e) - { + } catch (std::runtime_error const& e) { threw = true; msg = e.what(); } - if (threw) - { - if (error) - { - std::cout << str << " to int threw (" << msg << "): PASSED" << std::endl; - } - else - { - std::cout << str << " to int threw but wanted " - << wanted << std::endl; + if (threw) { + if (error) { + std::cout << str << " to int threw (" << msg << "): PASSED" + << std::endl; + } else { + std::cout << str << " to int threw but wanted " << wanted + << std::endl; } - } - else - { - if (worked) - { + } else { + if (worked) { std::cout << str << " to int: PASSED" << std::endl; - } - else - { + } else { std::cout << str << " to int failed; got " << result << std::endl; } } } -void test_to_int(char const* str, int wanted, bool error) +void +test_to_int(char const* str, int wanted, bool error) { test_to_number(str, wanted, error, QUtil::string_to_int); } -void test_to_ll(char const* str, long long wanted, bool error) +void +test_to_ll(char const* str, long long wanted, bool error) { test_to_number(str, wanted, error, QUtil::string_to_ll); } -void test_to_uint(char const* str, unsigned int wanted, bool error) +void +test_to_uint(char const* str, unsigned int wanted, bool error) { test_to_number(str, wanted, error, QUtil::string_to_uint); } -void test_to_ull(char const* str, unsigned long long wanted, bool error) +void +test_to_ull(char const* str, unsigned long long wanted, bool error) { test_to_number(str, wanted, error, QUtil::string_to_ull); } -static void set_locale() +static void +set_locale() { - try - { + try { // First try a locale known to put commas in numbers. std::locale::global(std::locale("en_US.UTF-8")); - } - catch (std::runtime_error&) - { - try - { + } catch (std::runtime_error&) { + try { // If that fails, fall back to the user's default locale. std::locale::global(std::locale("")); - } - catch (std::runtime_error& e) - { + } catch (std::runtime_error& e) { // Ignore this error on Windows without MSVC. We get // enough test coverage on other platforms, and mingw // seems to have limited locale support (as of // 2020-10). -#if ! defined(_WIN32) || defined(_MSC_VER) +#if !defined(_WIN32) || defined(_MSC_VER) throw e; #endif } } } -void string_conversion_test() +void +string_conversion_test() { // Make sure the code produces consistent results even if we load // a non-C locale. @@ -146,32 +136,23 @@ void string_conversion_test() std::cout << embedded_null.c_str() << std::endl; std::cout << embedded_null.length() << std::endl; char* tmp = QUtil::copy_string(embedded_null); - if (memcmp(tmp, embedded_null.c_str(), 7) == 0) - { + if (memcmp(tmp, embedded_null.c_str(), 7) == 0) { std::cout << "compare okay" << std::endl; - } - else - { + } else { std::cout << "compare failed" << std::endl; } - delete [] tmp; + delete[] tmp; // Also test with make_shared_cstr and make_unique_cstr 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) { std::cout << "compare okay" << std::endl; - } - else - { + } else { std::cout << "compare failed" << std::endl; } auto tmp3 = QUtil::make_unique_cstr(embedded_null); - if (memcmp(tmp3.get(), embedded_null.c_str(), 7) == 0) - { + if (memcmp(tmp3.get(), embedded_null.c_str(), 7) == 0) { std::cout << "compare okay" << std::endl; - } - else - { + } else { std::cout << "compare failed" << std::endl; } @@ -198,41 +179,37 @@ void string_conversion_test() test_to_ull(small_negative.c_str(), 0, true); } -void os_wrapper_test() +void +os_wrapper_test() { - try - { + try { std::cout << "before remove" << std::endl; - QUtil::os_wrapper("remove file", - remove("/this/file/does/not/exist")); + QUtil::os_wrapper("remove file", remove("/this/file/does/not/exist")); std::cout << "after remove" << std::endl; - } - catch (std::runtime_error& s) - { + } catch (std::runtime_error& s) { std::cout << "exception: " << s.what() << std::endl; } } -void fopen_wrapper_test() +void +fopen_wrapper_test() { - try - { + try { std::cout << "before fopen" << std::endl; FILE* f = QUtil::safe_fopen("/this/file/does/not/exist", "r"); std::cout << "after fopen" << std::endl; - (void) fclose(f); - } - catch (QPDFSystemError& s) - { + (void)fclose(f); + } catch (QPDFSystemError& s) { std::cout << "exception: " << s.what() << std::endl; assert(s.getErrno() != 0); } assert(QUtil::file_can_be_opened("qutil.out")); - assert(! QUtil::file_can_be_opened("/does/not/exist")); + assert(!QUtil::file_can_be_opened("/does/not/exist")); } -void getenv_test() +void +getenv_test() { std::string val; std::cout << "IN_TESTSUITE: " << QUtil::get_env("IN_TESTSUITE", &val) @@ -242,60 +219,63 @@ void getenv_test() << std::endl; } -static void print_utf8(unsigned long val) +static void +print_utf8(unsigned long val) { std::string result = QUtil::toUTF8(val); std::cout << "0x" << QUtil::uint_to_string_base(val, 16) << " ->"; - if (val < 0xfffe) - { + if (val < 0xfffe) { std::cout << " " << result; - } - else - { + } else { // Emacs has trouble with utf-8 encoding files with characters // outside the 16-bit portion, so just show the character // values. - for (std::string::iterator iter = result.begin(); - iter != result.end(); ++iter) - { - std::cout << " " << QUtil::int_to_string_base( - static_cast<int>(static_cast<unsigned char>(*iter)), 16, 2); + for (std::string::iterator iter = result.begin(); iter != result.end(); + ++iter) { + std::cout << " " + << QUtil::int_to_string_base( + static_cast<int>( + static_cast<unsigned char>(*iter)), + 16, + 2); } } std::cout << std::endl; } -void to_utf8_test() +void +to_utf8_test() { print_utf8(0x41UL); print_utf8(0xF7UL); print_utf8(0x3c0UL); print_utf8(0x16059UL); print_utf8(0x7fffffffUL); - try - { + try { print_utf8(0x80000000UL); - } - catch (std::runtime_error& e) - { + } catch (std::runtime_error& e) { std::cout << "0x80000000: " << e.what() << std::endl; } } -static void print_utf16(unsigned long val) +static void +print_utf16(unsigned long val) { std::string result = QUtil::toUTF16(val); std::cout << "0x" << QUtil::uint_to_string_base(val, 16) << " ->"; - for (std::string::iterator iter = result.begin(); - iter != result.end(); ++iter) - { - std::cout << " " << QUtil::int_to_string_base( - static_cast<int>(static_cast<unsigned char>(*iter)), 16, 2); + for (std::string::iterator iter = result.begin(); iter != result.end(); + ++iter) { + std::cout << " " + << QUtil::int_to_string_base( + static_cast<int>(static_cast<unsigned char>(*iter)), + 16, + 2); } std::cout << std::endl; } -void to_utf16_test() +void +to_utf16_test() { print_utf16(0x41UL); print_utf16(0xF7UL); @@ -308,88 +288,88 @@ void to_utf16_test() std::string s(QUtil::utf8_to_utf16("\xcf\x80")); std::cout << QUtil::utf16_to_utf8(s) << std::endl; std::cout << QUtil::utf16_to_utf8(s + ".") << std::endl; - std::cout << "LE: " << QUtil::utf16_to_utf8("\xff\xfe\xc0\x03") << std::endl; + std::cout << "LE: " << QUtil::utf16_to_utf8("\xff\xfe\xc0\x03") + << std::endl; } -void utf8_to_ascii_test() +void +utf8_to_ascii_test() { char const* input = "\302\277Does \317\200 have fingers?"; - std::cout << input - << std::endl - << QUtil::utf8_to_ascii(input) - << std::endl - << QUtil::utf8_to_ascii(input, '*') - << std::endl; + std::cout << input << std::endl + << QUtil::utf8_to_ascii(input) << std::endl + << QUtil::utf8_to_ascii(input, '*') << std::endl; std::string a = QUtil::utf8_to_win_ansi(input, '*'); std::string b = QUtil::utf8_to_mac_roman(input, '*'); std::cout - << "<" << QUtil::int_to_string_base( - static_cast<unsigned char>(a.at(0)), 16, 2) + << "<" + << QUtil::int_to_string_base(static_cast<unsigned char>(a.at(0)), 16, 2) << ">" << a.substr(1) << std::endl - << "<" << QUtil::int_to_string_base( - static_cast<unsigned char>(b.at(0)), 16, 2) + << "<" + << QUtil::int_to_string_base(static_cast<unsigned char>(b.at(0)), 16, 2) << ">" << b.substr(1) << std::endl; } -void transcoding_test(std::string (*to_utf8)(std::string const&), - std::string (*from_utf8)(std::string const&, char), - int first, int last, std::string unknown) +void +transcoding_test( + std::string (*to_utf8)(std::string const&), + std::string (*from_utf8)(std::string const&, char), + int first, + int last, + std::string unknown) { std::string in(" "); std::string out; std::string back; - for (int i = first; i <= last; ++i) - { + for (int i = first; i <= last; ++i) { in.at(0) = static_cast<char>(static_cast<unsigned char>(i)); out = (*to_utf8)(in); std::string wanted = (out == "\xef\xbf\xbd") ? unknown : in; back = (*from_utf8)(out, '?'); - if (back != wanted) - { - std::cout << i << ": " << in << " -> " << out - << " -> " << back << " (wanted " << wanted << ")" - << std::endl; + if (back != wanted) { + std::cout << i << ": " << in << " -> " << out << " -> " << back + << " (wanted " << wanted << ")" << std::endl; } } } -void check_analyze(std::string const& str, bool has8bit, bool utf8, bool utf16) +void +check_analyze(std::string const& str, bool has8bit, bool utf8, bool utf16) { bool has_8bit_chars = false; bool is_valid_utf8 = false; bool is_utf16 = false; QUtil::analyze_encoding(str, has_8bit_chars, is_valid_utf8, is_utf16); - if (! ((has_8bit_chars == has8bit) && - (is_valid_utf8 == utf8) && - (is_utf16 == utf16))) - { + if (!((has_8bit_chars == has8bit) && (is_valid_utf8 == utf8) && + (is_utf16 == utf16))) { std::cout << "analysis failed: " << str << std::endl; } } -void print_alternatives(std::string const& str) +void +print_alternatives(std::string const& str) { std::vector<std::string> result = QUtil::possible_repaired_encodings(str); size_t n = result.size(); - for (size_t i = 0; i < n; ++i) - { + for (size_t i = 0; i < n; ++i) { std::cout << i << ": " << QUtil::hex_encode(result.at(i)) << std::endl; } } -void transcoding_test() +void +transcoding_test() { - transcoding_test(&QUtil::pdf_doc_to_utf8, - &QUtil::utf8_to_pdf_doc, 127, 160, "\x9f"); + transcoding_test( + &QUtil::pdf_doc_to_utf8, &QUtil::utf8_to_pdf_doc, 127, 160, "\x9f"); std::cout << "bidirectional pdf doc done" << std::endl; - transcoding_test(&QUtil::pdf_doc_to_utf8, - &QUtil::utf8_to_pdf_doc, 24, 31, "?"); + transcoding_test( + &QUtil::pdf_doc_to_utf8, &QUtil::utf8_to_pdf_doc, 24, 31, "?"); std::cout << "bidirectional pdf doc low done" << std::endl; - transcoding_test(&QUtil::win_ansi_to_utf8, - &QUtil::utf8_to_win_ansi, 128, 160, "?"); + transcoding_test( + &QUtil::win_ansi_to_utf8, &QUtil::utf8_to_win_ansi, 128, 160, "?"); std::cout << "bidirectional win ansi done" << std::endl; - transcoding_test(&QUtil::mac_roman_to_utf8, - &QUtil::utf8_to_mac_roman, 128, 255, "?"); + transcoding_test( + &QUtil::mac_roman_to_utf8, &QUtil::utf8_to_mac_roman, 128, 255, "?"); std::cout << "bidirectional mac roman done" << std::endl; check_analyze("pi = \317\200", true, true, false); check_analyze("pi != \317", true, false, false); @@ -401,17 +381,17 @@ void transcoding_test() std::string input2("a\317\200b"); std::string input3("ab"); std::string output; - assert(! QUtil::utf8_to_ascii(input1, output)); - assert(! QUtil::utf8_to_ascii(input2, output)); + assert(!QUtil::utf8_to_ascii(input1, output)); + assert(!QUtil::utf8_to_ascii(input2, output)); assert(QUtil::utf8_to_ascii(input3, output)); assert(QUtil::utf8_to_win_ansi(input1, output)); - assert(! QUtil::utf8_to_win_ansi(input2, output)); + assert(!QUtil::utf8_to_win_ansi(input2, output)); assert(QUtil::utf8_to_win_ansi(input3, output)); assert(QUtil::utf8_to_mac_roman(input1, output)); - assert(! QUtil::utf8_to_mac_roman(input2, output)); + assert(!QUtil::utf8_to_mac_roman(input2, output)); assert(QUtil::utf8_to_mac_roman(input3, output)); assert(QUtil::utf8_to_pdf_doc(input1, output)); - assert(! QUtil::utf8_to_pdf_doc(input2, output)); + assert(!QUtil::utf8_to_pdf_doc(input2, output)); assert(QUtil::utf8_to_pdf_doc(input3, output)); std::cout << "alternatives" << std::endl; // char name mac win pdf-doc @@ -434,18 +414,20 @@ void transcoding_test() std::string other_utf8 = other + QUtil::toUTF8(0x9f) + "w" + QUtil::toUTF8(0xad) + "w"; std::string other_to_utf8; - assert(! QUtil::utf8_to_pdf_doc(other_utf8, other_to_utf8)); + assert(!QUtil::utf8_to_pdf_doc(other_utf8, other_to_utf8)); std::cout << other_to_utf8 << std::endl; std::cout << "done other characters" << std::endl; } -void print_whoami(char const* str) +void +print_whoami(char const* str) { auto dup = QUtil::make_unique_cstr(str); std::cout << QUtil::getWhoami(dup.get()) << std::endl; } -void get_whoami_test() +void +get_whoami_test() { print_whoami("a/b/c/quack1"); print_whoami("a/b/c/quack2.exe"); @@ -453,26 +435,24 @@ void get_whoami_test() print_whoami("a\\b\\c\\quack4.exe"); } -void assert_same_file(char const* file1, char const* file2, bool expected) +void +assert_same_file(char const* file1, char const* file2, bool expected) { bool actual = QUtil::same_file(file1, file2); std::cout << "file1: -" << (file1 ? file1 : "(null)") << "-, file2: -" - << (file2 ? file2 : "(null)") << "-; same: " - << actual << ": " << ((actual == expected) ? "PASS" : "FAIL") - << std::endl; + << (file2 ? file2 : "(null)") << "-; same: " << actual << ": " + << ((actual == expected) ? "PASS" : "FAIL") << std::endl; } -void same_file_test() +void +same_file_test() { - try - { + try { fclose(QUtil::safe_fopen("qutil.out", "r")); fclose(QUtil::safe_fopen("other-file", "r")); - } - catch (std::exception const&) - { + } catch (std::exception const&) { std::cout << "same_file_test expects to have qutil.out and other-file" - " exist in the current directory\n"; + " exist in the current directory\n"; return; } assert_same_file("qutil.out", "./qutil.out", true); @@ -483,12 +463,12 @@ void same_file_test() assert_same_file("", "qutil.out", false); } -void path_test() +void +path_test() { auto check = [](bool print, std::string const& a, std::string const& b) { auto result = QUtil::path_basename(a); - if (print) - { + if (print) { std::cout << a << " -> " << result << std::endl; } assert(result == b); @@ -506,12 +486,13 @@ void path_test() check(true, "quack", "quack"); } -void read_from_file_test() +void +read_from_file_test() { std::list<std::string> lines = QUtil::read_lines_from_file("other-file"); for (std::list<std::string>::iterator iter = lines.begin(); - iter != lines.end(); ++iter) - { + iter != lines.end(); + ++iter) { std::cout << *iter << std::endl; } // Test the other versions and make sure we get the same results @@ -565,36 +546,34 @@ void read_from_file_test() assert(memcmp(buf2->getBuffer(), p, size) == 0); } -void assert_hex_encode(std::string const& input, std::string const& expected) +void +assert_hex_encode(std::string const& input, std::string const& expected) { std::string actual = QUtil::hex_encode(input); - if (expected != actual) - { - std::cout << "hex encode " << input - << ": expected = " << expected - << "; actual = " << actual - << std::endl; + if (expected != actual) { + std::cout << "hex encode " << input << ": expected = " << expected + << "; actual = " << actual << std::endl; } } -void assert_hex_decode(std::string const& input, std::string const& expected) +void +assert_hex_decode(std::string const& input, std::string const& expected) { std::string actual = QUtil::hex_decode(input); - if (expected != actual) - { - std::cout << "hex encode " << input - << ": expected = " << expected - << "; actual = " << actual - << std::endl; + if (expected != actual) { + std::cout << "hex encode " << input << ": expected = " << expected + << "; actual = " << actual << std::endl; } } -void hex_encode_decode_test() +void +hex_encode_decode_test() { std::cout << "begin hex encode/decode\n"; assert_hex_encode("", ""); assert_hex_encode("Potato", "506f7461746f"); - std::string with_null("a\367" "00w"); + std::string with_null("a\367" + "00w"); with_null[3] = '\0'; assert_hex_encode(with_null, "61f7300077"); assert_hex_decode("", ""); @@ -603,58 +582,60 @@ void hex_encode_decode_test() std::cout << "end hex encode/decode\n"; } -static void assert_no_file(char const* filename) +static void +assert_no_file(char const* filename) { - try - { + try { fclose(QUtil::safe_fopen(filename, "r")); assert(false); - } - catch (QPDFSystemError&) - { + } catch (QPDFSystemError&) { } } -void rename_delete_test() +void +rename_delete_test() { PointerHolder<char> buf; size_t size = 0; - try - { + try { QUtil::remove_file("old\xcf\x80"); - } - catch (QPDFSystemError&) - { + } catch (QPDFSystemError&) { } assert_no_file("old\xcf\x80"); - std::cout << "create file" << std::endl;; + std::cout << "create file" << std::endl; + ; FILE* f1 = QUtil::safe_fopen("old\xcf\x80", "w"); fprintf(f1, "one"); fclose(f1); QUtil::read_file_into_memory("old\xcf\x80", buf, size); assert(memcmp(buf.get(), "one", 3) == 0); - std::cout << "rename file" << std::endl;; + std::cout << "rename file" << std::endl; + ; QUtil::rename_file("old\xcf\x80", "old\xcf\x80.~tmp"); QUtil::read_file_into_memory("old\xcf\x80.~tmp", buf, size); assert(memcmp(buf.get(), "one", 3) == 0); assert_no_file("old\xcf\x80"); - std::cout << "create file" << std::endl;; + std::cout << "create file" << std::endl; + ; f1 = QUtil::safe_fopen("old\xcf\x80", "w"); fprintf(f1, "two"); fclose(f1); - std::cout << "rename over existing" << std::endl;; + std::cout << "rename over existing" << std::endl; + ; QUtil::rename_file("old\xcf\x80", "old\xcf\x80.~tmp"); QUtil::read_file_into_memory("old\xcf\x80.~tmp", buf, size); assert(memcmp(buf.get(), "two", 3) == 0); assert_no_file("old\xcf\x80"); - std::cout << "delete file" << std::endl;; + std::cout << "delete file" << std::endl; + ; QUtil::remove_file("old\xcf\x80.~tmp"); assert_no_file("old\xcf\x80"); assert_no_file("old\xcf\x80.~tmp"); } -void timestamp_test() +void +timestamp_test() { auto check = [](QUtil::QPDFTime const& t) { std::string pdf = QUtil::qpdf_time_to_pdf_time(t); @@ -666,7 +647,7 @@ void timestamp_test() check(QUtil::QPDFTime(2021, 2, 9, 14, 49, 25, 300)); check(QUtil::QPDFTime(2021, 2, 10, 1, 19, 25, -330)); check(QUtil::QPDFTime(2021, 2, 9, 19, 19, 25, 0)); - assert(! QUtil::pdf_time_to_qpdf_time("potato")); + assert(!QUtil::pdf_time_to_qpdf_time("potato")); assert(QUtil::pdf_time_to_qpdf_time("D:20210211064743Z")); assert(QUtil::pdf_time_to_qpdf_time("D:20210211064743-05'00'")); assert(QUtil::pdf_time_to_qpdf_time("D:20210211064743+05'30'")); @@ -675,14 +656,13 @@ void timestamp_test() // Manual testing was done to ensure that we are actually getting // back the current time in various time zones. assert(QUtil::pdf_time_to_qpdf_time( - QUtil::qpdf_time_to_pdf_time( - QUtil::get_current_qpdf_time()))); + QUtil::qpdf_time_to_pdf_time(QUtil::get_current_qpdf_time()))); } -int main(int argc, char* argv[]) +int +main(int argc, char* argv[]) { - try - { + try { std::cout << "---- string conversion" << std::endl; string_conversion_test(); std::cout << "---- os wrapper" << std::endl; @@ -713,9 +693,7 @@ int main(int argc, char* argv[]) rename_delete_test(); std::cout << "---- timestamp" << std::endl; timestamp_test(); - } - catch (std::exception& e) - { + } catch (std::exception& e) { std::cout << "unexpected exception: " << e.what() << std::endl; } |