aboutsummaryrefslogtreecommitdiffstats
path: root/qpdf/qtest/linearization.test
blob: 02cd778a00e405c4581f548a0284542e17865a48 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#!/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('linearization');

my $n_tests = 0;
# $n_tests incremented after initialization of @linearized_files and
# @to_linearize.

# *'ed files were linearized with Pdlin.
my @linearized_files =
    ('lin0',                    #   not linearized
     'lin1',                    # * outlines, page labels, pdlin
     'lin2',                    # * lin1 with null and newline
     'lin3',                    #   same file saved with acrobat
     'lin4',                    # * lin1 with no /PageMode
     'lin5',                    #   lin3 with embedded thumbnails
     'lin6',                    # * lin5 with pdlin
     'lin7',                    #   lin5 with /PageMode /UseThumbs
     'lin8',                    # * lin7 with pdlin
     'lin9',                    # * shared objects, indirect null
     'badlin1',                 #   parameter dictionary errors
     );

my @to_linearize =
    ('lin-special',             # lots of weird cases -- see file comments
     'delete-and-reuse',        # deleted, reused objects
     'lin-delete-and-reuse',    # linearized, then delete and reuse
     'object-stream',           # contains object streams
     'hybrid-xref',             # contains both xref tables and streams
     'gen1',                    # has objects with generation > 0 and dangling references
     'gen1-no-dangling',        # has objects with generation > 0
     'direct-outlines',         # /Outlines is a direct object
     @linearized_files,         # we should be able to relinearize
     );

$n_tests += @linearized_files + 6;
$n_tests += (3 * @to_linearize * 5) + 7;

foreach my $base (@linearized_files)
{
    $td->runtest("dump linearization: $base",
                 {$td->COMMAND => "qpdf --show-linearization $base.pdf"},
                 {$td->FILE => "$base.out",
                  $td->EXIT_STATUS => ($base eq 'lin0' ? 0 : 3)},
                 $td->NORMALIZE_NEWLINES);
}

# Check normal modified and linearized modified files, making sure
# that their qdf files are identical.  The next two tests have the
# same expected output files and different input files.
check_pdf($td, "modified",
          "qpdf --static-id --qdf --no-original-object-ids" .
          " delete-and-reuse.pdf", "delete-and-reuse.qdf",
          0);
check_pdf($td, "linearized and modified",
          "qpdf --static-id --qdf --no-original-object-ids" .
          " lin-delete-and-reuse.pdf", "delete-and-reuse.qdf", # same output
          0);

$td->runtest("check linearized and modified",
             {$td->COMMAND => "qpdf --check lin-delete-and-reuse.pdf"},
             {$td->FILE => "lin-delete-and-reuse-check.out",
              $td->EXIT_STATUS => 0},
             $td->NORMALIZE_NEWLINES);
$td->runtest("check multiple modifications",
             {$td->COMMAND => "qpdf --check delete-and-reuse.pdf"},
             {$td->FILE => "delete-and-reuse-check.out",
              $td->EXIT_STATUS => 0},
             $td->NORMALIZE_NEWLINES);

foreach my $base (@to_linearize)
{
    foreach my $omode (qw(disable preserve generate))
    {
        my $xflags = 0;
        if ($base eq 'gen1')
        {
            $xflags = $td->EXPECT_FAILURE;
        }
        my $oarg = "-object-streams=$omode";
        my $sdarg = "";
        if (($base eq 'lin-special') || ($base eq 'object-stream'))
        {
            $sdarg = "--stream-data=uncompress";
        }
        unlink "a.pdf", "b.pdf", "c.pdf";
        $td->runtest("linearize $base ($omode)",
                     {$td->COMMAND =>
                          "qpdf -linearize $oarg $sdarg" .
                          " --static-id $base.pdf a.pdf"},
                     {$td->STRING => "", $td->EXIT_STATUS => 0},
                     $xflags);
        $td->runtest("check linearization",
                     {$td->COMMAND => "qpdf --check-linearization a.pdf"},
                     {$td->STRING => "a.pdf: no linearization errors\n",
                      $td->EXIT_STATUS => 0},
                     $td->NORMALIZE_NEWLINES | $xflags);
        # Relinearizing twice should produce identical results.  We
        # have to do it twice because, if objects changed ordering
        # during the original linearization, the hint tables won't
        # exactly match.  This is because object identifiers are
        # inserted into the hint table in their original order since
        # we don't yet have renumbering information when we compute
        # the table values.
        $td->runtest("relinearize $base 1",
                     {$td->COMMAND =>
                          "qpdf -linearize $sdarg --static-id a.pdf b.pdf"},
                     {$td->STRING => "", $td->EXIT_STATUS => 0},
                     $xflags);
        $td->runtest("relinearize $base 2",
                     {$td->COMMAND =>
                          "qpdf -linearize $sdarg --static-id b.pdf c.pdf"},
                     {$td->STRING => "", $td->EXIT_STATUS => 0},
                     $xflags);
        $td->runtest("compare files ($omode)",
                     {$td->FILE => "b.pdf"},
                     {$td->FILE => "c.pdf"},
                     $xflags);
        if (($base eq 'lin-special') || ($base eq 'object-stream'))
        {
            $td->runtest("check $base ($omode)",
                         {$td->FILE => "a.pdf"},
                         {$td->FILE => "$base.$omode.exp"});
        }
    }
}

$td->runtest("suppress linearization warnings",
             {$td->COMMAND => "qpdf --no-warn --check lin3.pdf"},
             {$td->FILE => "lin3-check-nowarn.out", $td->EXIT_STATUS => 3},
             $td->NORMALIZE_NEWLINES);

cleanup();
$td->report($n_tests);