#!/usr/bin/env perl
require 5.008;
use warnings;
use strict;

unshift(@INC, '.');
require qpdf_test_helpers;

chdir("qpdf") or die "chdir testdir failed: $!\n";

require TestDriver;

cleanup();

my $td = new TestDriver('specific-bugs');

# The number is the github issue number in which the bug was reported.
my @bug_tests = (
    ["51", "resolve loop", 3],
    ["99", "object 0", 2],
    ["99b", "object 0", 2],
    ["100", "xref reconstruction loop", 2],
    ["101", "resolve for exception text", 2],
    ["117", "other infinite loop", 3],
    ["118", "other infinite loop", 2],
    ["119", "other infinite loop", 3],
    ["120", "other infinite loop", 3],
    ["106", "zlib data error", 3],
    ["141a", "/W entry size 0", 2],
    ["141b", "/W entry size 0", 2],
    ["143", "self-referential ostream", 3, "--preserve-unreferenced"],
    ["146", "very deeply nested array", 2],
    ["147", "previously caused memory error", 2],
    ["148", "free memory on bad flate", 2],
    ["149", "xref prev pointer loop", 3],
    ["150", "integer overflow", 2],
    ["202", "even more deeply nested dictionary", 2],
    ["263", "empty xref stream", 2],
    ["335a", "ozz-fuzz-12152", 2],
    ["335b", "ozz-fuzz-14845", 2],
    ["fuzz-16214", "stream in object stream", 3, "--preserve-unreferenced"],
    # When adding to this list, consider adding to CORPUS_FROM_TEST in
    # fuzz/CMakeLists.txt and updating the count in
    # fuzz/qtest/fuzz.test.
    );
my $n_tests = scalar(@bug_tests);
foreach my $d (@bug_tests)
{
    my ($n, $description, $exit_status, $xargs) = @$d;
    if (! defined $xargs)
    {
        $xargs = "";
    }
    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
    {
        my $base = (-f "issue-$n.pdf") ? "issue-$n" : "$n";
        $td->runtest($description,
                     {$td->COMMAND => "qpdf $xargs $base.pdf a.pdf"},
                     {$td->FILE => "$base.out",
                          $td->EXIT_STATUS => $exit_status},
                     $td->NORMALIZE_NEWLINES);
    }
}
cleanup();
$td->report($n_tests);
