Commit 647b9831dc5cb2f2bfe775a8802416cdd51ed59d

Authored by Jay Berkenbilt
1 parent a238b4b0

Have qpdf-test-compare handle certain /ID differences

Rationale is in comments in the code. Deterministic ID tests
explicitly do not use this tool.
compare-for-test/qpdf-test-compare.cc
... ... @@ -24,7 +24,7 @@ usage()
24 24 << std::endl
25 25 << "If the files match, the output is the expected file. Otherwise, it is"
26 26 << std::endl
27   - << "the actual file. Read comments in the test suite for rationale." << std::endl;
  27 + << "the actual file. Read comments in the code for rationale." << std::endl;
28 28 exit(2);
29 29 }
30 30  
... ... @@ -50,6 +50,8 @@ compareObjects(std::string const&amp; label, QPDFObjectHandle act, QPDFObjectHandle
50 50 return label + ": different types";
51 51 }
52 52 if (act.isStream()) {
  53 + // Disregard stream lengths. The length of stream data is compared later, and we don't care
  54 + // about the length of compressed data as long as the uncompressed data matches.
53 55 auto act_dict = act.getDict();
54 56 auto exp_dict = exp.getDict();
55 57 act_dict.removeKey("/Length");
... ... @@ -59,6 +61,8 @@ compareObjects(std::string const&amp; label, QPDFObjectHandle act, QPDFObjectHandle
59 61 return label + ": stream dictionaries differ";
60 62 }
61 63 if (act_dict.getKey("/Type").isNameAndEquals("/XRef")) {
  64 + // Cross-reference streams will generally not match, but we have numerous tests that
  65 + // meaningfully ensure that xref streams are correct.
62 66 QTC::TC("compare", "ignore data for xref stream");
63 67 return "";
64 68 }
... ... @@ -103,6 +107,27 @@ compareObjects(std::string const&amp; label, QPDFObjectHandle act, QPDFObjectHandle
103 107 return "";
104 108 }
105 109  
  110 +void
  111 +cleanTrailer(QPDFObjectHandle& trailer)
  112 +{
  113 + // If the trailer is an object stream, it will have /Length.
  114 + trailer.removeKey("/Length");
  115 + // Disregard the second half of /ID. This doesn't have anything directly to do with zlib, but
  116 + // lots of tests use --deterministic-id, and that is affected. The deterministic ID tests
  117 + // meaningfully exercise that deterministic IDs behave as expected, so for the rest of the
  118 + // tests, it's okay to ignore /ID[1]. If the two halves of /ID are the same, ignore both since
  119 + // this means qpdf completely generated the /ID rather than preserving the first half.
  120 + auto id = trailer.getKey("/ID");
  121 + if (id.isArray() && id.getArrayNItems() == 2) {
  122 + auto id0 = id.getArrayItem(0).unparse();
  123 + auto id1 = id.getArrayItem(1).unparse();
  124 + id.setArrayItem(1, "()"_qpdf);
  125 + if (id0 == id1) {
  126 + id.setArrayItem(0, "()"_qpdf);
  127 + }
  128 + }
  129 +}
  130 +
106 131 std::string
107 132 compare(char const* actual_filename, char const* expected_filename)
108 133 {
... ... @@ -118,8 +143,8 @@ compare(char const* actual_filename, char const* expected_filename)
118 143  
119 144 auto act_trailer = actual.getTrailer();
120 145 auto exp_trailer = expected.getTrailer();
121   - act_trailer.removeKey("/Length");
122   - exp_trailer.removeKey("/Length");
  146 + cleanTrailer(act_trailer);
  147 + cleanTrailer(exp_trailer);
123 148 auto trailer_diff = compareObjects("trailer", act_trailer, exp_trailer);
124 149 if (!trailer_diff.empty()) {
125 150 QTC::TC("compare", "different trailer");
... ...
compare-for-test/qtest/compare.test
... ... @@ -52,6 +52,7 @@ my @diff = (
52 52 ["diff-data-unc.pdf", "5,0: stream data differs"],
53 53 ["diff-stream-dict.pdf", "4,0: stream dictionaries differ"],
54 54 ["diff-object-type.pdf", "6,0: different types"],
  55 + ["diff-id.pdf", "trailer: object contents differ"],
55 56 );
56 57 $n_tests += 2 * scalar(@diff);
57 58  
... ... @@ -90,4 +91,12 @@ $td-&gt;runtest(&quot;compare object stream files (same)&quot;,
90 91 {$td->COMMAND => "env QPDF_COMPARE_WHY=1 qpdf-test-compare ostream1.pdf ostream2.pdf"},
91 92 {$td->FILE => "ostream2.pdf", $td->EXIT_STATUS => 0});
92 93  
  94 +$n_tests += 2;
  95 +$td->runtest("files identical except /ID[1]",
  96 + {$td->COMMAND => "env QPDF_COMPARE_WHY=1 qpdf-test-compare zlib.pdf zlib-new-id.pdf"},
  97 + {$td->FILE => "zlib-new-id.pdf", $td->EXIT_STATUS => 0});
  98 +$td->runtest("/ID[0] = /ID[1]",
  99 + {$td->COMMAND => "env QPDF_COMPARE_WHY=1 qpdf-test-compare zlib-new-id1.pdf zlib-new-id2.pdf"},
  100 + {$td->FILE => "zlib-new-id2.pdf", $td->EXIT_STATUS => 0});
  101 +
93 102 $td->report($n_tests);
... ...
compare-for-test/qtest/compare/diff-id.pdf 0 → 100644
No preview for this file type
compare-for-test/qtest/compare/zlib-new-id.pdf 0 → 100644
No preview for this file type
compare-for-test/qtest/compare/zlib-new-id1.pdf 0 → 100644
No preview for this file type
compare-for-test/qtest/compare/zlib-new-id2.pdf 0 → 100644
No preview for this file type