diff options
-rw-r--r-- | qpdf/qtest/qpdf.test | 30 | ||||
-rw-r--r-- | qpdf/qtest/qpdf/issue-118.obfuscated | 1 | ||||
-rw-r--r-- | qpdf/qtest/qpdf/issue-118.pdf | bin | 806 -> 0 bytes | |||
-rw-r--r-- | qpdf/qtest/qpdf/issue-51.obfuscated | 1 | ||||
-rw-r--r-- | qpdf/qtest/qpdf/issue-51.out | 1 | ||||
-rw-r--r-- | qpdf/qtest/qpdf/issue-51.pdf | 22 | ||||
-rw-r--r-- | qpdf/test_driver.cc | 115 |
7 files changed, 109 insertions, 61 deletions
diff --git a/qpdf/qtest/qpdf.test b/qpdf/qtest/qpdf.test index a091456c..1468a438 100644 --- a/qpdf/qtest/qpdf.test +++ b/qpdf/qtest/qpdf.test @@ -291,11 +291,31 @@ $n_tests += scalar(@bug_tests); foreach my $d (@bug_tests) { my ($n, $description, $exit_status) = @$d; - $td->runtest($description, - {$td->COMMAND => "qpdf issue-$n.pdf a.pdf"}, - {$td->FILE => "issue-$n.out", - $td->EXIT_STATUS => $exit_status}, - $td->NORMALIZE_NEWLINES); + if (-f "issue-$n.obfuscated") + { + # Some of the PDF files in the test suite trigger anti-virus + # warnings (MAL/PDFEx-H) and are quarantined or deleted by + # some antivirus software. These files are not actually + # infected files with malicious intent. They are present in + # the test suite to ensure that qpdf does not crash when + # process those files. Base64-encode them and pass them to + # stdin to prevent anti-virus programs from messing up the + # extracted sources. Search for "obfuscated" in test_driver.cc + # for instructions on how to obfuscate input files. + $td->runtest($description, + {$td->COMMAND => "test_driver 45 issue-$n"}, + {$td->FILE => "issue-$n.out", + $td->EXIT_STATUS => $exit_status}, + $td->NORMALIZE_NEWLINES); + } + else + { + $td->runtest($description, + {$td->COMMAND => "qpdf issue-$n.pdf a.pdf"}, + {$td->FILE => "issue-$n.out", + $td->EXIT_STATUS => $exit_status}, + $td->NORMALIZE_NEWLINES); + } } show_ntests(); # ---------- diff --git a/qpdf/qtest/qpdf/issue-118.obfuscated b/qpdf/qtest/qpdf/issue-118.obfuscated new file mode 100644 index 00000000..54ea8fe5 --- /dev/null +++ b/qpdf/qtest/qpdf/issue-118.obfuscated @@ -0,0 +1 @@ +éáýüüüüüüüüüýìü죮ŠÆððÆìì㵌©ìãüüüüüüüüüãìüüüüãüüü¿üìüüüüüã©¢«ž€ìøýôÆòòÆ¿žŸ©¡Æüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüü¿üüüüüüü¿üüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüü¿üüüüüüüüüüüü¿üüüüü¿üüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüü¿üüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüü¿üüüüüüüüüüüüü©¢š¿žŸ©¡Æ©¢š£®ŠÆÆüüüüüüüüüüüüüüüüüüüüüüüüüüü¿üüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüü¿üüüüüüüüüüüüüüôìü죮ŠÆððÆìì㵌©ì㩪Æìì㥶©ìõÆììã
¢š©ŽìüìõÆììãìýìþìýÆììã©¢«ž€ìÿúÆìì㣣žìþìüìÆììãüü¿üìüìüìÆòòÆ¿žŸ©¡ÆÌüüüÍÌÃÌÎÌÎüÎüüüÎüüüÎüüüÎüüüÍüüüÍüüüÆ©¢š¿žŸ©¡Æ©¢š£®ŠÆÆ¿žŸžŽŸ©ªÆúýûÆéé
\ No newline at end of file diff --git a/qpdf/qtest/qpdf/issue-118.pdf b/qpdf/qtest/qpdf/issue-118.pdf Binary files differdeleted file mode 100644 index 5dc05f6d..00000000 --- a/qpdf/qtest/qpdf/issue-118.pdf +++ /dev/null diff --git a/qpdf/qtest/qpdf/issue-51.obfuscated b/qpdf/qtest/qpdf/issue-51.obfuscated new file mode 100644 index 00000000..0d81d9ed --- /dev/null +++ b/qpdf/qtest/qpdf/issue-51.obfuscated @@ -0,0 +1 @@ +éáýüüüüüüüüüüüüüþìü죮ŠÆððã©¢«ž€ìþìüìãüüüüüüãüüüüüüüüüüüòòÆ¿žŸ©¡Æüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüýìü죮ŠÆððãüüüüüüüüüüüüüüüüìüìüìãüüüüüüüüüìüìüìãüüüüüüüüüüüüüüüüüüüãüüüüüððãüãüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüòòãüüüüüüüüìþìüìòòüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüûìü죮ŠÆððãüüüüãüüüüüüüãüüüüüìüìüìÆãüüüüüüüüüüýìüììüüüü좹 좹 ìüÆãüüüüäüüüüüåÆòòüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüŽŸ©ªÆüìõÆüüüüüüüüüüìüüüüüìªìÆüüüüüüüþüüìüüüüüì¢ìÆüüüüüüüüüõìüüüüüì¢ìÆüüüüüüüüüüìüüüüüì¢ìÆüüüüüüüüüüìüüüüüì¢ìÆüüüüüüüüüüìüüüüüì¢ìÆüüüüüüüüüüìüüüüüì¢ìÆüüüüüüüøüüìüüüüüì¢ìÆüüüüüüüüüüìüüüüüì¢ìÆžŸ¥ ©Ÿðð㥶©ìü㣣žìûìüìòò¿žŸžŽŸ©ªÆûøüÆéé
\ No newline at end of file diff --git a/qpdf/qtest/qpdf/issue-51.out b/qpdf/qtest/qpdf/issue-51.out index 692c0984..e361b7d0 100644 --- a/qpdf/qtest/qpdf/issue-51.out +++ b/qpdf/qtest/qpdf/issue-51.out @@ -8,4 +8,3 @@ WARNING: issue-51.pdf (object 2 0, offset 71): attempting to recover stream leng WARNING: issue-51.pdf (object 2 0, offset 71): unable to recover stream data; treating stream as empty WARNING: issue-51.pdf (object 2 0, offset 977): expected endobj WARNING: issue-51.pdf (object 2 0, offset 977): EOF after endobj -qpdf: operation succeeded with warnings; resulting file may have some problems diff --git a/qpdf/qtest/qpdf/issue-51.pdf b/qpdf/qtest/qpdf/issue-51.pdf deleted file mode 100644 index 2dafce1a..00000000 --- a/qpdf/qtest/qpdf/issue-51.pdf +++ /dev/null @@ -1,22 +0,0 @@ -%PDF-100000000000002 0 obj -<</Length 2 0 R/000000/00000000000>> -stream -000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 0 obj -<</0000000000000000 0 0 R/000000000 0 0 R/00000000[00000000000]/00000<</0/00000000000000000000000000000000>>/00000000 2 0 R>>000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007 0 obj -<</0000/0000000/00000 0 0 R -/0000000000[1 0 R 0000 null null 0] -/0000(00000) ->>0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000xref -0 9 -0000000000 00000 f -0000000200 00000 n -0000000009 00000 n -0000000000 00000 n -0000000000 00000 n -0000000000 00000 n -0000000000 00000 n -0000000400 00000 n -0000000000 00000 n -trailer<</Size 0/Root 7 0 R>>startxref -740 -%%EOF
\ No newline at end of file diff --git a/qpdf/test_driver.cc b/qpdf/test_driver.cc index 14a317ba..69d13d54 100644 --- a/qpdf/test_driver.cc +++ b/qpdf/test_driver.cc @@ -161,6 +161,44 @@ static void print_rect(std::ostream& out, << r.urx << ", " << r.ury << "]"; } +static void read_file_into_memory( + char const* filename, + PointerHolder<char>& file_buf, size_t& size) +{ + FILE* f = QUtil::safe_fopen(filename, "rb"); + fseek(f, 0, SEEK_END); + size = QUtil::tell(f); + fseek(f, 0, SEEK_SET); + file_buf = PointerHolder<char>(true, new char[size]); + char* buf_p = file_buf.getPointer(); + size_t bytes_read = 0; + size_t len = 0; + while ((len = fread(buf_p + bytes_read, 1, size - bytes_read, f)) > 0) + { + bytes_read += len; + } + if (bytes_read != size) + { + if (ferror(f)) + { + throw std::runtime_error( + std::string("failure reading file ") + filename + + " into memory: read " + + QUtil::int_to_string(bytes_read) + "; wanted " + + QUtil::int_to_string(size)); + } + else + { + throw std::logic_error( + std::string("premature eof reading file ") + filename + + " into memory: read " + + QUtil::int_to_string(bytes_read) + "; wanted " + + QUtil::int_to_string(size)); + } + } + fclose(f); +} + void runtest(int n, char const* filename1, char const* arg2) { // Most tests here are crafted to work on specific files. Look at @@ -200,6 +238,34 @@ void runtest(int n, char const* filename1, char const* arg2) // arg2 is password pdf.processFile(filename1, arg2); } + else if (n == 45) + { + // Decode obfuscated files. To obfuscated, run the input file + // through this perl script, and save the result to + // filename.obfuscated. This pretends that the input was + // called filename.pdf and that that file contained the + // deobfuscated version. + + // undef $/; + // my @str = split('', <STDIN>); + // for (my $i = 0; $i < scalar(@str); ++$i) + // { + // $str[$i] = chr(ord($str[$i]) ^ 0xcc); + // } + // print(join('', @str)); + + std::string filename(std::string(filename1) + ".obfuscated"); + PointerHolder<char> file_buf; + size_t size = 0; + read_file_into_memory(filename.c_str(), file_buf, size); + char* p = file_buf.getPointer(); + for (size_t i = 0; i < size; ++i) + { + p[i] ^= 0xcc; + } + pdf.processMemoryFile((std::string(filename1) + ".pdf").c_str(), + p, size); + } else if (n % 2 == 0) { if (n % 4 == 0) @@ -217,39 +283,9 @@ void runtest(int n, char const* filename1, char const* arg2) else { QTC::TC("qpdf", "exercise processMemoryFile"); - FILE* f = QUtil::safe_fopen(filename1, "rb"); - fseek(f, 0, SEEK_END); - size_t size = QUtil::tell(f); - fseek(f, 0, SEEK_SET); - file_buf = PointerHolder<char>(true, new char[size]); - char* buf_p = file_buf.getPointer(); - size_t bytes_read = 0; - size_t len = 0; - while ((len = fread(buf_p + bytes_read, 1, size - bytes_read, f)) > 0) - { - bytes_read += len; - } - if (bytes_read != size) - { - if (ferror(f)) - { - throw std::runtime_error( - std::string("failure reading file ") + filename1 + - " into memory: read " + - QUtil::int_to_string(bytes_read) + "; wanted " + - QUtil::int_to_string(size)); - } - else - { - throw std::logic_error( - std::string("premature eof reading file ") + filename1 + - " into memory: read " + - QUtil::int_to_string(bytes_read) + "; wanted " + - QUtil::int_to_string(size)); - } - } - fclose(f); - pdf.processMemoryFile(filename1, buf_p, size); + size_t size = 0; + read_file_into_memory(filename1, file_buf, size); + pdf.processMemoryFile(filename1, file_buf.getPointer(), size); } if ((n == 0) || (n == 1)) @@ -1612,6 +1648,19 @@ void runtest(int n, char const* filename1, char const* arg2) w.setSuppressOriginalObjectIDs(true); w.write(); } + else if (n == 45) + { + // Decode obfuscated files. This is here to help test with + // files that trigger anti-virus warnings. See comments in + // qpdf.test for details. + QPDFWriter w(pdf, "a.pdf"); + w.setStaticID(true); + w.write(); + if (! pdf.getWarnings().empty()) + { + exit(3); + } + } else { throw std::runtime_error(std::string("invalid test ") + |