#!/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; my $td = new TestDriver('large-file'); my $large_file_test_path = $ENV{'QPDF_LARGE_FILE_TEST_PATH'} || undef; if (defined($large_file_test_path)) { $large_file_test_path = File::Spec->rel2abs($large_file_test_path); $large_file_test_path =~ s!\\!/!g; } large_cleanup(); my $nlarge = 1; if (defined $large_file_test_path) { $nlarge = 2; } else { $td->notify("--- Skipping tests on actual large files ---"); } my $n_tests = $nlarge * 21; for (my $large = 0; $large < $nlarge; ++$large) { my $now = time(); my $show_time = sub {}; if ($large) { $td->notify("--- Running tests on actual large files ---"); $show_time = sub { $td->notify("--- time: " . (time() - $now)); }; } else { $td->notify("--- Running large file tests on small files ---"); } my $size = ($large ? "large" : "small"); my $file = $large ? "$large_file_test_path/a.pdf" : "a.pdf"; my $json = $large ? "$large_file_test_path/a.json" : "a.json"; # Pick a stream near the end of the file to test. my $stream = $large ? "$large_file_test_path/a.json-603" : "a.json-603"; $now = time(); $td->runtest("write test file", {$td->COMMAND => "test_large_file write $size '$file'"}, {$td->FILE => "large_file.out", $td->EXIT_STATUS => 0}, $td->NORMALIZE_NEWLINES); &$show_time(); $now = time(); $td->runtest("read test file", {$td->COMMAND => "test_large_file read $size '$file'"}, {$td->FILE => "large_file.out", $td->EXIT_STATUS => 0}, $td->NORMALIZE_NEWLINES); &$show_time(); $td->runtest("check", {$td->COMMAND => "qpdf --suppress-recovery --check '$file'", $td->FILTER => "grep -v checking"}, {$td->FILE => "large_file-check-normal.out", $td->EXIT_STATUS => 0}, $td->NORMALIZE_NEWLINES); $now = time(); $td->runtest("large to json inline", {$td->COMMAND => "qpdf --json-output '$file' '$json'"}, {$td->STRING => "", $td->EXIT_STATUS => 0}); &$show_time(); $now = time(); $td->runtest("json inline to large", {$td->COMMAND => "qpdf --json-input --compress-streams=n" . " --static-id '$json' '$file'"}, {$td->STRING => "", $td->EXIT_STATUS => 0}); &$show_time(); $td->runtest("read test file", {$td->COMMAND => "test_large_file read $size '$file'"}, {$td->FILE => "large_file.out", $td->EXIT_STATUS => 0}, $td->NORMALIZE_NEWLINES); $now = time(); $td->runtest("large to json with file", {$td->COMMAND => "qpdf --json-output --json-stream-data=file" . " '$file' '$json'"}, {$td->STRING => "", $td->EXIT_STATUS => 0}); &$show_time(); $td->runtest("inspect json", {$td->FILE => $json, $td->FILTER => "perl filter-json.pl"}, {$td->FILE => "exp-large-json.json"}, $td->NORMALIZE_NEWLINES); $td->runtest("spot check stream", {$td->FILE => $stream}, {$td->FILE => "exp-large-stream"}, $td->NORMALIZE_NEWLINES); $now = time(); $td->runtest("json with file to large", {$td->COMMAND => "qpdf --json-input" . " --compress-streams=n '$json' '$file'"}, {$td->STRING => "", $td->EXIT_STATUS => 0}); &$show_time(); $td->runtest("read test file", {$td->COMMAND => "test_large_file read $size '$file'"}, {$td->FILE => "large_file.out", $td->EXIT_STATUS => 0}, $td->NORMALIZE_NEWLINES); for my $ostream (0, 1) { for my $linearize (0, 1) { if (($ostream == 0) && ($linearize == 0)) { # Original file has no object streams and is not linearized. next; } my $args = ""; my $omode = $ostream ? "generate" : "disable"; my $lin = $linearize ? "--linearize" : ""; my $newfile = "$file-new"; $td->runtest("transform: ostream=$ostream, linearize=$linearize", {$td->COMMAND => "qpdf --stream-data=preserve" . " --object-streams=$omode" . " $lin '$file' '$newfile'"}, {$td->STRING => "", $td->EXIT_STATUS => 0}); $td->runtest("read: ostream=$ostream, linearize=$linearize", {$td->COMMAND => "test_large_file read $size '$newfile'"}, {$td->FILE => "large_file.out", $td->EXIT_STATUS => 0}, $td->NORMALIZE_NEWLINES); my $check_out = ($linearize ? ($ostream ? "large_file-check-ostream-linearized.out" : "large_file-check-linearized.out") : ($ostream ? "large_file-check-ostream.out" : "large_file-check-normal.out")); $td->runtest("check: ostream=$ostream, linearize=$linearize", {$td->COMMAND => "qpdf --suppress-recovery --check '$newfile'", $td->FILTER => "grep -v checking"}, {$td->FILE => $check_out, $td->EXIT_STATUS => 0}, $td->NORMALIZE_NEWLINES); unlink $newfile; } } # Clobber xref open(F, "+<$file") or die; seek(F, -50, 2); my $pos = tell F; my $buf; read(F, $buf, 50); die unless $buf =~ m/^(.*startxref\n)\d+/s; $pos += length($1); seek(F, $pos, 0) or die; print F "oops" or die; close(F); my $cmd = +{$td->COMMAND => "test_large_file read $size '$file'"}; if ($large) { $cmd->{$td->FILTER} = "sed -e 's,$large_file_test_path/,,'"; } $td->runtest("reconstruct xref table", $cmd, {$td->FILE => "large_file_xref_reconstruct.out", $td->EXIT_STATUS => 0}, $td->NORMALIZE_NEWLINES); unlink $file; large_cleanup(); } large_cleanup(); sub large_cleanup { cleanup(); system("rm -f a.json* a.pdf*"); if (defined $large_file_test_path) { system("rm -f $large_file_test_path/a.pdf*" . " $large_file_test_path/a.json*"); } } $td->report($n_tests);