mirror of
https://github.com/qpdf/qpdf.git
synced 2025-01-31 02:48:31 +00:00
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.
This commit is contained in:
parent
5d9d80beba
commit
164cbdde46
@ -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();
|
||||
# ----------
|
||||
|
1
qpdf/qtest/qpdf/issue-118.obfuscated
Normal file
1
qpdf/qtest/qpdf/issue-118.obfuscated
Normal file
@ -0,0 +1 @@
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>癬¦¦¦¦'踰譯<EFBFBD>軟霪跛<EFBFBD><EFBFBD>擬<EFBFBD>笨¦¦¦¦<EFBFBD><EFBFBD>踰¦髜¦鋻鶴¦¦髜<EFBFBD><EFBFBD><EFBFBD>れ<EFBFBD><EFBFBD>鴪匿絃<EFBFBD>‘¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦鋻¦¦¦鋻¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦頗¦¦¦¦¦鋻¦¦鋻¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦頗¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦頗¦¦¦¦¦¦<EFBFBD>┸絃<EFBFBD>‘<EFBFBD>┌<EFBFBD>篤¦¦¦¦¦¦¦¦¦¦¦¦¦鋻¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦鋻¦¦¦¦¦¦¦<EFBFBD>鶴<EFBFBD>ζ韶縄趁<EFBFBD>擬<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>縄趁<EFBFBD>ザ<EFBFBD><EFBFBD>跛<EFBFBD><EFBFBD>※<EFBFBD><EFBFBD><EFBFBD>鶴<EFBFBD><EFBFBD>縄趁<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>縄趁<EFBFBD><EFBFBD><EFBFBD>れ<EFBFBD>朗跛<EFBFBD><EFBFBD><EFBFBD>語<EFBFBD>鶴<EFBFBD>縄趁<EFBFBD>¦頗踰踰<EFBFBD><EFBFBD>汝鯑晋奨①凸¦鑈銘摸摸閒¦閒¦閒¦閒¦鑈¦鑈¦鍗<EFBFBD>┸絃<EFBFBD>‘<EFBFBD>┌<EFBFBD>篤晋Ⅹ鹸奨<EFBFBD>燾福蜑<EFBFBD><EFBFBD><EFBFBD>
|
Binary file not shown.
1
qpdf/qtest/qpdf/issue-51.obfuscated
Normal file
1
qpdf/qtest/qpdf/issue-51.obfuscated
Normal file
@ -0,0 +1 @@
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>癬¦¦¦¦¦¦"踰譯<EFBFBD>軟鞦<EFBFBD><EFBFBD><EFBFBD>れ<EFBFBD>鶴<EFBFBD>笨¦¦髜¦¦¦¦¦ⅱ鯑晋奨①日¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦<EFBFBD>鶴<EFBFBD>ζ韶笨¦¦¦¦¦¦¦鶴鶴鶴<EFBFBD>笨¦¦¦¦踰踰<EFBFBD><EFBFBD>笨¦¦¦<EFBFBD><EFBFBD>¦¦¦¦¦<EFBFBD><EFBFBD>笨¦¦韶笨笨¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ⅱ鱆¦¦¦¦蹊踰<EFBFBD><EFBFBD>鴪¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¬踰譯<EFBFBD>軟鞦¦¦笨¦¦¦笨¦¦踰踰<EFBFBD><EFBFBD>乍¦¦¦¦¦<EFBFBD><EFBFBD>鶴<EFBFBD>踰¦鶴<EFBFBD><EFBFBD><EFBFBD>譬<EFBFBD><EFBFBD><EFBFBD>踰<EFBFBD>乍¦¦糶¦¦綟鴪¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦鉸奨<EFBFBD>鶴<EFBFBD>¦¦¦¦¦踰¦¦讓貽¦¦¦"¦踰¦¦譬貽¦¦¦¦ⅴ踰¦¦譬貽¦¦¦¦¦踰¦¦譬貽¦¦¦¦¦踰¦¦譬貽¦¦¦¦¦踰¦¦譬貽¦¦¦¦¦踰¦¦譬貽¦¦¦ⅷ¦踰¦¦譬貽¦¦¦¦¦踰¦¦譬貽絃⑤<EFBFBD><EFBFBD>韶<EFBFBD><EFBFBD>ザ<EFBFBD>髜<EFBFBD><EFBFBD>語諟鶴<EFBFBD>鴪晋Ⅹ鹸奨<EFBFBD>逸鍗蜑<EFBFBD><EFBFBD><EFBFBD>
|
@ -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
|
||||
|
@ -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
|
@ -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 ") +
|
||||
|
Loading…
x
Reference in New Issue
Block a user