Commit ea96330bb615791de58a4f6beb6203137fe1ba35

Authored by Jay Berkenbilt
1 parent 47f33cec

QPDFJob json: flatten json structure

Flatten everything to make it easier to map command-line flags to
json. The old structure was an illusion anyway because there was no
mechanism to enforce that things were in the right place. This also
helps with future flexibility.
generate_auto_job
... ... @@ -562,7 +562,7 @@ class Main:
562 562  
563 563 def generate_schema(self, data):
564 564 # Check to make sure that every command-line option is
565   - # represented either in data['json'] or data['no-json'].
  565 + # represented in data['json'].
566 566  
567 567 # Build a list of options that we expect. If an option appears
568 568 # once, we just expect to see it once. If it appears in more
... ... @@ -578,7 +578,7 @@ class Main:
578 578 else:
579 579 for t in sorted(tables):
580 580 expected[f'{t}.{k}'] = {**v}
581   - options_seen = set(data['no-json'])
  581 + options_seen = set()
582 582  
583 583 # Walk through the json information building the schema as we
584 584 # go. This verifies consistency between command-line options
... ... @@ -600,7 +600,7 @@ class Main:
600 600  
601 601 def validate(self, data):
602 602 self.check_keys('top', data, set(
603   - ['choices', 'options', 'no-json', 'json']))
  603 + ['choices', 'options', 'json']))
604 604 for o in data['options']:
605 605 self.check_keys('top', o, set(
606 606 ['table', 'prefix', 'config', 'config_prefix',
... ...
job.sums
1 1 # Generated by generate_auto_job
2   -generate_auto_job ef1b438aeebed7ca0afcbe4d1f9c54d3acf899aec8410ebc69cd15ec673dd158
  2 +generate_auto_job 905fed38c06d258af617ac909bed78a7888a5eaba3f14cf143168665f6e90a86
3 3 include/qpdf/auto_job_c_att.hh 7ad43bb374c1370ef32ebdcdcb7b73a61d281f7f4e3f12755585872ab30fb60e
4 4 include/qpdf/auto_job_c_copy_att.hh 32275d03cdc69b703dd7e02ba0bbe15756e714e9ad185484773a6178dc09e1ee
5 5 include/qpdf/auto_job_c_enc.hh 72e138c7b96ed5aacdce78c1dec04b1c20d361faec4f8faf52f64c1d6be99265
6 6 include/qpdf/auto_job_c_main.hh ff776dd643279330fbf59770d1abf5aaeb13f20bfc5f6a25997aaa72a0907b44
7 7 include/qpdf/auto_job_c_pages.hh 931840b329a36ca0e41401190e04537b47f2867671a6643bfd8da74014202671
8 8 include/qpdf/auto_job_c_uo.hh 0585b7de459fa479d9e51a45fa92de0ff6dee748efc9ec1cedd0dde6cee1ad50
9   -job.yml c3e714b3c3e2fc85390d983302ff398aa0992c621e85dbcaee20173b1bd3cb0b
  9 +job.yml 92565dc8023ea880aca5b96c2620f756642a6dafa5ed15546bc2c777c31b218e
10 10 libqpdf/qpdf/auto_job_decl.hh 9f79396ec459f191be4c5fe34cf88c265cf47355a1a945fa39169d1c94cf04f6
11 11 libqpdf/qpdf/auto_job_help.hh a0ab6ab4dde2ad3d3f17ecae3ea274919119329e075061f3a3973535f5e367de
12 12 libqpdf/qpdf/auto_job_init.hh c244e03e8b83ed7db732920f40aff0134e5f2e78a6edb9473ea4dd1934a8953e
13   -libqpdf/qpdf/auto_job_json_decl.hh 741a44106f7850b6cbc8af264b5b77bb605475c8d8dd8cd87011d5debbee6269
14   -libqpdf/qpdf/auto_job_json_init.hh 63bbe1c3d673cd56196ec42ec7ede7b531563667d83564aa6680634fcb2cf259
15   -libqpdf/qpdf/auto_job_schema.hh a764050cc99f1cc95645fd1ea2f020c4b778957abc64fbc55c12eac3a369dc92
  13 +libqpdf/qpdf/auto_job_json_decl.hh c5e3fd38a3b0c569eb0c6b4c60953a09cd6bc7d3361a357a81f64fe36af2b0cf
  14 +libqpdf/qpdf/auto_job_json_init.hh bfaf88ad1461e1157e7a0eb6e8c90669eba6d03b5b1ffd2e7e7041250c5f0523
  15 +libqpdf/qpdf/auto_job_schema.hh 2ec70dffdd15974d74102b4d7ada9f97449bc28c98be119efee5e15507ed22a8
16 16 manual/_ext/qpdf.py e9ac9d6c70642a3d29281ee5ad92ae2422dee8be9306fb8a0bc9dba0ed5e28f3
17 17 manual/cli.rst a75a7e34aa9aba4f06e9c88cae9a2d9a2aa4e55a08521dde1478e8f2d80aadab
... ...
... ... @@ -243,13 +243,6 @@ options:
243 243 required_parameter:
244 244 prefix: prefix
245 245 password: password
246   -no-json:
247   - - preserve-unreferenced-resources
248   - - job-json-file
249   - - replace-input
250   - - warning-exit-0
251   - - requires-password
252   - - is-encrypted
253 246 json:
254 247 # The structure of this section defines what the json input to
255 248 # QPDFJob looks like. If a key starts with underscore, it does not
... ... @@ -262,143 +255,149 @@ json:
262 255 # converted to camelCase for the schema and must be appear that way
263 256 # in the user-supplied json. This makes it more convenient to
264 257 # populate JSON objects in some languages.
265   - _input:
266   - _file: "input filename"
267   - main.password:
268   - password-file:
269   - empty:
270   - _output:
271   - _file: "output filename"
272   - _replace-input: "set to true to replace input"
273   - _options:
274   - qdf:
275   - preserve-unreferenced:
276   - newline-before-endstream:
277   - normalize-content:
278   - stream-data:
279   - compress-streams:
280   - recompress-flate:
281   - decode-level:
282   - decrypt:
283   - deterministic-id:
284   - static-aes-iv:
285   - static-id:
286   - no-original-object-ids:
287   - copy-encryption:
288   - encryption-file-password:
289   - linearize:
290   - linearize-pass1:
291   - object-streams:
292   - min-version:
293   - force-version:
294   - progress:
295   - split-pages:
296   - encrypt:
297   - _user-password: "user password"
298   - _owner-password: "owner password"
299   - _40bit:
300   - Enc40.annotate:
301   - Enc40.extract:
302   - Enc40.modify:
303   - Enc40.print:
304   - _128bit:
305   - Enc128.accessibility:
306   - Enc128.annotate:
307   - Enc128.assemble:
308   - Enc128.cleartext-metadata:
309   - Enc128.extract:
310   - Enc128.form:
311   - Enc128.modify-other:
312   - Enc128.modify:
313   - Enc128.print:
314   - force-V4:
315   - use-aes:
316   - _256bit:
317   - Enc256.accessibility:
318   - Enc256.annotate:
319   - Enc256.assemble:
320   - Enc256.cleartext-metadata:
321   - Enc256.extract:
322   - Enc256.form:
323   - Enc256.modify-other:
324   - Enc256.modify:
325   - Enc256.print:
326   - allow-insecure:
327   - force-R5:
328   - _inspect:
329   - check:
330   - check-linearization:
331   - filtered-stream-data:
332   - raw-stream-data:
333   - show-encryption:
334   - show-encryption-key:
335   - show-linearization:
336   - show-npages:
337   - show-object:
338   - show-pages:
339   - show-xref:
340   - with-images:
341   - list-attachments:
342   - show-attachment:
343   - json:
344   - json-key:
345   - - null
346   - json-object:
347   - - null
348   - _options:
349   - allow-weak-crypto:
350   - keep-files-open:
351   - keep-files-open-threshold:
352   - no-warn:
353   - verbose:
354   - ignore-xref-streams:
355   - password-is-hex-key:
356   - password-mode:
357   - suppress-password-recovery:
358   - suppress-recovery:
359   - coalesce-contents:
360   - compression-level:
361   - externalize-inline-images:
362   - ii-min-bytes:
363   - remove-unreferenced-resources:
364   - add-attachment:
365   - - _file: "attachment to add"
366   - creationdate:
367   - description:
368   - filename:
369   - key:
370   - mimetype:
371   - moddate:
372   - replace:
373   - remove-attachment:
374   - copy-attachments-from:
375   - - _file: "attachment source filename"
376   - CopyAtt.password:
377   - prefix:
378   - collate:
379   - flatten-annotations:
380   - flatten-rotation:
381   - generate-appearances:
382   - keep-inline-images:
383   - oi-min-area:
384   - oi-min-height:
385   - oi-min-width:
386   - optimize-images:
387   - pages:
388   - - _file: "source for for pages"
389   - Pages.password:
390   - _range: "page range"
391   - remove-page-labels:
392   - rotate:
393   - overlay:
394   - _file: "source file for overlay"
395   - UO.password:
396   - from:
397   - repeat:
398   - to:
399   - underlay:
400   - _file: "source file for underlay"
401   - UO.password:
402   - from:
403   - repeat:
404   - to:
  258 +
  259 + # input
  260 + _inputFile: "input filename"
  261 + main.password:
  262 + password-file:
  263 + empty:
  264 + # output
  265 + _outputFile: "output filename"
  266 + replace-input:
  267 + # output options
  268 + qdf:
  269 + preserve-unreferenced:
  270 + newline-before-endstream:
  271 + normalize-content:
  272 + stream-data:
  273 + compress-streams:
  274 + recompress-flate:
  275 + decode-level:
  276 + decrypt:
  277 + deterministic-id:
  278 + static-aes-iv:
  279 + static-id:
  280 + no-original-object-ids:
  281 + copy-encryption:
  282 + encryption-file-password:
  283 + linearize:
  284 + linearize-pass1:
  285 + object-streams:
  286 + min-version:
  287 + force-version:
  288 + progress:
  289 + split-pages:
  290 + encrypt:
  291 + _user-password: "user password"
  292 + _owner-password: "owner password"
  293 + _40bit:
  294 + Enc40.annotate:
  295 + Enc40.extract:
  296 + Enc40.modify:
  297 + Enc40.print:
  298 + _128bit:
  299 + Enc128.accessibility:
  300 + Enc128.annotate:
  301 + Enc128.assemble:
  302 + Enc128.cleartext-metadata:
  303 + Enc128.extract:
  304 + Enc128.form:
  305 + Enc128.modify-other:
  306 + Enc128.modify:
  307 + Enc128.print:
  308 + force-V4:
  309 + use-aes:
  310 + _256bit:
  311 + Enc256.accessibility:
  312 + Enc256.annotate:
  313 + Enc256.assemble:
  314 + Enc256.cleartext-metadata:
  315 + Enc256.extract:
  316 + Enc256.form:
  317 + Enc256.modify-other:
  318 + Enc256.modify:
  319 + Enc256.print:
  320 + allow-insecure:
  321 + force-R5:
  322 + # inspect
  323 + check:
  324 + check-linearization:
  325 + filtered-stream-data:
  326 + raw-stream-data:
  327 + show-encryption:
  328 + show-encryption-key:
  329 + show-linearization:
  330 + show-npages:
  331 + show-object:
  332 + show-pages:
  333 + show-xref:
  334 + with-images:
  335 + list-attachments:
  336 + show-attachment:
  337 + json:
  338 + json-key:
  339 + - null
  340 + json-object:
  341 + - null
  342 + # other options
  343 + allow-weak-crypto:
  344 + keep-files-open:
  345 + keep-files-open-threshold:
  346 + no-warn:
  347 + verbose:
  348 + ignore-xref-streams:
  349 + password-is-hex-key:
  350 + password-mode:
  351 + suppress-password-recovery:
  352 + suppress-recovery:
  353 + coalesce-contents:
  354 + compression-level:
  355 + externalize-inline-images:
  356 + ii-min-bytes:
  357 + remove-unreferenced-resources:
  358 + add-attachment:
  359 + - _file: "attachment to add"
  360 + creationdate:
  361 + description:
  362 + filename:
  363 + key:
  364 + mimetype:
  365 + moddate:
  366 + replace:
  367 + remove-attachment:
  368 + copy-attachments-from:
  369 + - _file: "attachment source filename"
  370 + CopyAtt.password:
  371 + prefix:
  372 + collate:
  373 + flatten-annotations:
  374 + flatten-rotation:
  375 + generate-appearances:
  376 + keep-inline-images:
  377 + oi-min-area:
  378 + oi-min-height:
  379 + oi-min-width:
  380 + optimize-images:
  381 + pages:
  382 + - _file: "source for for pages"
  383 + Pages.password:
  384 + _range: "page range"
  385 + remove-page-labels:
  386 + rotate:
  387 + overlay:
  388 + _file: "source file for overlay"
  389 + UO.password:
  390 + from:
  391 + repeat:
  392 + to:
  393 + underlay:
  394 + _file: "source file for underlay"
  395 + UO.password:
  396 + from:
  397 + repeat:
  398 + to:
  399 + warning-exit-0:
  400 + job-json-file:
  401 + preserve-unreferenced-resources:
  402 + requires-password:
  403 + is-encrypted:
... ...
libqpdf/QPDFJob_json.cc
... ... @@ -220,18 +220,6 @@ Handlers::handle(JSON& j)
220 220 }
221 221  
222 222 void
223   -Handlers::beginInput(JSON)
224   -{
225   - // nothing needed
226   -}
227   -
228   -void
229   -Handlers::endInput()
230   -{
231   - // nothing needed
232   -}
233   -
234   -void
235 223 Handlers::setupInputFile()
236 224 {
237 225 addParameter([this](char const* p) {
... ... @@ -240,7 +228,7 @@ Handlers::setupInputFile()
240 228 }
241 229  
242 230 void
243   -Handlers::setupInputPassword()
  231 +Handlers::setupPassword()
244 232 {
245 233 addParameter([this](char const* p) {
246 234 c_main->password(p);
... ... @@ -248,7 +236,7 @@ Handlers::setupInputPassword()
248 236 }
249 237  
250 238 void
251   -Handlers::setupInputEmpty()
  239 +Handlers::setupEmpty()
252 240 {
253 241 addBare([this]() {
254 242 c_main->emptyInput();
... ... @@ -256,18 +244,6 @@ Handlers::setupInputEmpty()
256 244 }
257 245  
258 246 void
259   -Handlers::beginOutput(JSON)
260   -{
261   - // nothing needed
262   -}
263   -
264   -void
265   -Handlers::endOutput()
266   -{
267   - // nothing needed
268   -}
269   -
270   -void
271 247 Handlers::setupOutputFile()
272 248 {
273 249 addParameter([this](char const* p) {
... ... @@ -276,7 +252,7 @@ Handlers::setupOutputFile()
276 252 }
277 253  
278 254 void
279   -Handlers::setupOutputReplaceInput()
  255 +Handlers::setupReplaceInput()
280 256 {
281 257 addBare([this]() {
282 258 c_main->replaceInput();
... ... @@ -284,19 +260,7 @@ Handlers::setupOutputReplaceInput()
284 260 }
285 261  
286 262 void
287   -Handlers::beginOutputOptions(JSON)
288   -{
289   - // nothing needed
290   -}
291   -
292   -void
293   -Handlers::endOutputOptions()
294   -{
295   - // nothing needed
296   -}
297   -
298   -void
299   -Handlers::beginOutputOptionsEncrypt(JSON j)
  263 +Handlers::beginEncrypt(JSON j)
300 264 {
301 265 // This method is only called if the overall JSON structure
302 266 // matches the schema, so we already know that keys that are
... ... @@ -342,137 +306,113 @@ Handlers::beginOutputOptionsEncrypt(JSON j)
342 306 }
343 307  
344 308 void
345   -Handlers::endOutputOptionsEncrypt()
  309 +Handlers::endEncrypt()
346 310 {
347 311 this->c_enc->endEncrypt();
348 312 this->c_enc = nullptr;
349 313 }
350 314  
351 315 void
352   -Handlers::setupOutputOptionsEncryptUserPassword()
  316 +Handlers::setupEncryptUserPassword()
353 317 {
354   - // handled in beginOutputOptionsEncrypt
  318 + // handled in beginEncrypt
355 319 ignoreItem();
356 320 }
357 321  
358 322 void
359   -Handlers::setupOutputOptionsEncryptOwnerPassword()
  323 +Handlers::setupEncryptOwnerPassword()
360 324 {
361   - // handled in beginOutputOptionsEncrypt
  325 + // handled in beginEncrypt
362 326 ignoreItem();
363 327 }
364 328  
365 329 void
366   -Handlers::beginOutputOptionsEncrypt40bit(JSON)
367   -{
368   - // nothing needed
369   -}
370   -
371   -void
372   -Handlers::endOutputOptionsEncrypt40bit()
373   -{
374   - // nothing needed
375   -}
376   -
377   -void
378   -Handlers::beginOutputOptionsEncrypt128bit(JSON)
379   -{
380   - // nothing needed
381   -}
382   -
383   -void
384   -Handlers::endOutputOptionsEncrypt128bit()
385   -{
386   - // nothing needed
387   -}
388   -
389   -void
390   -Handlers::beginOutputOptionsEncrypt256bit(JSON)
  330 +Handlers::beginEncrypt40bit(JSON)
391 331 {
392 332 // nothing needed
393 333 }
394 334  
395 335 void
396   -Handlers::endOutputOptionsEncrypt256bit()
  336 +Handlers::endEncrypt40bit()
397 337 {
398 338 // nothing needed
399 339 }
400 340  
401 341 void
402   -Handlers::beginOptions(JSON)
  342 +Handlers::beginEncrypt128bit(JSON)
403 343 {
404 344 // nothing needed
405 345 }
406 346  
407 347 void
408   -Handlers::endOptions()
  348 +Handlers::endEncrypt128bit()
409 349 {
410 350 // nothing needed
411 351 }
412 352  
413 353 void
414   -Handlers::beginInspect(JSON)
  354 +Handlers::beginEncrypt256bit(JSON)
415 355 {
416 356 // nothing needed
417 357 }
418 358  
419 359 void
420   -Handlers::endInspect()
  360 +Handlers::endEncrypt256bit()
421 361 {
422 362 // nothing needed
423 363 }
424 364  
425 365 void
426   -Handlers::beginInspectJsonKeyArray(JSON)
  366 +Handlers::beginJsonKeyArray(JSON)
427 367 {
428 368 // nothing needed
429 369 }
430 370  
431 371 void
432   -Handlers::endInspectJsonKeyArray()
  372 +Handlers::endJsonKeyArray()
433 373 {
434 374 // nothing needed
435 375 }
436 376  
437 377 void
438   -Handlers::beginInspectJsonObjectArray(JSON)
  378 +Handlers::beginJsonObjectArray(JSON)
439 379 {
440 380 // nothing needed
441 381 }
442 382  
443 383 void
444   -Handlers::endInspectJsonObjectArray()
  384 +Handlers::endJsonObjectArray()
445 385 {
446 386 // nothing needed
447 387 }
448 388  
449 389 void
450   -Handlers::beginOptionsAddAttachmentArray(JSON)
  390 +Handlers::beginAddAttachmentArray(JSON)
451 391 {
452 392 // nothing needed
453 393 }
454 394  
455 395 void
456   -Handlers::endOptionsAddAttachmentArray()
  396 +Handlers::endAddAttachmentArray()
457 397 {
458 398 // nothing needed
459 399 }
460 400  
461 401 void
462   -Handlers::beginOptionsAddAttachment(JSON)
  402 +Handlers::beginAddAttachment(JSON)
463 403 {
464 404 this->c_att = c_main->addAttachment();
465 405 }
466 406  
467 407 void
468   -Handlers::endOptionsAddAttachment()
  408 +Handlers::endAddAttachment()
469 409 {
470 410 this->c_att->endAddAttachment();
471 411 this->c_att = nullptr;
472 412 }
473 413  
474 414 void
475   -Handlers::setupOptionsAddAttachmentFile()
  415 +Handlers::setupAddAttachmentFile()
476 416 {
477 417 addParameter([this](char const* p) {
478 418 c_att->file(p);
... ... @@ -480,32 +420,32 @@ Handlers::setupOptionsAddAttachmentFile()
480 420 }
481 421  
482 422 void
483   -Handlers::beginOptionsCopyAttachmentsFromArray(JSON)
  423 +Handlers::beginCopyAttachmentsFromArray(JSON)
484 424 {
485 425 // nothing needed
486 426 }
487 427  
488 428 void
489   -Handlers::endOptionsCopyAttachmentsFromArray()
  429 +Handlers::endCopyAttachmentsFromArray()
490 430 {
491 431 // nothing needed
492 432 }
493 433  
494 434 void
495   -Handlers::beginOptionsCopyAttachmentsFrom(JSON)
  435 +Handlers::beginCopyAttachmentsFrom(JSON)
496 436 {
497 437 this->c_copy_att = c_main->copyAttachmentsFrom();
498 438 }
499 439  
500 440 void
501   -Handlers::endOptionsCopyAttachmentsFrom()
  441 +Handlers::endCopyAttachmentsFrom()
502 442 {
503 443 this->c_copy_att->endCopyAttachmentsFrom();
504 444 this->c_copy_att = nullptr;
505 445 }
506 446  
507 447 void
508   -Handlers::setupOptionsCopyAttachmentsFromFile()
  448 +Handlers::setupCopyAttachmentsFromFile()
509 449 {
510 450 addParameter([this](char const* p) {
511 451 c_copy_att->file(p);
... ... @@ -513,7 +453,7 @@ Handlers::setupOptionsCopyAttachmentsFromFile()
513 453 }
514 454  
515 455 void
516   -Handlers::setupOptionsCopyAttachmentsFromPassword()
  456 +Handlers::setupCopyAttachmentsFromPassword()
517 457 {
518 458 addParameter([this](char const* p) {
519 459 c_copy_att->password(p);
... ... @@ -521,20 +461,20 @@ Handlers::setupOptionsCopyAttachmentsFromPassword()
521 461 }
522 462  
523 463 void
524   -Handlers::beginOptionsPagesArray(JSON)
  464 +Handlers::beginPagesArray(JSON)
525 465 {
526 466 this->c_pages = c_main->pages();
527 467 }
528 468  
529 469 void
530   -Handlers::endOptionsPagesArray()
  470 +Handlers::endPagesArray()
531 471 {
532 472 c_pages->endPages();
533 473 c_pages = nullptr;
534 474 }
535 475  
536 476 void
537   -Handlers::beginOptionsPages(JSON j)
  477 +Handlers::beginPages(JSON j)
538 478 {
539 479 std::string file;
540 480 std::string range("1-z");
... ... @@ -565,47 +505,47 @@ Handlers::beginOptionsPages(JSON j)
565 505 }
566 506  
567 507 void
568   -Handlers::endOptionsPages()
  508 +Handlers::endPages()
569 509 {
570 510 // nothing needed
571 511 }
572 512  
573 513 void
574   -Handlers::setupOptionsPagesFile()
  514 +Handlers::setupPagesFile()
575 515 {
576   - // handled in beginOptionsPages
  516 + // handled in beginPages
577 517 ignoreItem();
578 518 }
579 519  
580 520 void
581   -Handlers::setupOptionsPagesPassword()
  521 +Handlers::setupPagesPassword()
582 522 {
583   - // handled in beginOptionsPages
  523 + // handled in beginPages
584 524 ignoreItem();
585 525 }
586 526  
587 527 void
588   -Handlers::setupOptionsPagesRange()
  528 +Handlers::setupPagesRange()
589 529 {
590   - // handled in beginOptionsPages
  530 + // handled in beginPages
591 531 ignoreItem();
592 532 }
593 533  
594 534 void
595   -Handlers::beginOptionsOverlay(JSON)
  535 +Handlers::beginOverlay(JSON)
596 536 {
597 537 this->c_uo = c_main->overlay();
598 538 }
599 539  
600 540 void
601   -Handlers::endOptionsOverlay()
  541 +Handlers::endOverlay()
602 542 {
603 543 c_uo->endUnderlayOverlay();
604 544 c_uo = nullptr;
605 545 }
606 546  
607 547 void
608   -Handlers::setupOptionsOverlayFile()
  548 +Handlers::setupOverlayFile()
609 549 {
610 550 addParameter([this](char const* p) {
611 551 c_uo->file(p);
... ... @@ -613,7 +553,7 @@ Handlers::setupOptionsOverlayFile()
613 553 }
614 554  
615 555 void
616   -Handlers::setupOptionsOverlayPassword()
  556 +Handlers::setupOverlayPassword()
617 557 {
618 558 addParameter([this](char const* p) {
619 559 c_uo->password(p);
... ... @@ -621,20 +561,20 @@ Handlers::setupOptionsOverlayPassword()
621 561 }
622 562  
623 563 void
624   -Handlers::beginOptionsUnderlay(JSON)
  564 +Handlers::beginUnderlay(JSON)
625 565 {
626 566 this->c_uo = c_main->underlay();
627 567 }
628 568  
629 569 void
630   -Handlers::endOptionsUnderlay()
  570 +Handlers::endUnderlay()
631 571 {
632 572 c_uo->endUnderlayOverlay();
633 573 c_uo = nullptr;
634 574 }
635 575  
636 576 void
637   -Handlers::setupOptionsUnderlayFile()
  577 +Handlers::setupUnderlayFile()
638 578 {
639 579 addParameter([this](char const* p) {
640 580 c_uo->file(p);
... ... @@ -642,7 +582,7 @@ Handlers::setupOptionsUnderlayFile()
642 582 }
643 583  
644 584 void
645   -Handlers::setupOptionsUnderlayPassword()
  585 +Handlers::setupUnderlayPassword()
646 586 {
647 587 addParameter([this](char const* p) {
648 588 c_uo->password(p);
... ...
libqpdf/qpdf/auto_job_json_decl.hh
... ... @@ -3,58 +3,48 @@
3 3 // Edits will be automatically overwritten if the build is
4 4 // run in maintainer mode.
5 5 //
6   -void beginInput(JSON);
7   -void endInput();
8 6 void setupInputFile();
9   -void setupInputPassword();
10   -void setupInputEmpty();
11   -void beginOutput(JSON);
12   -void endOutput();
  7 +void setupPassword();
  8 +void setupEmpty();
13 9 void setupOutputFile();
14   -void setupOutputReplaceInput();
15   -void beginOutputOptions(JSON);
16   -void endOutputOptions();
17   -void beginOutputOptionsEncrypt(JSON);
18   -void endOutputOptionsEncrypt();
19   -void setupOutputOptionsEncryptUserPassword();
20   -void setupOutputOptionsEncryptOwnerPassword();
21   -void beginOutputOptionsEncrypt40bit(JSON);
22   -void endOutputOptionsEncrypt40bit();
23   -void beginOutputOptionsEncrypt128bit(JSON);
24   -void endOutputOptionsEncrypt128bit();
25   -void beginOutputOptionsEncrypt256bit(JSON);
26   -void endOutputOptionsEncrypt256bit();
27   -void beginInspect(JSON);
28   -void endInspect();
29   -void beginInspectJsonKeyArray(JSON);
30   -void endInspectJsonKeyArray();
31   -void beginInspectJsonObjectArray(JSON);
32   -void endInspectJsonObjectArray();
33   -void beginOptions(JSON);
34   -void endOptions();
35   -void beginOptionsAddAttachmentArray(JSON);
36   -void endOptionsAddAttachmentArray();
37   -void beginOptionsAddAttachment(JSON);
38   -void endOptionsAddAttachment();
39   -void setupOptionsAddAttachmentFile();
40   -void beginOptionsCopyAttachmentsFromArray(JSON);
41   -void endOptionsCopyAttachmentsFromArray();
42   -void beginOptionsCopyAttachmentsFrom(JSON);
43   -void endOptionsCopyAttachmentsFrom();
44   -void setupOptionsCopyAttachmentsFromFile();
45   -void setupOptionsCopyAttachmentsFromPassword();
46   -void beginOptionsPagesArray(JSON);
47   -void endOptionsPagesArray();
48   -void beginOptionsPages(JSON);
49   -void endOptionsPages();
50   -void setupOptionsPagesFile();
51   -void setupOptionsPagesPassword();
52   -void setupOptionsPagesRange();
53   -void beginOptionsOverlay(JSON);
54   -void endOptionsOverlay();
55   -void setupOptionsOverlayFile();
56   -void setupOptionsOverlayPassword();
57   -void beginOptionsUnderlay(JSON);
58   -void endOptionsUnderlay();
59   -void setupOptionsUnderlayFile();
60   -void setupOptionsUnderlayPassword();
  10 +void setupReplaceInput();
  11 +void beginEncrypt(JSON);
  12 +void endEncrypt();
  13 +void setupEncryptUserPassword();
  14 +void setupEncryptOwnerPassword();
  15 +void beginEncrypt40bit(JSON);
  16 +void endEncrypt40bit();
  17 +void beginEncrypt128bit(JSON);
  18 +void endEncrypt128bit();
  19 +void beginEncrypt256bit(JSON);
  20 +void endEncrypt256bit();
  21 +void beginJsonKeyArray(JSON);
  22 +void endJsonKeyArray();
  23 +void beginJsonObjectArray(JSON);
  24 +void endJsonObjectArray();
  25 +void beginAddAttachmentArray(JSON);
  26 +void endAddAttachmentArray();
  27 +void beginAddAttachment(JSON);
  28 +void endAddAttachment();
  29 +void setupAddAttachmentFile();
  30 +void beginCopyAttachmentsFromArray(JSON);
  31 +void endCopyAttachmentsFromArray();
  32 +void beginCopyAttachmentsFrom(JSON);
  33 +void endCopyAttachmentsFrom();
  34 +void setupCopyAttachmentsFromFile();
  35 +void setupCopyAttachmentsFromPassword();
  36 +void beginPagesArray(JSON);
  37 +void endPagesArray();
  38 +void beginPages(JSON);
  39 +void endPages();
  40 +void setupPagesFile();
  41 +void setupPagesPassword();
  42 +void setupPagesRange();
  43 +void beginOverlay(JSON);
  44 +void endOverlay();
  45 +void setupOverlayFile();
  46 +void setupOverlayPassword();
  47 +void beginUnderlay(JSON);
  48 +void endUnderlay();
  49 +void setupUnderlayFile();
  50 +void setupUnderlayPassword();
... ...
libqpdf/qpdf/auto_job_json_init.hh
... ... @@ -15,31 +15,24 @@ static char const* json_key_choices[] = {"acroform", "attachments", "encrypt", "
15 15 static char const* print128_choices[] = {"full", "low", "none", 0};
16 16 static char const* modify128_choices[] = {"all", "annotate", "form", "assembly", "none", 0};
17 17  
18   -pushKey("input");
19   -beginDict(bindJSON(&Handlers::beginInput), bindBare(&Handlers::endInput)); // .input
20   -pushKey("file");
  18 +pushKey("inputFile");
21 19 setupInputFile();
22   -popHandler(); // key: file
  20 +popHandler(); // key: inputFile
23 21 pushKey("password");
24   -setupInputPassword();
  22 +setupPassword();
25 23 popHandler(); // key: password
26 24 pushKey("passwordFile");
27 25 addParameter([this](char const* p) { c_main->passwordFile(p); });
28 26 popHandler(); // key: passwordFile
29 27 pushKey("empty");
30   -setupInputEmpty();
  28 +setupEmpty();
31 29 popHandler(); // key: empty
32   -popHandler(); // key: input
33   -pushKey("output");
34   -beginDict(bindJSON(&Handlers::beginOutput), bindBare(&Handlers::endOutput)); // .output
35   -pushKey("file");
  30 +pushKey("outputFile");
36 31 setupOutputFile();
37   -popHandler(); // key: file
  32 +popHandler(); // key: outputFile
38 33 pushKey("replaceInput");
39   -setupOutputReplaceInput();
  34 +setupReplaceInput();
40 35 popHandler(); // key: replaceInput
41   -pushKey("options");
42   -beginDict(bindJSON(&Handlers::beginOutputOptions), bindBare(&Handlers::endOutputOptions)); // .output.options
43 36 pushKey("qdf");
44 37 addBare([this]() { c_main->qdf(); });
45 38 popHandler(); // key: qdf
... ... @@ -107,15 +100,15 @@ pushKey("splitPages");
107 100 addParameter([this](char const* p) { c_main->splitPages(p); });
108 101 popHandler(); // key: splitPages
109 102 pushKey("encrypt");
110   -beginDict(bindJSON(&Handlers::beginOutputOptionsEncrypt), bindBare(&Handlers::endOutputOptionsEncrypt)); // .output.options.encrypt
  103 +beginDict(bindJSON(&Handlers::beginEncrypt), bindBare(&Handlers::endEncrypt)); // .encrypt
111 104 pushKey("userPassword");
112   -setupOutputOptionsEncryptUserPassword();
  105 +setupEncryptUserPassword();
113 106 popHandler(); // key: userPassword
114 107 pushKey("ownerPassword");
115   -setupOutputOptionsEncryptOwnerPassword();
  108 +setupEncryptOwnerPassword();
116 109 popHandler(); // key: ownerPassword
117 110 pushKey("40bit");
118   -beginDict(bindJSON(&Handlers::beginOutputOptionsEncrypt40bit), bindBare(&Handlers::endOutputOptionsEncrypt40bit)); // .output.options.encrypt.40bit
  111 +beginDict(bindJSON(&Handlers::beginEncrypt40bit), bindBare(&Handlers::endEncrypt40bit)); // .encrypt.40bit
119 112 pushKey("annotate");
120 113 addChoices(yn_choices, [this](char const* p) { c_enc->annotate(p); });
121 114 popHandler(); // key: annotate
... ... @@ -130,7 +123,7 @@ addChoices(print128_choices, [this](char const* p) { c_enc->print(p); });
130 123 popHandler(); // key: print
131 124 popHandler(); // key: 40bit
132 125 pushKey("128bit");
133   -beginDict(bindJSON(&Handlers::beginOutputOptionsEncrypt128bit), bindBare(&Handlers::endOutputOptionsEncrypt128bit)); // .output.options.encrypt.128bit
  126 +beginDict(bindJSON(&Handlers::beginEncrypt128bit), bindBare(&Handlers::endEncrypt128bit)); // .encrypt.128bit
134 127 pushKey("accessibility");
135 128 addChoices(yn_choices, [this](char const* p) { c_enc->accessibility(p); });
136 129 popHandler(); // key: accessibility
... ... @@ -166,7 +159,7 @@ addChoices(yn_choices, [this](char const* p) { c_enc->useAes(p); });
166 159 popHandler(); // key: useAes
167 160 popHandler(); // key: 128bit
168 161 pushKey("256bit");
169   -beginDict(bindJSON(&Handlers::beginOutputOptionsEncrypt256bit), bindBare(&Handlers::endOutputOptionsEncrypt256bit)); // .output.options.encrypt.256bit
  162 +beginDict(bindJSON(&Handlers::beginEncrypt256bit), bindBare(&Handlers::endEncrypt256bit)); // .encrypt.256bit
170 163 pushKey("accessibility");
171 164 addChoices(yn_choices, [this](char const* p) { c_enc->accessibility(p); });
172 165 popHandler(); // key: accessibility
... ... @@ -202,10 +195,6 @@ addBare([this]() { c_enc->forceR5(); });
202 195 popHandler(); // key: forceR5
203 196 popHandler(); // key: 256bit
204 197 popHandler(); // key: encrypt
205   -popHandler(); // key: options
206   -popHandler(); // key: output
207   -pushKey("inspect");
208   -beginDict(bindJSON(&Handlers::beginInspect), bindBare(&Handlers::endInspect)); // .inspect
209 198 pushKey("check");
210 199 addBare([this]() { c_main->check(); });
211 200 popHandler(); // key: check
... ... @@ -252,18 +241,15 @@ pushKey("json");
252 241 addChoices(json_version_choices, [this](char const* p) { c_main->json(p); });
253 242 popHandler(); // key: json
254 243 pushKey("jsonKey");
255   -beginArray(bindJSON(&Handlers::beginInspectJsonKeyArray), bindBare(&Handlers::endInspectJsonKeyArray)); // .inspect.jsonKey[]
  244 +beginArray(bindJSON(&Handlers::beginJsonKeyArray), bindBare(&Handlers::endJsonKeyArray)); // .jsonKey[]
256 245 addChoices(json_key_choices, [this](char const* p) { c_main->jsonKey(p); });
257   -popHandler(); // array: .inspect.jsonKey[]
  246 +popHandler(); // array: .jsonKey[]
258 247 popHandler(); // key: jsonKey
259 248 pushKey("jsonObject");
260   -beginArray(bindJSON(&Handlers::beginInspectJsonObjectArray), bindBare(&Handlers::endInspectJsonObjectArray)); // .inspect.jsonObject[]
  249 +beginArray(bindJSON(&Handlers::beginJsonObjectArray), bindBare(&Handlers::endJsonObjectArray)); // .jsonObject[]
261 250 addParameter([this](char const* p) { c_main->jsonObject(p); });
262   -popHandler(); // array: .inspect.jsonObject[]
  251 +popHandler(); // array: .jsonObject[]
263 252 popHandler(); // key: jsonObject
264   -popHandler(); // key: inspect
265   -pushKey("options");
266   -beginDict(bindJSON(&Handlers::beginOptions), bindBare(&Handlers::endOptions)); // .options
267 253 pushKey("allowWeakCrypto");
268 254 addBare([this]() { c_main->allowWeakCrypto(); });
269 255 popHandler(); // key: allowWeakCrypto
... ... @@ -310,10 +296,10 @@ pushKey("removeUnreferencedResources");
310 296 addChoices(remove_unref_choices, [this](char const* p) { c_main->removeUnreferencedResources(p); });
311 297 popHandler(); // key: removeUnreferencedResources
312 298 pushKey("addAttachment");
313   -beginArray(bindJSON(&Handlers::beginOptionsAddAttachmentArray), bindBare(&Handlers::endOptionsAddAttachmentArray)); // .options.addAttachment[]
314   -beginDict(bindJSON(&Handlers::beginOptionsAddAttachment), bindBare(&Handlers::endOptionsAddAttachment)); // .options.addAttachment
  299 +beginArray(bindJSON(&Handlers::beginAddAttachmentArray), bindBare(&Handlers::endAddAttachmentArray)); // .addAttachment[]
  300 +beginDict(bindJSON(&Handlers::beginAddAttachment), bindBare(&Handlers::endAddAttachment)); // .addAttachment
315 301 pushKey("file");
316   -setupOptionsAddAttachmentFile();
  302 +setupAddAttachmentFile();
317 303 popHandler(); // key: file
318 304 pushKey("creationdate");
319 305 addParameter([this](char const* p) { c_att->creationdate(p); });
... ... @@ -336,24 +322,24 @@ popHandler(); // key: moddate
336 322 pushKey("replace");
337 323 addBare([this]() { c_att->replace(); });
338 324 popHandler(); // key: replace
339   -popHandler(); // array: .options.addAttachment[]
  325 +popHandler(); // array: .addAttachment[]
340 326 popHandler(); // key: addAttachment
341 327 pushKey("removeAttachment");
342 328 addParameter([this](char const* p) { c_main->removeAttachment(p); });
343 329 popHandler(); // key: removeAttachment
344 330 pushKey("copyAttachmentsFrom");
345   -beginArray(bindJSON(&Handlers::beginOptionsCopyAttachmentsFromArray), bindBare(&Handlers::endOptionsCopyAttachmentsFromArray)); // .options.copyAttachmentsFrom[]
346   -beginDict(bindJSON(&Handlers::beginOptionsCopyAttachmentsFrom), bindBare(&Handlers::endOptionsCopyAttachmentsFrom)); // .options.copyAttachmentsFrom
  331 +beginArray(bindJSON(&Handlers::beginCopyAttachmentsFromArray), bindBare(&Handlers::endCopyAttachmentsFromArray)); // .copyAttachmentsFrom[]
  332 +beginDict(bindJSON(&Handlers::beginCopyAttachmentsFrom), bindBare(&Handlers::endCopyAttachmentsFrom)); // .copyAttachmentsFrom
347 333 pushKey("file");
348   -setupOptionsCopyAttachmentsFromFile();
  334 +setupCopyAttachmentsFromFile();
349 335 popHandler(); // key: file
350 336 pushKey("password");
351   -setupOptionsCopyAttachmentsFromPassword();
  337 +setupCopyAttachmentsFromPassword();
352 338 popHandler(); // key: password
353 339 pushKey("prefix");
354 340 addParameter([this](char const* p) { c_copy_att->prefix(p); });
355 341 popHandler(); // key: prefix
356   -popHandler(); // array: .options.copyAttachmentsFrom[]
  342 +popHandler(); // array: .copyAttachmentsFrom[]
357 343 popHandler(); // key: copyAttachmentsFrom
358 344 pushKey("collate");
359 345 addParameter([this](char const* p) { c_main->collate(p); });
... ... @@ -383,18 +369,18 @@ pushKey("optimizeImages");
383 369 addBare([this]() { c_main->optimizeImages(); });
384 370 popHandler(); // key: optimizeImages
385 371 pushKey("pages");
386   -beginArray(bindJSON(&Handlers::beginOptionsPagesArray), bindBare(&Handlers::endOptionsPagesArray)); // .options.pages[]
387   -beginDict(bindJSON(&Handlers::beginOptionsPages), bindBare(&Handlers::endOptionsPages)); // .options.pages
  372 +beginArray(bindJSON(&Handlers::beginPagesArray), bindBare(&Handlers::endPagesArray)); // .pages[]
  373 +beginDict(bindJSON(&Handlers::beginPages), bindBare(&Handlers::endPages)); // .pages
388 374 pushKey("file");
389   -setupOptionsPagesFile();
  375 +setupPagesFile();
390 376 popHandler(); // key: file
391 377 pushKey("password");
392   -setupOptionsPagesPassword();
  378 +setupPagesPassword();
393 379 popHandler(); // key: password
394 380 pushKey("range");
395   -setupOptionsPagesRange();
  381 +setupPagesRange();
396 382 popHandler(); // key: range
397   -popHandler(); // array: .options.pages[]
  383 +popHandler(); // array: .pages[]
398 384 popHandler(); // key: pages
399 385 pushKey("removePageLabels");
400 386 addBare([this]() { c_main->removePageLabels(); });
... ... @@ -403,12 +389,12 @@ pushKey("rotate");
403 389 addParameter([this](char const* p) { c_main->rotate(p); });
404 390 popHandler(); // key: rotate
405 391 pushKey("overlay");
406   -beginDict(bindJSON(&Handlers::beginOptionsOverlay), bindBare(&Handlers::endOptionsOverlay)); // .options.overlay
  392 +beginDict(bindJSON(&Handlers::beginOverlay), bindBare(&Handlers::endOverlay)); // .overlay
407 393 pushKey("file");
408   -setupOptionsOverlayFile();
  394 +setupOverlayFile();
409 395 popHandler(); // key: file
410 396 pushKey("password");
411   -setupOptionsOverlayPassword();
  397 +setupOverlayPassword();
412 398 popHandler(); // key: password
413 399 pushKey("from");
414 400 addParameter([this](char const* p) { c_uo->from(p); });
... ... @@ -421,12 +407,12 @@ addParameter([this](char const* p) { c_uo->to(p); });
421 407 popHandler(); // key: to
422 408 popHandler(); // key: overlay
423 409 pushKey("underlay");
424   -beginDict(bindJSON(&Handlers::beginOptionsUnderlay), bindBare(&Handlers::endOptionsUnderlay)); // .options.underlay
  410 +beginDict(bindJSON(&Handlers::beginUnderlay), bindBare(&Handlers::endUnderlay)); // .underlay
425 411 pushKey("file");
426   -setupOptionsUnderlayFile();
  412 +setupUnderlayFile();
427 413 popHandler(); // key: file
428 414 pushKey("password");
429   -setupOptionsUnderlayPassword();
  415 +setupUnderlayPassword();
430 416 popHandler(); // key: password
431 417 pushKey("from");
432 418 addParameter([this](char const* p) { c_uo->from(p); });
... ... @@ -438,4 +424,18 @@ pushKey("to");
438 424 addParameter([this](char const* p) { c_uo->to(p); });
439 425 popHandler(); // key: to
440 426 popHandler(); // key: underlay
441   -popHandler(); // key: options
  427 +pushKey("warningExit0");
  428 +addBare([this]() { c_main->warningExit0(); });
  429 +popHandler(); // key: warningExit0
  430 +pushKey("jobJsonFile");
  431 +addParameter([this](char const* p) { c_main->jobJsonFile(p); });
  432 +popHandler(); // key: jobJsonFile
  433 +pushKey("preserveUnreferencedResources");
  434 +addBare([this]() { c_main->preserveUnreferencedResources(); });
  435 +popHandler(); // key: preserveUnreferencedResources
  436 +pushKey("requiresPassword");
  437 +addBare([this]() { c_main->requiresPassword(); });
  438 +popHandler(); // key: requiresPassword
  439 +pushKey("isEncrypted");
  440 +addBare([this]() { c_main->isEncrypted(); });
  441 +popHandler(); // key: isEncrypted
... ...
libqpdf/qpdf/auto_job_schema.hh
1 1 static constexpr char const* JOB_SCHEMA_DATA = R"({
2   - "input": {
3   - "file": "input filename",
4   - "password": "specify password",
5   - "passwordFile": "read password from a file",
6   - "empty": "empty input file"
7   - },
8   - "output": {
9   - "file": "output filename",
10   - "replaceInput": "set to true to replace input",
11   - "options": {
12   - "qdf": "enable viewing PDF code in a text editor",
13   - "preserveUnreferenced": "preserve unreferenced objects",
14   - "newlineBeforeEndstream": "force a newline before endstream",
15   - "normalizeContent": "fix newlines in content streams",
16   - "streamData": "control stream compression",
17   - "compressStreams": "compress uncompressed streams",
18   - "recompressFlate": "uncompress and recompress flate",
19   - "decodeLevel": "control which streams to uncompress",
20   - "decrypt": "remove encryption from input file",
21   - "deterministicId": "generate ID deterministically",
22   - "staticAesIv": "use a fixed AES vector",
23   - "staticId": "use a fixed document ID",
24   - "noOriginalObjectIds": "omit original object IDs in qdf",
25   - "copyEncryption": "copy another file's encryption details",
26   - "encryptionFilePassword": "supply password for copyEncryption",
27   - "linearize": "linearize (web-optimize) output",
28   - "linearizePass1": "save pass 1 of linearization",
29   - "objectStreams": "control use of object streams",
30   - "minVersion": "set minimum PDF version",
31   - "forceVersion": "set output PDF version",
32   - "progress": "show progress when writing",
33   - "splitPages": "write pages to separate files",
34   - "encrypt": {
35   - "userPassword": "user password",
36   - "ownerPassword": "owner password",
37   - "40bit": {
38   - "annotate": "restrict document annotation",
39   - "extract": "restrict text/graphic extraction",
40   - "modify": "restrict document modification",
41   - "print": "restrict printing"
42   - },
43   - "128bit": {
44   - "accessibility": "restrict document accessibility",
45   - "annotate": "restrict document annotation",
46   - "assemble": "restrict document assembly",
47   - "cleartextMetadata": "don't encrypt metadata",
48   - "extract": "restrict text/graphic extraction",
49   - "form": "restrict form filling",
50   - "modifyOther": "restrict other modifications",
51   - "modify": "restrict document modification",
52   - "print": "restrict printing",
53   - "forceV4": "force V=4 in encryption dictionary",
54   - "useAes": "use AES with 128-bit encryption"
55   - },
56   - "256bit": {
57   - "accessibility": "restrict document accessibility",
58   - "annotate": "restrict document annotation",
59   - "assemble": "restrict document assembly",
60   - "cleartextMetadata": "don't encrypt metadata",
61   - "extract": "restrict text/graphic extraction",
62   - "form": "restrict form filling",
63   - "modifyOther": "restrict other modifications",
64   - "modify": "restrict document modification",
65   - "print": "restrict printing",
66   - "allowInsecure": "allow empty owner passwords",
67   - "forceR5": "use unsupported R=5 encryption"
68   - }
69   - }
  2 + "inputFile": "input filename",
  3 + "password": "specify password",
  4 + "passwordFile": "read password from a file",
  5 + "empty": "empty input file",
  6 + "outputFile": "output filename",
  7 + "replaceInput": "replace input with output",
  8 + "qdf": "enable viewing PDF code in a text editor",
  9 + "preserveUnreferenced": "preserve unreferenced objects",
  10 + "newlineBeforeEndstream": "force a newline before endstream",
  11 + "normalizeContent": "fix newlines in content streams",
  12 + "streamData": "control stream compression",
  13 + "compressStreams": "compress uncompressed streams",
  14 + "recompressFlate": "uncompress and recompress flate",
  15 + "decodeLevel": "control which streams to uncompress",
  16 + "decrypt": "remove encryption from input file",
  17 + "deterministicId": "generate ID deterministically",
  18 + "staticAesIv": "use a fixed AES vector",
  19 + "staticId": "use a fixed document ID",
  20 + "noOriginalObjectIds": "omit original object IDs in qdf",
  21 + "copyEncryption": "copy another file's encryption details",
  22 + "encryptionFilePassword": "supply password for copyEncryption",
  23 + "linearize": "linearize (web-optimize) output",
  24 + "linearizePass1": "save pass 1 of linearization",
  25 + "objectStreams": "control use of object streams",
  26 + "minVersion": "set minimum PDF version",
  27 + "forceVersion": "set output PDF version",
  28 + "progress": "show progress when writing",
  29 + "splitPages": "write pages to separate files",
  30 + "encrypt": {
  31 + "userPassword": "user password",
  32 + "ownerPassword": "owner password",
  33 + "40bit": {
  34 + "annotate": "restrict document annotation",
  35 + "extract": "restrict text/graphic extraction",
  36 + "modify": "restrict document modification",
  37 + "print": "restrict printing"
  38 + },
  39 + "128bit": {
  40 + "accessibility": "restrict document accessibility",
  41 + "annotate": "restrict document annotation",
  42 + "assemble": "restrict document assembly",
  43 + "cleartextMetadata": "don't encrypt metadata",
  44 + "extract": "restrict text/graphic extraction",
  45 + "form": "restrict form filling",
  46 + "modifyOther": "restrict other modifications",
  47 + "modify": "restrict document modification",
  48 + "print": "restrict printing",
  49 + "forceV4": "force V=4 in encryption dictionary",
  50 + "useAes": "use AES with 128-bit encryption"
  51 + },
  52 + "256bit": {
  53 + "accessibility": "restrict document accessibility",
  54 + "annotate": "restrict document annotation",
  55 + "assemble": "restrict document assembly",
  56 + "cleartextMetadata": "don't encrypt metadata",
  57 + "extract": "restrict text/graphic extraction",
  58 + "form": "restrict form filling",
  59 + "modifyOther": "restrict other modifications",
  60 + "modify": "restrict document modification",
  61 + "print": "restrict printing",
  62 + "allowInsecure": "allow empty owner passwords",
  63 + "forceR5": "use unsupported R=5 encryption"
70 64 }
71 65 },
72   - "inspect": {
73   - "check": "partially check whether PDF is valid",
74   - "checkLinearization": "check linearization tables",
75   - "filteredStreamData": "show filtered stream data",
76   - "rawStreamData": "show raw stream data",
77   - "showEncryption": "information about encrypted files",
78   - "showEncryptionKey": "show key with showEncryption",
79   - "showLinearization": "show linearization hint tables",
80   - "showNpages": "show number of pages",
81   - "showObject": "show contents of an object",
82   - "showPages": "display page dictionary information",
83   - "showXref": "show cross reference data",
84   - "withImages": "include image details with showPages",
85   - "listAttachments": "list embedded files",
86   - "showAttachment": "export an embedded file",
87   - "json": "show file in json format",
88   - "jsonKey": [
89   - "restrict which keys are in json output"
90   - ],
91   - "jsonObject": [
92   - "restrict which objects are in JSON"
93   - ]
94   - },
95   - "options": {
96   - "allowWeakCrypto": "allow insecure cryptographic algorithms",
97   - "keepFilesOpen": "manage keeping multiple files open",
98   - "keepFilesOpenThreshold": "set threshold for keepFilesOpen",
99   - "noWarn": "suppress printing of warning messages",
100   - "verbose": "print additional information",
101   - "ignoreXrefStreams": "use xref tables rather than streams",
102   - "passwordIsHexKey": "provide hex-encoded encryption key",
103   - "passwordMode": "tweak how qpdf encodes passwords",
104   - "suppressPasswordRecovery": "don't try different password encodings",
105   - "suppressRecovery": "suppress error recovery",
106   - "coalesceContents": "combine content streams",
107   - "compressionLevel": "set compression level for flate",
108   - "externalizeInlineImages": "convert inline to regular images",
109   - "iiMinBytes": "set minimum size for externalizeInlineImages",
110   - "removeUnreferencedResources": "remove unreferenced page resources",
111   - "addAttachment": [
112   - {
113   - "file": "attachment to add",
114   - "creationdate": "set attachment's creation date",
115   - "description": "set attachment's description",
116   - "filename": "set attachment's displayed filename",
117   - "key": "specify attachment key",
118   - "mimetype": "attachment mime type, e.g. application/pdf",
119   - "moddate": "set attachment's modification date",
120   - "replace": "replace attachment with same key"
121   - }
122   - ],
123   - "removeAttachment": "remove an embedded file",
124   - "copyAttachmentsFrom": [
125   - {
126   - "file": "attachment source filename",
127   - "password": "specify password",
128   - "prefix": "key prefix for copying attachments"
129   - }
130   - ],
131   - "collate": "collate with pages",
132   - "flattenAnnotations": "push annotations into content",
133   - "flattenRotation": "remove rotation from page dictionary",
134   - "generateAppearances": "generate appearances for form fields",
135   - "keepInlineImages": "exclude inline images from optimization",
136   - "oiMinArea": "minimum area for optimizeImages",
137   - "oiMinHeight": "minimum height for optimizeImages",
138   - "oiMinWidth": "minimum width for optimizeImages",
139   - "optimizeImages": "use efficient compression for images",
140   - "pages": [
141   - {
142   - "file": "source for for pages",
143   - "password": "specify password",
144   - "range": "page range"
145   - }
146   - ],
147   - "removePageLabels": "remove explicit page numbers",
148   - "rotate": "rotate pages",
149   - "overlay": {
150   - "file": "source file for overlay",
  66 + "check": "partially check whether PDF is valid",
  67 + "checkLinearization": "check linearization tables",
  68 + "filteredStreamData": "show filtered stream data",
  69 + "rawStreamData": "show raw stream data",
  70 + "showEncryption": "information about encrypted files",
  71 + "showEncryptionKey": "show key with showEncryption",
  72 + "showLinearization": "show linearization hint tables",
  73 + "showNpages": "show number of pages",
  74 + "showObject": "show contents of an object",
  75 + "showPages": "display page dictionary information",
  76 + "showXref": "show cross reference data",
  77 + "withImages": "include image details with showPages",
  78 + "listAttachments": "list embedded files",
  79 + "showAttachment": "export an embedded file",
  80 + "json": "show file in json format",
  81 + "jsonKey": [
  82 + "restrict which keys are in json output"
  83 + ],
  84 + "jsonObject": [
  85 + "restrict which objects are in JSON"
  86 + ],
  87 + "allowWeakCrypto": "allow insecure cryptographic algorithms",
  88 + "keepFilesOpen": "manage keeping multiple files open",
  89 + "keepFilesOpenThreshold": "set threshold for keepFilesOpen",
  90 + "noWarn": "suppress printing of warning messages",
  91 + "verbose": "print additional information",
  92 + "ignoreXrefStreams": "use xref tables rather than streams",
  93 + "passwordIsHexKey": "provide hex-encoded encryption key",
  94 + "passwordMode": "tweak how qpdf encodes passwords",
  95 + "suppressPasswordRecovery": "don't try different password encodings",
  96 + "suppressRecovery": "suppress error recovery",
  97 + "coalesceContents": "combine content streams",
  98 + "compressionLevel": "set compression level for flate",
  99 + "externalizeInlineImages": "convert inline to regular images",
  100 + "iiMinBytes": "set minimum size for externalizeInlineImages",
  101 + "removeUnreferencedResources": "remove unreferenced page resources",
  102 + "addAttachment": [
  103 + {
  104 + "file": "attachment to add",
  105 + "creationdate": "set attachment's creation date",
  106 + "description": "set attachment's description",
  107 + "filename": "set attachment's displayed filename",
  108 + "key": "specify attachment key",
  109 + "mimetype": "attachment mime type, e.g. application/pdf",
  110 + "moddate": "set attachment's modification date",
  111 + "replace": "replace attachment with same key"
  112 + }
  113 + ],
  114 + "removeAttachment": "remove an embedded file",
  115 + "copyAttachmentsFrom": [
  116 + {
  117 + "file": "attachment source filename",
151 118 "password": "specify password",
152   - "from": "source pages for underlay/overlay",
153   - "repeat": "overlay/underlay pages to repeat",
154   - "to": "destination pages for underlay/overlay"
155   - },
156   - "underlay": {
157   - "file": "source file for underlay",
  119 + "prefix": "key prefix for copying attachments"
  120 + }
  121 + ],
  122 + "collate": "collate with pages",
  123 + "flattenAnnotations": "push annotations into content",
  124 + "flattenRotation": "remove rotation from page dictionary",
  125 + "generateAppearances": "generate appearances for form fields",
  126 + "keepInlineImages": "exclude inline images from optimization",
  127 + "oiMinArea": "minimum area for optimizeImages",
  128 + "oiMinHeight": "minimum height for optimizeImages",
  129 + "oiMinWidth": "minimum width for optimizeImages",
  130 + "optimizeImages": "use efficient compression for images",
  131 + "pages": [
  132 + {
  133 + "file": "source for for pages",
158 134 "password": "specify password",
159   - "from": "source pages for underlay/overlay",
160   - "repeat": "overlay/underlay pages to repeat",
161   - "to": "destination pages for underlay/overlay"
  135 + "range": "page range"
162 136 }
163   - }
  137 + ],
  138 + "removePageLabels": "remove explicit page numbers",
  139 + "rotate": "rotate pages",
  140 + "overlay": {
  141 + "file": "source file for overlay",
  142 + "password": "specify password",
  143 + "from": "source pages for underlay/overlay",
  144 + "repeat": "overlay/underlay pages to repeat",
  145 + "to": "destination pages for underlay/overlay"
  146 + },
  147 + "underlay": {
  148 + "file": "source file for underlay",
  149 + "password": "specify password",
  150 + "from": "source pages for underlay/overlay",
  151 + "repeat": "overlay/underlay pages to repeat",
  152 + "to": "destination pages for underlay/overlay"
  153 + },
  154 + "warningExit0": "exit 0 even with warnings",
  155 + "jobJsonFile": "job JSON file",
  156 + "preserveUnreferencedResources": "use removeUnreferencedResourcesNo",
  157 + "requiresPassword": "silently test a file's password",
  158 + "isEncrypted": "silently test whether a file is encrypted"
164 159 })";
... ...
qpdf/qtest/qpdf/bad-bare-option-false-json.out
1 1  
2   -qpdf: error with job-json file bad-json-bare-option-false.json: .output.options.qdf: value must be true
  2 +qpdf: error with job-json file bad-json-bare-option-false.json: .qdf: value must be true
3 3 Run qpdf--job-json-help for information on the file format.
4 4  
5 5 For help:
... ...
qpdf/qtest/qpdf/bad-choice-mismatch-json.out
1 1  
2   -qpdf: error with job-json file bad-json-choice-mismatch.json: .output.options.objectStreams: unexpected value; expected one of disable, preserve, generate
  2 +qpdf: error with job-json file bad-json-choice-mismatch.json: .objectStreams: unexpected value; expected one of disable, preserve, generate
3 3 Run qpdf--job-json-help for information on the file format.
4 4  
5 5 For help:
... ...
qpdf/qtest/qpdf/bad-json-bare-option-false.json
1 1 {
2   - "output": {
3   - "options": {
4   - "qdf": false
5   - }
6   - }
  2 + "qdf": false
7 3 }
... ...
qpdf/qtest/qpdf/bad-json-choice-mismatch.json
1 1 {
2   - "output": {
3   - "options": {
4   - "objectStreams": "potato"
5   - }
6   - }
  2 + "objectStreams": "potato"
7 3 }
... ...
qpdf/qtest/qpdf/bad-json-encrypt-duplicate-key-length.json
1 1 {
2   - "output": {
3   - "options": {
4   - "encrypt": {
5   - "userPassword": "",
6   - "ownerPassword": "someOwnerThing",
7   - "256bit": {
8   - },
9   - "128bit": {
10   - }
11   - }
  2 + "encrypt": {
  3 + "userPassword": "",
  4 + "ownerPassword": "someOwnerThing",
  5 + "256bit": {
  6 + },
  7 + "128bit": {
12 8 }
13 9 }
14 10 }
... ...
qpdf/qtest/qpdf/bad-json-encrypt-missing-password.json
1 1 {
2   - "output": {
3   - "options": {
4   - "encrypt": {
5   - "userPassword": "",
6   - "256bit": {
7   - }
8   - }
  2 + "encrypt": {
  3 + "userPassword": "",
  4 + "256bit": {
9 5 }
10 6 }
11 7 }
... ...
qpdf/qtest/qpdf/bad-json-encrypt-no-key-length.json
1 1 {
2   - "output": {
3   - "options": {
4   - "encrypt": {
5   - "userPassword": "",
6   - "ownerPassword": "someOwnerThing"
7   - }
8   - }
  2 + "encrypt": {
  3 + "userPassword": "",
  4 + "ownerPassword": "someOwnerThing"
9 5 }
10 6 }
... ...
qpdf/qtest/qpdf/bad-json-error-json.out
1 1  
2   -qpdf: error with job-json file bad-json-json-error.json: JSON: offset 130: unexpected dictionary end delimiter
  2 +qpdf: error with job-json file bad-json-json-error.json: JSON: offset 83: unexpected dictionary end delimiter
3 3 Run qpdf--job-json-help for information on the file format.
4 4  
5 5 For help:
... ...
qpdf/qtest/qpdf/bad-json-json-error.json
1 1 {
2   - "output": {
3   - "options": {
4   - "encrypt": {
5   - "userPassword": "",
6   - "ownerPassword": "someOwnerThing",
7   - }
8   - }
  2 + "encrypt": {
  3 + "userPassword": "",
  4 + "ownerPassword": "someOwnerThing",
9 5 }
10 6 }
... ...
qpdf/qtest/qpdf/bad-json-pages-no-file.json
1 1 {
2   - "options": {
3   - "pages": [
4   - {
5   - "range": "1-z"
6   - }
7   - ]
8   - }
  2 + "pages": [
  3 + {
  4 + "range": "1-z"
  5 + }
  6 + ]
9 7 }
... ...
qpdf/qtest/qpdf/bad-json-schema-error.json
1 1 {
2   - "output": {
3   - "potato": {
4   - "encrypt": {
5   - "userPassword": "",
6   - "ownerPassword": "someOwnerThing",
7   - "256bit": {
8   - }
9   - }
  2 + "potato": {
  3 + },
  4 + "encrypt": {
  5 + "userPassword": "",
  6 + "ownerPassword": "someOwnerThing",
  7 + "256bit": {
10 8 }
11 9 }
12 10 }
... ...
qpdf/qtest/qpdf/bad-schema-error-json.out
1 1  
2 2 qpdf: error with job-json file bad-json-schema-error.json: qpdf: job json has errors:
3   - json key ".output": key "potato" is not present in schema but appears in object
  3 + top-level object: key "potato" is not present in schema but appears in object
4 4 Run qpdf--job-json-help for information on the file format.
5 5  
6 6 For help:
... ...
qpdf/qtest/qpdf/job-json-add-attachments.json
1 1 {
2   - "input": {
3   - "file": "minimal.pdf"
4   - },
5   - "output": {
6   - "file": "a.pdf",
7   - "options": {
8   - "staticId": true
  2 + "inputFile": "minimal.pdf",
  3 + "outputFile": "a.pdf",
  4 + "staticId": true,
  5 + "addAttachment": [
  6 + {
  7 + "file": "auto-txt",
  8 + "moddate": "D:20220131134246-05'00'",
  9 + "creationdate": "D:20220131134246-05'00'"
  10 + },
  11 + {
  12 + "file": "auto-txt",
  13 + "moddate": "D:20220131134246-05'00'",
  14 + "creationdate": "D:20220131134246-05'00'",
  15 + "filename": "auto2",
  16 + "key": "auto2-key"
9 17 }
10   - },
11   - "options": {
12   - "addAttachment": [
13   - {
14   - "file": "auto-txt",
15   - "moddate": "D:20220131134246-05'00'",
16   - "creationdate": "D:20220131134246-05'00'"
17   - },
18   - {
19   - "file": "auto-txt",
20   - "moddate": "D:20220131134246-05'00'",
21   - "creationdate": "D:20220131134246-05'00'",
22   - "filename": "auto2",
23   - "key": "auto2-key"
24   - }
25   - ]
26   - }
  18 + ]
27 19 }
... ...
qpdf/qtest/qpdf/job-json-choice-match.json
1 1 {
2   - "input": {
3   - "file": "minimal.pdf"
4   - },
5   - "output": {
6   - "file": "a.pdf",
7   - "options": {
8   - "deterministicId": true,
9   - "objectStreams": "generate"
10   - }
11   - }
  2 + "inputFile": "minimal.pdf",
  3 + "outputFile": "a.pdf",
  4 + "deterministicId": true,
  5 + "objectStreams": "generate"
12 6 }
... ...
qpdf/qtest/qpdf/job-json-copy-attachments.json
1 1 {
2   - "input": {
3   - "file": "minimal.pdf"
4   - },
5   - "output": {
6   - "file": "a.pdf",
7   - "options": {
8   - "staticId": true
  2 + "inputFile": "minimal.pdf",
  3 + "outputFile": "a.pdf",
  4 + "staticId": true,
  5 + "copyAttachmentsFrom": [
  6 + {
  7 + "file": "job-json-add-attachments.pdf"
  8 + },
  9 + {
  10 + "file": "20-pages.pdf",
  11 + "password": "user"
  12 + },
  13 + {
  14 + "file": "job-json-add-attachments.pdf",
  15 + "prefix": "p-"
9 16 }
10   - },
11   - "options": {
12   - "copyAttachmentsFrom": [
13   - {
14   - "file": "job-json-add-attachments.pdf"
15   - },
16   - {
17   - "file": "20-pages.pdf",
18   - "password": "user"
19   - },
20   - {
21   - "file": "job-json-add-attachments.pdf",
22   - "prefix": "p-"
23   - }
24   - ]
25   - }
  17 + ]
26 18 }
... ...
qpdf/qtest/qpdf/job-json-empty-input.json
1 1 {
2   - "input": {
3   - "empty": true
4   - },
5   - "output": {
6   - "file": "a.pdf",
7   - "options": {
8   - "staticId": true
  2 + "empty": true,
  3 + "outputFile": "a.pdf",
  4 + "staticId": true,
  5 + "pages": [
  6 + {
  7 + "file": "minimal.pdf"
  8 + },
  9 + {
  10 + "file": "20-pages.pdf",
  11 + "password": "user",
  12 + "range": "1-5"
9 13 }
10   - },
11   - "options": {
12   - "pages": [
13   - {
14   - "file": "minimal.pdf"
15   - },
16   - {
17   - "file": "20-pages.pdf",
18   - "password": "user",
19   - "range": "1-5"
20   - }
21   - ]
22   - }
  14 + ]
23 15 }
... ...
qpdf/qtest/qpdf/job-json-encrypt-128.json
1 1 {
2   - "input": {
3   - "file": "fxo-blue.pdf"
4   - },
5   - "output": {
6   - "file": "a.pdf",
7   - "options": {
8   - "staticId": true,
9   - "staticAesIv": true,
10   - "encrypt": {
11   - "userPassword": "u",
12   - "ownerPassword": "o",
13   - "128bit": {
14   - "useAes": "y"
15   - }
16   - }
  2 + "inputFile": "fxo-blue.pdf",
  3 + "outputFile": "a.pdf",
  4 + "staticId": true,
  5 + "staticAesIv": true,
  6 + "encrypt": {
  7 + "userPassword": "u",
  8 + "ownerPassword": "o",
  9 + "128bit": {
  10 + "useAes": "y"
17 11 }
18 12 }
19 13 }
... ...
qpdf/qtest/qpdf/job-json-encrypt-256-with-restrictions.json
1 1 {
2   - "input": {
3   - "file": "minimal.pdf"
4   - },
5   - "output": {
6   - "file": "a.pdf",
7   - "options": {
8   - "staticId": true,
9   - "staticAesIv": true,
10   - "encrypt": {
11   - "userPassword": "u",
12   - "ownerPassword": "o",
13   - "256bit": {
14   - "print": "low",
15   - "modify": "form"
16   - }
17   - }
  2 + "inputFile": "minimal.pdf",
  3 + "outputFile": "a.pdf",
  4 + "staticId": true,
  5 + "staticAesIv": true,
  6 + "encrypt": {
  7 + "userPassword": "u",
  8 + "ownerPassword": "o",
  9 + "256bit": {
  10 + "print": "low",
  11 + "modify": "form"
18 12 }
19 13 }
20 14 }
... ...
qpdf/qtest/qpdf/job-json-encrypt-40.json
1 1 {
2   - "input": {
3   - "file": "minimal.pdf"
  2 + "inputFile": "minimal.pdf",
  3 + "outputFile": "a.pdf",
  4 + "staticId": true,
  5 + "encrypt": {
  6 + "userPassword": "u",
  7 + "ownerPassword": "o",
  8 + "40bit": {}
4 9 },
5   - "output": {
6   - "file": "a.pdf",
7   - "options": {
8   - "staticId": true,
9   - "encrypt": {
10   - "userPassword": "u",
11   - "ownerPassword": "o",
12   - "40bit": {}
13   - }
14   - }
15   - },
16   - "options": {
17   - "allowWeakCrypto": true
18   - }
  10 + "allowWeakCrypto": true
19 11 }
... ...
qpdf/qtest/qpdf/job-json-input-file-password.json
1 1 {
2   - "input": {
3   - "file": "20-pages.pdf",
4   - "password": "user"
5   - },
6   - "output": {
7   - "file": "a.pdf",
8   - "options": {
9   - "staticId": true,
10   - "staticAesIv": true,
11   - "compressStreams": "n"
12   - }
13   - }
  2 + "inputFile": "20-pages.pdf",
  3 + "password": "user",
  4 + "outputFile": "a.pdf",
  5 + "staticId": true,
  6 + "staticAesIv": true,
  7 + "compressStreams": "n"
14 8 }
... ...
qpdf/qtest/qpdf/job-json-misc-options.json
1 1 {
2   - "input": {
3   - "file": "minimal.pdf"
4   - },
5   - "output": {
6   - "file": "a.pdf",
7   - "options": {
8   - "staticId": true,
9   - "linearize": true,
10   - "compressStreams": "n"
11   - }
12   - }
  2 + "inputFile": "minimal.pdf",
  3 + "outputFile": "a.pdf",
  4 + "staticId": true,
  5 + "linearize": true,
  6 + "compressStreams": "n"
13 7 }
... ...
qpdf/qtest/qpdf/job-json-output.json
1 1 {
2   - "input": {
3   - "file": "minimal.pdf"
4   - },
5   - "inspect": {
6   - "json": "1",
7   - "jsonKey": [
8   - "pages",
9   - "objects"
10   - ],
11   - "jsonObject": [
12   - "trailer",
13   - "5"
14   - ]
15   - }
  2 + "inputFile": "minimal.pdf",
  3 + "json": "1",
  4 + "jsonKey": [
  5 + "pages",
  6 + "objects"
  7 + ],
  8 + "jsonObject": [
  9 + "trailer",
  10 + "5"
  11 + ]
16 12 }
... ...
qpdf/qtest/qpdf/job-json-replace-input.json
1 1 {
2   - "input": {
3   - "file": "a.pdf"
4   - },
5   - "output": {
6   - "replaceInput": true,
7   - "options": {
8   - "staticId": true,
9   - "objectStreams": "generate"
10   - }
11   - }
  2 + "inputFile": "a.pdf",
  3 + "replaceInput": true,
  4 + "staticId": true,
  5 + "objectStreams": "generate"
12 6 }
... ...
qpdf/qtest/qpdf/job-json-underlay-overlay-password.json
1 1 {
2   - "input": {
3   - "file": "minimal.pdf"
  2 + "inputFile": "minimal.pdf",
  3 + "outputFile": "a.pdf",
  4 + "staticId": true,
  5 + "underlay": {
  6 + "file": "20-pages.pdf",
  7 + "password": "user",
  8 + "from": "5"
4 9 },
5   - "output": {
6   - "file": "a.pdf",
7   - "options": {
8   - "staticId": true
9   - }
10   - },
11   - "options": {
12   - "underlay": {
13   - "file": "20-pages.pdf",
14   - "password": "user",
15   - "from": "5"
16   - },
17   - "overlay": {
18   - "file": "job-json-encrypt-128.pdf",
19   - "password": "o",
20   - "from": "7"
21   - }
  10 + "overlay": {
  11 + "file": "job-json-encrypt-128.pdf",
  12 + "password": "o",
  13 + "from": "7"
22 14 }
23 15 }
... ...
qpdf/qtest/qpdf/job-json-underlay-overlay.json
1 1 {
2   - "input": {
3   - "file": "20-pages.pdf",
4   - "password": "owner"
  2 + "inputFile": "20-pages.pdf",
  3 + "password": "owner",
  4 + "outputFile": "a.pdf",
  5 + "staticId": true,
  6 + "decrypt": true,
  7 + "underlay": {
  8 + "file": "fxo-green.pdf"
5 9 },
6   - "output": {
7   - "file": "a.pdf",
8   - "options": {
9   - "staticId": true,
10   - "decrypt": true
11   - }
12   - },
13   - "options": {
14   - "underlay": {
15   - "file": "fxo-green.pdf"
16   - },
17   - "overlay": {
18   - "file": "fxo-red.pdf",
19   - "from": "1,2",
20   - "repeat": "3"
21   - }
  10 + "overlay": {
  11 + "file": "fxo-red.pdf",
  12 + "from": "1,2",
  13 + "repeat": "3"
22 14 }
23 15 }
... ...
qpdf/qtest/qpdf/job-partial.json
1 1 {
2   - "output": {
3   - "options": {
4   - "encrypt": {
5   - "userPassword": "",
6   - "ownerPassword": "",
7   - "256bit": {
8   - }
9   - }
  2 + "encrypt": {
  3 + "userPassword": "",
  4 + "ownerPassword": "",
  5 + "256bit": {
10 6 }
11 7 }
12 8 }
... ...
qpdf/qtest/qpdf/job-show-encryption.json
1 1 {
2   - "inspect": {
3   - "showEncryption": true
4   - }
  2 + "showEncryption": true
5 3 }
... ...