Commit c2023db265ea35ad7d0ab0cd989f16479bcb798d

Authored by Jay Berkenbilt
1 parent c1e53f14

Implement changes suggested by Zarko and our subsequent conversations:

- Add a way to set the minimum PDF version
 - Add a way to force the PDF version
 - Have isEncrypted return true if an /Encrypt dictionary exists even
   when we can't read the file
 - Allow qpdf_init_write to be called multiple times
 - Update some comments in headers


git-svn-id: svn+q:///qpdf/trunk@748 71b93d88-0707-0410-a8cf-f5a4172ac649
ChangeLog
1 1 2009-10-04 Jay Berkenbilt <ejb@ql.org>
2 2  
  3 + * Add methods to QPDFWriter and corresponding command line
  4 + arguments to qpdf to set the minimum output PDF version and also
  5 + to force the version to a particular value.
  6 +
3 7 * libqpdf/QPDF.cc (processXRefStream): warn and ignore extra xref
4 8 stream entries when stream is larger than reported size. This
5 9 used to be a fatal error. (Fixes qpdf-Bugs-2872265.)
... ...
1   -Now
2   -===
3   -
4   - * Add functions to set minimum version and to force pdf version
5   -
6   - * Make multiple calls to init_write safe; document that write
7   - parameter settings must be repeated
8   -
9   - * qpdf_is_encrypted returns false for encrypted file when incorrect
10   - password is given
11   -
12   -
13 1 2.1
14 2 ===
15 3  
... ...
include/qpdf/QPDFWriter.hh
... ... @@ -34,7 +34,13 @@ class Pl_Count;
34 34 class QPDFWriter
35 35 {
36 36 public:
37   - // Passing null as filename means write to stdout
  37 + // Passing null as filename means write to stdout. QPDFWriter
  38 + // will create a zero-length output file upon construction. If
  39 + // write fails, the empty or partially written file will not be
  40 + // deleted. This is by design: sometimes the partial file may be
  41 + // useful for tracking down problems. If your application doesn't
  42 + // want the partially written file to be left behind, you should
  43 + // delete it the eventual call to write fails.
38 44 DLL_EXPORT
39 45 QPDFWriter(QPDF& pdf, char const* filename);
40 46 DLL_EXPORT
... ... @@ -78,6 +84,30 @@ class QPDFWriter
78 84 DLL_EXPORT
79 85 void setQDFMode(bool);
80 86  
  87 + // Set the minimum PDF version. If the PDF version of the input
  88 + // file (or previously set minimum version) is less than the
  89 + // version passed to this method, the PDF version of the output
  90 + // file will be set to this value. If the original PDF file's
  91 + // version or previously set minimum version is already this
  92 + // version or later, the original file's version will be used.
  93 + // QPDFWriter automatically sets the minimum version to 1.4 when
  94 + // R3 encryption parameters are used, and to 1.5 when object
  95 + // streams are used.
  96 + DLL_EXPORT
  97 + void setMinimumPDFVersion(std::string const&);
  98 +
  99 + // Force the PDF version of the output file to be a given version.
  100 + // Use of this function may create PDF files that will not work
  101 + // properly with older PDF viewers. When a PDF version is set
  102 + // using this function, qpdf will use this version even if the
  103 + // file contains features that are not supported in that version
  104 + // of PDF. In other words, you should only use this function if
  105 + // you are sure the PDF file in question has no features of newer
  106 + // versions of PDF or if you are willing to create files that old
  107 + // viewers may try to open but not be able to properly interpret.
  108 + DLL_EXPORT
  109 + void forcePDFVersion(std::string const&);
  110 +
81 111 // Cause a static /ID value to be generated. Use only in test
82 112 // suites.
83 113 DLL_EXPORT
... ... @@ -241,6 +271,7 @@ class QPDFWriter
241 271 std::string id1; // for /ID key of
242 272 std::string id2; // trailer dictionary
243 273 std::string min_pdf_version;
  274 + std::string forced_pdf_version;
244 275 int encryption_dict_objid;
245 276 std::string cur_data_key;
246 277 std::list<PointerHolder<Pipeline> > to_delete;
... ...
include/qpdf/qpdf-c.h
... ... @@ -189,7 +189,12 @@ extern &quot;C&quot; {
189 189 /* Supply the name of the file to be written and initialize the
190 190 * qpdf_data object to handle writing operations. This function
191 191 * also attempts to create the file. The PDF data is not written
192   - * until the call to qpdf_write.
  192 + * until the call to qpdf_write. qpdf_init_write may be called
  193 + * multiple times for the same qpdf_data object. When
  194 + * qpdf_init_write is called, all information from previous calls
  195 + * to functions that set write parameters (qpdf_set_linearization,
  196 + * etc.) is lost, so any write parameter functions must be called
  197 + * again.
193 198 */
194 199 DLL_EXPORT
195 200 QPDF_ERROR_CODE qpdf_init_write(qpdf_data qpdf, char const* filename);
... ... @@ -256,6 +261,12 @@ extern &quot;C&quot; {
256 261 DLL_EXPORT
257 262 void qpdf_set_linearization(qpdf_data qpdf, QPDF_BOOL value);
258 263  
  264 + DLL_EXPORT
  265 + void qpdf_set_minimum_pdf_version(qpdf_data qpdf, char const* version);
  266 +
  267 + DLL_EXPORT
  268 + void qpdf_force_pdf_version(qpdf_data qpdf, char const* version);
  269 +
259 270 /* Do actual write operation. */
260 271 DLL_EXPORT
261 272 QPDF_ERROR_CODE qpdf_write(qpdf_data qpdf);
... ...
libqpdf/QPDFWriter.cc
... ... @@ -100,6 +100,37 @@ QPDFWriter::setQDFMode(bool val)
100 100 }
101 101  
102 102 void
  103 +QPDFWriter::setMinimumPDFVersion(std::string const& version)
  104 +{
  105 + bool set_version = false;
  106 + if (this->min_pdf_version.empty())
  107 + {
  108 + set_version = true;
  109 + }
  110 + else
  111 + {
  112 + float v = atof(version.c_str());
  113 + float mv = atof(this->min_pdf_version.c_str());
  114 + if (v > mv)
  115 + {
  116 + QTC::TC("qpdf", "QPDFWriter increasing minimum version");
  117 + set_version = true;
  118 + }
  119 + }
  120 +
  121 + if (set_version)
  122 + {
  123 + this->min_pdf_version = version;
  124 + }
  125 +}
  126 +
  127 +void
  128 +QPDFWriter::forcePDFVersion(std::string const& version)
  129 +{
  130 + this->forced_pdf_version = version;
  131 +}
  132 +
  133 +void
103 134 QPDFWriter::setStaticID(bool val)
104 135 {
105 136 this->static_id = val;
... ... @@ -147,7 +178,7 @@ QPDFWriter::setR2EncryptionParameters(
147 178 clear.insert(6);
148 179 }
149 180  
150   - this->min_pdf_version = "1.3";
  181 + setMinimumPDFVersion("1.3");
151 182 setEncryptionParameters(user_password, owner_password, 1, 2, 5, clear);
152 183 }
153 184  
... ... @@ -221,7 +252,7 @@ QPDFWriter::setR3EncryptionParameters(
221 252 // no default so gcc warns for missing cases
222 253 }
223 254  
224   - this->min_pdf_version = "1.4";
  255 + setMinimumPDFVersion("1.4");
225 256 setEncryptionParameters(user_password, owner_password, 2, 3, 16, clear);
226 257 }
227 258  
... ... @@ -1361,7 +1392,7 @@ QPDFWriter::write()
1361 1392  
1362 1393 if (! this->object_stream_to_objects.empty())
1363 1394 {
1364   - this->min_pdf_version = "1.5";
  1395 + setMinimumPDFVersion("1.5");
1365 1396 }
1366 1397  
1367 1398 generateID();
... ... @@ -1417,15 +1448,12 @@ QPDFWriter::writeEncryptionDictionary()
1417 1448 void
1418 1449 QPDFWriter::writeHeader()
1419 1450 {
1420   - std::string version = pdf.getPDFVersion();
1421   - if (! this->min_pdf_version.empty())
  1451 + setMinimumPDFVersion(pdf.getPDFVersion());
  1452 + std::string version = this->min_pdf_version;
  1453 + if (! this->forced_pdf_version.empty())
1422 1454 {
1423   - float ov = atof(version.c_str());
1424   - float mv = atof(this->min_pdf_version.c_str());
1425   - if (mv > ov)
1426   - {
1427   - version = this->min_pdf_version;
1428   - }
  1455 + QTC::TC("qpdf", "QPDFWriter using forced PDF version");
  1456 + version = this->forced_pdf_version;
1429 1457 }
1430 1458  
1431 1459 writeString("%PDF-");
... ...
libqpdf/QPDF_encryption.cc
... ... @@ -289,6 +289,11 @@ QPDF::initializeEncryption()
289 289 return;
290 290 }
291 291  
  292 + // Go ahead and set this->encryption here. That way, isEncrypted
  293 + // will return true even if there were errors reading the
  294 + // encryption dictionary.
  295 + this->encrypted = true;
  296 +
292 297 QPDFObjectHandle id_obj = this->trailer.getKey("/ID");
293 298 if (! (id_obj.isArray() &&
294 299 (id_obj.getArrayNItems() == 2) &&
... ... @@ -377,7 +382,6 @@ QPDF::initializeEncryption()
377 382 throw QPDFExc(this->file.getName() + ": invalid password");
378 383 }
379 384  
380   - this->encrypted = true;
381 385 this->encryption_key = compute_encryption_key(this->user_password, data);
382 386 }
383 387  
... ...
libqpdf/qpdf-c.cc
... ... @@ -252,6 +252,12 @@ DLL_EXPORT
252 252 QPDF_ERROR_CODE qpdf_init_write(qpdf_data qpdf, char const* filename)
253 253 {
254 254 QPDF_ERROR_CODE status = QPDF_SUCCESS;
  255 + if (qpdf->qpdf_writer)
  256 + {
  257 + QTC::TC("qpdf", "qpdf-c called qpdf_init_write multiple times");
  258 + delete qpdf->qpdf_writer;
  259 + qpdf->qpdf_writer = 0;
  260 + }
255 261 try
256 262 {
257 263 qpdf->qpdf_writer = new QPDFWriter(*(qpdf->qpdf), filename);
... ... @@ -391,6 +397,20 @@ void qpdf_set_linearization(qpdf_data qpdf, QPDF_BOOL value)
391 397 }
392 398  
393 399 DLL_EXPORT
  400 +void qpdf_set_minimum_pdf_version(qpdf_data qpdf, char const* version)
  401 +{
  402 + QTC::TC("qpdf", "qpdf-c called qpdf_set_minimum_pdf_version");
  403 + qpdf->qpdf_writer->setMinimumPDFVersion(version);
  404 +}
  405 +
  406 +DLL_EXPORT
  407 +void qpdf_force_pdf_version(qpdf_data qpdf, char const* version)
  408 +{
  409 + QTC::TC("qpdf", "qpdf-c called qpdf_force_pdf_version");
  410 + qpdf->qpdf_writer->forcePDFVersion(version);
  411 +}
  412 +
  413 +DLL_EXPORT
394 414 QPDF_ERROR_CODE qpdf_write(qpdf_data qpdf)
395 415 {
396 416 QPDF_ERROR_CODE status = QPDF_SUCCESS;
... ...
qpdf/qpdf-ctest.c
... ... @@ -20,7 +20,8 @@ static void report_errors()
20 20  
21 21 static void test01(char const* infile,
22 22 char const* password,
23   - char const* outfile)
  23 + char const* outfile,
  24 + char const* outfile2)
24 25 {
25 26 qpdf_read(qpdf, infile, password);
26 27 printf("version: %s\n", qpdf_get_pdf_version(qpdf));
... ... @@ -53,7 +54,8 @@ static void test01(char const* infile,
53 54  
54 55 static void test02(char const* infile,
55 56 char const* password,
56   - char const* outfile)
  57 + char const* outfile,
  58 + char const* outfile2)
57 59 {
58 60 qpdf_set_suppress_warnings(qpdf, QPDF_TRUE);
59 61 if (((qpdf_read(qpdf, infile, password) & QPDF_ERRORS) == 0) &&
... ... @@ -67,7 +69,8 @@ static void test02(char const* infile,
67 69  
68 70 static void test03(char const* infile,
69 71 char const* password,
70   - char const* outfile)
  72 + char const* outfile,
  73 + char const* outfile2)
71 74 {
72 75 qpdf_read(qpdf, infile, password);
73 76 qpdf_init_write(qpdf, outfile);
... ... @@ -79,7 +82,8 @@ static void test03(char const* infile,
79 82  
80 83 static void test04(char const* infile,
81 84 char const* password,
82   - char const* outfile)
  85 + char const* outfile,
  86 + char const* outfile2)
83 87 {
84 88 qpdf_set_ignore_xref_streams(qpdf, QPDF_TRUE);
85 89 qpdf_read(qpdf, infile, password);
... ... @@ -91,7 +95,8 @@ static void test04(char const* infile,
91 95  
92 96 static void test05(char const* infile,
93 97 char const* password,
94   - char const* outfile)
  98 + char const* outfile,
  99 + char const* outfile2)
95 100 {
96 101 qpdf_read(qpdf, infile, password);
97 102 qpdf_init_write(qpdf, outfile);
... ... @@ -103,7 +108,8 @@ static void test05(char const* infile,
103 108  
104 109 static void test06(char const* infile,
105 110 char const* password,
106   - char const* outfile)
  111 + char const* outfile,
  112 + char const* outfile2)
107 113 {
108 114 qpdf_read(qpdf, infile, password);
109 115 qpdf_init_write(qpdf, outfile);
... ... @@ -115,7 +121,8 @@ static void test06(char const* infile,
115 121  
116 122 static void test07(char const* infile,
117 123 char const* password,
118   - char const* outfile)
  124 + char const* outfile,
  125 + char const* outfile2)
119 126 {
120 127 qpdf_read(qpdf, infile, password);
121 128 qpdf_init_write(qpdf, outfile);
... ... @@ -127,7 +134,8 @@ static void test07(char const* infile,
127 134  
128 135 static void test08(char const* infile,
129 136 char const* password,
130   - char const* outfile)
  137 + char const* outfile,
  138 + char const* outfile2)
131 139 {
132 140 qpdf_read(qpdf, infile, password);
133 141 qpdf_init_write(qpdf, outfile);
... ... @@ -140,7 +148,8 @@ static void test08(char const* infile,
140 148  
141 149 static void test09(char const* infile,
142 150 char const* password,
143   - char const* outfile)
  151 + char const* outfile,
  152 + char const* outfile2)
144 153 {
145 154 qpdf_read(qpdf, infile, password);
146 155 qpdf_init_write(qpdf, outfile);
... ... @@ -152,7 +161,8 @@ static void test09(char const* infile,
152 161  
153 162 static void test10(char const* infile,
154 163 char const* password,
155   - char const* outfile)
  164 + char const* outfile,
  165 + char const* outfile2)
156 166 {
157 167 qpdf_set_attempt_recovery(qpdf, QPDF_FALSE);
158 168 qpdf_read(qpdf, infile, password);
... ... @@ -161,7 +171,8 @@ static void test10(char const* infile,
161 171  
162 172 static void test11(char const* infile,
163 173 char const* password,
164   - char const* outfile)
  174 + char const* outfile,
  175 + char const* outfile2)
165 176 {
166 177 qpdf_read(qpdf, infile, password);
167 178 qpdf_init_write(qpdf, outfile);
... ... @@ -174,7 +185,8 @@ static void test11(char const* infile,
174 185  
175 186 static void test12(char const* infile,
176 187 char const* password,
177   - char const* outfile)
  188 + char const* outfile,
  189 + char const* outfile2)
178 190 {
179 191 qpdf_read(qpdf, infile, password);
180 192 qpdf_init_write(qpdf, outfile);
... ... @@ -188,7 +200,8 @@ static void test12(char const* infile,
188 200  
189 201 static void test13(char const* infile,
190 202 char const* password,
191   - char const* outfile)
  203 + char const* outfile,
  204 + char const* outfile2)
192 205 {
193 206 qpdf_read(qpdf, infile, password);
194 207 printf("user password: %s\n", qpdf_get_user_password(qpdf));
... ... @@ -199,15 +212,33 @@ static void test13(char const* infile,
199 212 report_errors();
200 213 }
201 214  
  215 +static void test14(char const* infile,
  216 + char const* password,
  217 + char const* outfile,
  218 + char const* outfile2)
  219 +{
  220 + qpdf_read(qpdf, infile, password);
  221 + qpdf_init_write(qpdf, outfile);
  222 + qpdf_set_static_ID(qpdf, QPDF_TRUE);
  223 + qpdf_set_minimum_pdf_version(qpdf, "1.6");
  224 + qpdf_write(qpdf);
  225 + qpdf_init_write(qpdf, outfile2);
  226 + qpdf_set_static_ID(qpdf, QPDF_TRUE);
  227 + qpdf_force_pdf_version(qpdf, "1.4");
  228 + qpdf_write(qpdf);
  229 + report_errors();
  230 +}
  231 +
202 232 int main(int argc, char* argv[])
203 233 {
204 234 char* whoami = 0;
205 235 char* p = 0;
206 236 int n = 0;
207   - char const* infile;
208   - char const* password;
209   - char const* outfile;
210   - void (*fn)(char const*, char const*, char const*) = 0;
  237 + char const* infile = 0;
  238 + char const* password = 0;
  239 + char const* outfile = 0;
  240 + char const* outfile2 = 0;
  241 + void (*fn)(char const*, char const*, char const*, char const*) = 0;
211 242  
212 243 if ((p = strrchr(argv[0], '/')) != NULL)
213 244 {
... ... @@ -221,7 +252,7 @@ int main(int argc, char* argv[])
221 252 {
222 253 whoami = argv[0];
223 254 }
224   - if (argc != 5)
  255 + if (argc < 5)
225 256 {
226 257 fprintf(stderr, "usage: %s n infile password outfile\n", whoami);
227 258 exit(2);
... ... @@ -231,6 +262,7 @@ int main(int argc, char* argv[])
231 262 infile = argv[2];
232 263 password = argv[3];
233 264 outfile = argv[4];
  265 + outfile2 = (argc > 5 ? argv[5] : 0);
234 266  
235 267 fn = ((n == 1) ? test01 :
236 268 (n == 2) ? test02 :
... ... @@ -245,6 +277,7 @@ int main(int argc, char* argv[])
245 277 (n == 11) ? test11 :
246 278 (n == 12) ? test12 :
247 279 (n == 13) ? test13 :
  280 + (n == 14) ? test14 :
248 281 0);
249 282  
250 283 if (fn == 0)
... ... @@ -254,7 +287,7 @@ int main(int argc, char* argv[])
254 287 }
255 288  
256 289 qpdf = qpdf_init();
257   - fn(infile, password, outfile);
  290 + fn(infile, password, outfile, outfile2);
258 291 qpdf_cleanup(&qpdf);
259 292 assert(qpdf == 0);
260 293  
... ...
qpdf/qpdf.cc
... ... @@ -103,6 +103,8 @@ familiar with the PDF file format or who are PDF developers.\n\
103 103 --object-streams=mode controls handing of object streams\n\
104 104 --ignore-xref-streams tells qpdf to ignore any cross-reference streams\n\
105 105 --qdf turns on \"QDF mode\" (below)\n\
  106 +--min-version=version sets the minimum PDF version of the output file\n\
  107 +--force-version=version forces this to be the PDF version of the output file\n\
106 108 \n\
107 109 Values for stream data options:\n\
108 110 \n\
... ... @@ -119,6 +121,12 @@ Values for object stream mode:\n\
119 121 In qdf mode, by default, content normalization is turned on, and the\n\
120 122 stream data mode is set to uncompress.\n\
121 123 \n\
  124 +Setting the minimum PDF version of the output file may raise the version\n\
  125 +but will never lower it. Forcing the PDF version of the output file may\n\
  126 +set the PDF version to a lower value than actually allowed by the file's\n\
  127 +contents. You should only do this if you have no other possible way to\n\
  128 +open the file or if you know that the file definitely doesn't include\n\
  129 +features not supported later versions.\n\
122 130 \n\
123 131 Testing, Inspection, and Debugging Options\n\
124 132 ------------------------------------------\n\
... ... @@ -518,6 +526,8 @@ int main(int argc, char* argv[])
518 526 QPDFWriter::object_stream_e object_stream_mode = QPDFWriter::o_preserve;
519 527 bool ignore_xref_streams = false;
520 528 bool qdf_mode = false;
  529 + std::string min_version;
  530 + std::string force_version;
521 531  
522 532 bool static_id = false;
523 533 bool suppress_original_object_id = false;
... ... @@ -651,6 +661,24 @@ int main(int argc, char* argv[])
651 661 {
652 662 qdf_mode = true;
653 663 }
  664 + else if (strcmp(arg, "min-version") == 0)
  665 + {
  666 + if (parameter == 0)
  667 + {
  668 + usage("--min-version be given as"
  669 + "--min-version=version");
  670 + }
  671 + min_version = parameter;
  672 + }
  673 + else if (strcmp(arg, "force-version") == 0)
  674 + {
  675 + if (parameter == 0)
  676 + {
  677 + usage("--force-version be given as"
  678 + "--force-version=version");
  679 + }
  680 + force_version = parameter;
  681 + }
654 682 else if (strcmp(arg, "static-id") == 0)
655 683 {
656 684 static_id = true;
... ... @@ -977,6 +1005,14 @@ int main(int argc, char* argv[])
977 1005 {
978 1006 w.setObjectStreamMode(object_stream_mode);
979 1007 }
  1008 + if (! min_version.empty())
  1009 + {
  1010 + w.setMinimumPDFVersion(min_version);
  1011 + }
  1012 + if (! force_version.empty())
  1013 + {
  1014 + w.forcePDFVersion(force_version);
  1015 + }
980 1016 w.write();
981 1017 }
982 1018 if (! pdf.getWarnings().empty())
... ...
qpdf/qpdf.testcov
... ... @@ -153,3 +153,8 @@ qpdf-c called qpdf_allow_modify_form 0
153 153 qpdf-c called qpdf_allow_modify_annotation 0
154 154 qpdf-c called qpdf_allow_modify_other 0
155 155 qpdf-c called qpdf_allow_modify_all 0
  156 +QPDFWriter increasing minimum version 0
  157 +QPDFWriter using forced PDF version 0
  158 +qpdf-c called qpdf_set_minimum_pdf_version 0
  159 +qpdf-c called qpdf_force_pdf_version 0
  160 +qpdf-c called qpdf_init_write multiple times 0
... ...
qpdf/qtest/qpdf.test
... ... @@ -81,7 +81,7 @@ flush_tiff_cache();
81 81 show_ntests();
82 82 # ----------
83 83 $td->notify("--- Miscellaneous Tests ---");
84   -$n_tests += 7;
  84 +$n_tests += 14;
85 85  
86 86 foreach (my $i = 1; $i <= 3; ++$i)
87 87 {
... ... @@ -115,6 +115,44 @@ $td-&gt;runtest(&quot;show new xref stream&quot;,
115 115 $td->EXIT_STATUS => 0},
116 116 $td->NORMALIZE_NEWLINES);
117 117  
  118 +# Min/Force version
  119 +$td->runtest("set min version",
  120 + {$td->COMMAND => "qpdf --min-version=1.6 good1.pdf a.pdf"},
  121 + {$td->STRING => "",
  122 + $td->EXIT_STATUS => 0},
  123 + $td->NORMALIZE_NEWLINES);
  124 +$td->runtest("check version",
  125 + {$td->COMMAND => "qpdf --check a.pdf"},
  126 + {$td->FILE => "min-version.out",
  127 + $td->EXIT_STATUS => 0},
  128 + $td->NORMALIZE_NEWLINES);
  129 +$td->runtest("force version",
  130 + {$td->COMMAND => "qpdf --force-version=1.4 a.pdf b.pdf"},
  131 + {$td->STRING => "",
  132 + $td->EXIT_STATUS => 0},
  133 + $td->NORMALIZE_NEWLINES);
  134 +$td->runtest("check version",
  135 + {$td->COMMAND => "qpdf --check b.pdf"},
  136 + {$td->FILE => "forced-version.out",
  137 + $td->EXIT_STATUS => 0},
  138 + $td->NORMALIZE_NEWLINES);
  139 +unlink "a.pdf", "b.pdf" or die;
  140 +$td->runtest("C API: min/force versions",
  141 + {$td->COMMAND => "qpdf-ctest 14 object-stream.pdf '' a.pdf b.pdf"},
  142 + {$td->STRING => "",
  143 + $td->EXIT_STATUS => 0},
  144 + $td->NORMALIZE_NEWLINES);
  145 +$td->runtest("C check version 1",
  146 + {$td->COMMAND => "qpdf --check a.pdf"},
  147 + {$td->FILE => "min-version.out",
  148 + $td->EXIT_STATUS => 0},
  149 + $td->NORMALIZE_NEWLINES);
  150 +$td->runtest("C check version 2",
  151 + {$td->COMMAND => "qpdf --check b.pdf"},
  152 + {$td->FILE => "forced-version.out",
  153 + $td->EXIT_STATUS => 0},
  154 + $td->NORMALIZE_NEWLINES);
  155 +
118 156 show_ntests();
119 157 # ----------
120 158 $td->notify("--- Error Condition Tests ---");
... ... @@ -883,7 +921,7 @@ foreach my $d (@cenc)
883 921 my ($n, $infile, $pass, $description, $output) = @$d;
884 922 my $outfile = $description;
885 923 $outfile =~ s/ /-/g;
886   - my $outfile = "c-$outfile.pdf";
  924 + $outfile = "c-$outfile.pdf";
887 925 $td->runtest("C API encryption: $description",
888 926 {$td->COMMAND => "qpdf-ctest $n $infile $pass a.pdf"},
889 927 {$td->STRING => $output, $td->EXIT_STATUS => 0},
... ...
qpdf/qtest/qpdf/forced-version.out 0 → 100644
  1 +checking b.pdf
  2 +PDF Version: 1.4
  3 +File is not encrypted
  4 +File is not linearized
  5 +No errors found
... ...
qpdf/qtest/qpdf/min-version.out 0 → 100644
  1 +checking a.pdf
  2 +PDF Version: 1.6
  3 +File is not encrypted
  4 +File is not linearized
  5 +No errors found
... ...