aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2018-08-14 01:26:20 +0200
committerJay Berkenbilt <ejb@ql.org>2018-08-14 01:26:20 +0200
commit164cbdde46d7ec6924782a60f346a6a465a79a26 (patch)
tree719c10db22a05ad0b7c30053eb66298ce2c6cebf
parent5d9d80beba1caa5828093dd1932fd806df1e644b (diff)
downloadqpdf-164cbdde46d7ec6924782a60f346a6a465a79a26.tar.zst
Protect against virus warnings (fixes #216)
Some files in the test suite trigger antivirus warnings. These are not infected files with malicious intent. They are test files to ensure that qpdf does not crash when it encounters the files. This change enables those files to be obfuscated in the source repository so that checking out qpdf from version control or extracting the source code doesn't trigger antivirus warnings.
-rw-r--r--qpdf/qtest/qpdf.test30
-rw-r--r--qpdf/qtest/qpdf/issue-118.obfuscated1
-rw-r--r--qpdf/qtest/qpdf/issue-118.pdfbin806 -> 0 bytes
-rw-r--r--qpdf/qtest/qpdf/issue-51.obfuscated1
-rw-r--r--qpdf/qtest/qpdf/issue-51.out1
-rw-r--r--qpdf/qtest/qpdf/issue-51.pdf22
-rw-r--r--qpdf/test_driver.cc115
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
deleted file mode 100644
index 5dc05f6d..00000000
--- a/qpdf/qtest/qpdf/issue-118.pdf
+++ /dev/null
Binary files differ
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 ") +