Commit 7b4ecb6019b810feee0e2b077dbbe842ea78d531

Authored by m-holger
Committed by GitHub
2 parents 96e3677c f3109f67

Merge pull request #1617 from m-holger/i1403

Add `--remove-acroform` option to exclude AcroForm dictionary
include/qpdf/auto_job_c_main.hh
@@ -32,6 +32,7 @@ QPDF_DLL Config* progress(); @@ -32,6 +32,7 @@ QPDF_DLL Config* progress();
32 QPDF_DLL Config* qdf(); 32 QPDF_DLL Config* qdf();
33 QPDF_DLL Config* rawStreamData(); 33 QPDF_DLL Config* rawStreamData();
34 QPDF_DLL Config* recompressFlate(); 34 QPDF_DLL Config* recompressFlate();
  35 +QPDF_DLL Config* removeAcroform();
35 QPDF_DLL Config* removeInfo(); 36 QPDF_DLL Config* removeInfo();
36 QPDF_DLL Config* removeMetadata(); 37 QPDF_DLL Config* removeMetadata();
37 QPDF_DLL Config* removePageLabels(); 38 QPDF_DLL Config* removePageLabels();
job.sums
@@ -5,17 +5,17 @@ include/qpdf/auto_job_c_att.hh 4c2b171ea00531db54720bf49a43f8b34481586ae7fb6cbf2 @@ -5,17 +5,17 @@ include/qpdf/auto_job_c_att.hh 4c2b171ea00531db54720bf49a43f8b34481586ae7fb6cbf2
5 include/qpdf/auto_job_c_copy_att.hh 50609012bff14fd82f0649185940d617d05d530cdc522185c7f3920a561ccb42 5 include/qpdf/auto_job_c_copy_att.hh 50609012bff14fd82f0649185940d617d05d530cdc522185c7f3920a561ccb42
6 include/qpdf/auto_job_c_enc.hh 28446f3c32153a52afa239ea40503e6cc8ac2c026813526a349e0cd4ae17ddd5 6 include/qpdf/auto_job_c_enc.hh 28446f3c32153a52afa239ea40503e6cc8ac2c026813526a349e0cd4ae17ddd5
7 include/qpdf/auto_job_c_global.hh 7df0ff87d18d7fa6d57437960377509420b6b6eb9527b534996f86d3bd7a0ddc 7 include/qpdf/auto_job_c_global.hh 7df0ff87d18d7fa6d57437960377509420b6b6eb9527b534996f86d3bd7a0ddc
8 -include/qpdf/auto_job_c_main.hh b865eb827356554763bb8349eadfcbc5cb260f80e025a5e229467c525007356d 8 +include/qpdf/auto_job_c_main.hh 7a7cc311e194b778ea7568ece2335c00c9bdd8162431c264af2f6105548efc5f
9 include/qpdf/auto_job_c_pages.hh 09ca15649cc94fdaf6d9bdae28a20723f2a66616bf15aa86d83df31051d82506 9 include/qpdf/auto_job_c_pages.hh 09ca15649cc94fdaf6d9bdae28a20723f2a66616bf15aa86d83df31051d82506
10 include/qpdf/auto_job_c_uo.hh 9c2f98a355858dd54d0bba444b73177a59c9e56833e02fa6406f429c07f39e62 10 include/qpdf/auto_job_c_uo.hh 9c2f98a355858dd54d0bba444b73177a59c9e56833e02fa6406f429c07f39e62
11 -job.yml fa98c8444c8a22a89aeeb76670aa5919aa7a86ebfac2eb45018602fbc7e45b79 11 +job.yml 442ef5e7fb8027a0f3cd4816b614d59abb327b359e861d87426b706db142d2bc
12 libqpdf/qpdf/auto_job_decl.hh d612a02839e4f20a80e1c6a3ba09c17187fccddc3581ec7ebb1e3919ffd6801d 12 libqpdf/qpdf/auto_job_decl.hh d612a02839e4f20a80e1c6a3ba09c17187fccddc3581ec7ebb1e3919ffd6801d
13 -libqpdf/qpdf/auto_job_help.hh 7503b1083c952ace12976857c8ece4e1af67788af9f827fb4248bd22329f93cd  
14 -libqpdf/qpdf/auto_job_init.hh 10a697528d4cae1ac566ee7612f62e611190b3c10c0021862a77fa7e4f330570 13 +libqpdf/qpdf/auto_job_help.hh 43d0c1f4477949d1a4facc6984e9e341758201f4884e8d0d82ffc8dd795b2d38
  14 +libqpdf/qpdf/auto_job_init.hh 2bb9d1524817e7150da55790ba0ac5ed8042ff4ff9688d70a927ee95903849a4
15 libqpdf/qpdf/auto_job_json_decl.hh 7dbb83ddadcea39bfd1faa4ca061e1e3c3134d693b8ae634b463e7e19dc8bd0a 15 libqpdf/qpdf/auto_job_json_decl.hh 7dbb83ddadcea39bfd1faa4ca061e1e3c3134d693b8ae634b463e7e19dc8bd0a
16 -libqpdf/qpdf/auto_job_json_init.hh e9cacbcb78ca250a962c226a935067ef9b76f5485bae7e5302eea0a1a8e2ff65  
17 -libqpdf/qpdf/auto_job_schema.hh 2b974a436c5b4d03fb38258d6213f993cfa9f673834cebe754b4c7ad657481c9 16 +libqpdf/qpdf/auto_job_json_init.hh 33934c23235c760a1fc1375c74f4fd52c8f5accf655c510fa3dd9a2be293b61d
  17 +libqpdf/qpdf/auto_job_schema.hh 81b8d57f05f5125a722912b6ee5e10fc6b02ae68e040108b75f32fc6527c02b1
18 manual/_ext/qpdf.py 6add6321666031d55ed4aedf7c00e5662bba856dfcd66ccb526563bffefbb580 18 manual/_ext/qpdf.py 6add6321666031d55ed4aedf7c00e5662bba856dfcd66ccb526563bffefbb580
19 -manual/cli.rst be2b9366e953fce743c115db00eeedc7894e547a9222133395e929f535fa9836  
20 -manual/qpdf.1 c1d6e58e37aed1b8d434b37edd1837b7261c9933b09d64bf3915dc3f35d6cccb 19 +manual/cli.rst efbce4b34fefbe1f46fca9c9693af245a7f7e2b63c0853c464569087aa49cb18
  20 +manual/qpdf.1 0567419e4f6a2b8facd03b9febaf65a384dd68e0e327fc058e77c21121a6cf17
21 manual/qpdf.1.in 436ecc85d45c4c9e2dbd1725fb7f0177fb627179469f114561adf3cb6cbb677b 21 manual/qpdf.1.in 436ecc85d45c4c9e2dbd1725fb7f0177fb627179469f114561adf3cb6cbb677b
@@ -145,6 +145,7 @@ options: @@ -145,6 +145,7 @@ options:
145 - qdf 145 - qdf
146 - raw-stream-data 146 - raw-stream-data
147 - recompress-flate 147 - recompress-flate
  148 + - remove-acroform
148 - remove-info 149 - remove-info
149 - remove-metadata 150 - remove-metadata
150 - remove-page-labels 151 - remove-page-labels
@@ -468,6 +469,7 @@ json: @@ -468,6 +469,7 @@ json:
468 - Pages.file: 469 - Pages.file:
469 Pages.password: 470 Pages.password:
470 range: 471 range:
  472 + remove-acroform:
471 remove-info: 473 remove-info:
472 remove-metadata: 474 remove-metadata:
473 remove-page-labels: 475 remove-page-labels:
libqpdf/QPDFJob.cc
@@ -438,6 +438,9 @@ QPDFJob::createQPDF() @@ -438,6 +438,9 @@ QPDFJob::createQPDF()
438 m->warnings |= m->inputs.clear(); 438 m->warnings |= m->inputs.clear();
439 439
440 auto root = pdf.getRoot(); 440 auto root = pdf.getRoot();
  441 + if (m->remove_acroform) {
  442 + root.erase("/AcroForm");
  443 + }
441 if (m->remove_info) { 444 if (m->remove_info) {
442 auto trailer = pdf.getTrailer(); 445 auto trailer = pdf.getTrailer();
443 auto mod_date = trailer["/Info"]["/ModDate"]; 446 auto mod_date = trailer["/Info"]["/ModDate"];
libqpdf/QPDFJob_config.cc
@@ -563,6 +563,13 @@ QPDFJob::Config::removeAttachment(std::string const& parameter) @@ -563,6 +563,13 @@ QPDFJob::Config::removeAttachment(std::string const& parameter)
563 } 563 }
564 564
565 QPDFJob::Config* 565 QPDFJob::Config*
  566 +QPDFJob::Config::removeAcroform()
  567 +{
  568 + o.m->remove_acroform = true;
  569 + return this;
  570 +}
  571 +
  572 +QPDFJob::Config*
566 QPDFJob::Config::removeInfo() 573 QPDFJob::Config::removeInfo()
567 { 574 {
568 o.m->remove_info = true; 575 o.m->remove_info = true;
libqpdf/qpdf/QPDFJob_private.hh
@@ -250,6 +250,7 @@ class QPDFJob::Members @@ -250,6 +250,7 @@ class QPDFJob::Members
250 bool optimize_images{false}; 250 bool optimize_images{false};
251 bool externalize_inline_images{false}; 251 bool externalize_inline_images{false};
252 bool keep_inline_images{false}; 252 bool keep_inline_images{false};
  253 + bool remove_acroform{false};
253 bool remove_info{false}; 254 bool remove_info{false};
254 bool remove_metadata{false}; 255 bool remove_metadata{false};
255 bool remove_page_labels{false}; 256 bool remove_page_labels{false};
libqpdf/qpdf/auto_job_help.hh
@@ -430,6 +430,11 @@ ap.addOptionHelp("--keep-inline-images", "modification", "exclude inline images @@ -430,6 +430,11 @@ ap.addOptionHelp("--keep-inline-images", "modification", "exclude inline images
430 } 430 }
431 static void add_help_5(QPDFArgParser& ap) 431 static void add_help_5(QPDFArgParser& ap)
432 { 432 {
  433 +ap.addOptionHelp("--remove-acroform", "modification", "remove the interactive form dictionary", R"(Exclude the interactive form dictionary from the output file. This
  434 +option only removes the interactive form dictionary from the
  435 +document catalog. It does not remove form field dictionaries or
  436 +widget annotations. See the manual for more detail.
  437 +)");
433 ap.addOptionHelp("--remove-info", "modification", "remove file information", R"(Exclude file information (except modification date) from the output file. 438 ap.addOptionHelp("--remove-info", "modification", "remove file information", R"(Exclude file information (except modification date) from the output file.
434 )"); 439 )");
435 ap.addOptionHelp("--remove-metadata", "modification", "remove metadata", R"(Exclude metadata from the output file. 440 ap.addOptionHelp("--remove-metadata", "modification", "remove metadata", R"(Exclude metadata from the output file.
@@ -642,6 +647,9 @@ ap.addOptionHelp("--cleartext-metadata", "encryption", "don't encrypt metadata", @@ -642,6 +647,9 @@ ap.addOptionHelp("--cleartext-metadata", "encryption", "don't encrypt metadata",
642 encrypting the rest of the document. This option is not 647 encrypting the rest of the document. This option is not
643 available with 40-bit encryption. 648 available with 40-bit encryption.
644 )"); 649 )");
  650 +}
  651 +static void add_help_6(QPDFArgParser& ap)
  652 +{
645 ap.addOptionHelp("--use-aes", "encryption", "use AES with 128-bit encryption", R"(--use-aes=[y|n] 653 ap.addOptionHelp("--use-aes", "encryption", "use AES with 128-bit encryption", R"(--use-aes=[y|n]
646 654
647 Enables/disables use of the more secure AES encryption with 655 Enables/disables use of the more secure AES encryption with
@@ -650,9 +658,6 @@ version to be at least 1.6. This option is only available with @@ -650,9 +658,6 @@ version to be at least 1.6. This option is only available with
650 128-bit encryption. The default is "n" for compatibility 658 128-bit encryption. The default is "n" for compatibility
651 reasons. Use 256-bit encryption instead. 659 reasons. Use 256-bit encryption instead.
652 )"); 660 )");
653 -}  
654 -static void add_help_6(QPDFArgParser& ap)  
655 -{  
656 ap.addOptionHelp("--allow-insecure", "encryption", "allow empty owner passwords", R"(Allow creation of PDF files with empty owner passwords and 661 ap.addOptionHelp("--allow-insecure", "encryption", "allow empty owner passwords", R"(Allow creation of PDF files with empty owner passwords and
657 non-empty user passwords when using 256-bit encryption. 662 non-empty user passwords when using 256-bit encryption.
658 )"); 663 )");
@@ -828,14 +833,14 @@ Specify the attachment's modification date in PDF format; @@ -828,14 +833,14 @@ Specify the attachment's modification date in PDF format;
828 defaults to the current time. Run qpdf --help=pdf-dates for 833 defaults to the current time. Run qpdf --help=pdf-dates for
829 information about the date format. 834 information about the date format.
830 )"); 835 )");
  836 +}
  837 +static void add_help_7(QPDFArgParser& ap)
  838 +{
831 ap.addOptionHelp("--mimetype", "add-attachment", "attachment mime type, e.g. application/pdf", R"(--mimetype=type/subtype 839 ap.addOptionHelp("--mimetype", "add-attachment", "attachment mime type, e.g. application/pdf", R"(--mimetype=type/subtype
832 840
833 Specify the mime type for the attachment, such as text/plain, 841 Specify the mime type for the attachment, such as text/plain,
834 application/pdf, image/png, etc. 842 application/pdf, image/png, etc.
835 )"); 843 )");
836 -}  
837 -static void add_help_7(QPDFArgParser& ap)  
838 -{  
839 ap.addOptionHelp("--description", "add-attachment", "set attachment's description", R"(--description="text" 844 ap.addOptionHelp("--description", "add-attachment", "set attachment's description", R"(--description="text"
840 845
841 Supply descriptive text for the attachment, displayed by some 846 Supply descriptive text for the attachment, displayed by some
@@ -924,12 +929,12 @@ Useful for scripts. @@ -924,12 +929,12 @@ Useful for scripts.
924 ap.addOptionHelp("--show-pages", "inspection", "display page dictionary information", R"(Show the object and generation number for each page dictionary 929 ap.addOptionHelp("--show-pages", "inspection", "display page dictionary information", R"(Show the object and generation number for each page dictionary
925 object and for each content stream associated with the page. 930 object and for each content stream associated with the page.
926 )"); 931 )");
927 -ap.addOptionHelp("--with-images", "inspection", "include image details with --show-pages", R"(When used with --show-pages, also shows the object and  
928 -generation numbers for the image objects on each page.  
929 -)");  
930 } 932 }
931 static void add_help_8(QPDFArgParser& ap) 933 static void add_help_8(QPDFArgParser& ap)
932 { 934 {
  935 +ap.addOptionHelp("--with-images", "inspection", "include image details with --show-pages", R"(When used with --show-pages, also shows the object and
  936 +generation numbers for the image objects on each page.
  937 +)");
933 ap.addOptionHelp("--list-attachments", "inspection", "list embedded files", R"(Show the key and stream number for each embedded file. Combine 938 ap.addOptionHelp("--list-attachments", "inspection", "list embedded files", R"(Show the key and stream number for each embedded file. Combine
934 with --verbose for more detailed information. 939 with --verbose for more detailed information.
935 )"); 940 )");
@@ -1033,6 +1038,9 @@ parsing. The limit applies when the PDF document's xref table is undamaged @@ -1033,6 +1038,9 @@ parsing. The limit applies when the PDF document's xref table is undamaged
1033 and the object itself can be parsed without errors. The default limit 1038 and the object itself can be parsed without errors. The default limit
1034 is 4,294,967,295. See also --parser-max-container-size-damaged. 1039 is 4,294,967,295. See also --parser-max-container-size-damaged.
1035 )"); 1040 )");
  1041 +}
  1042 +static void add_help_9(QPDFArgParser& ap)
  1043 +{
1036 ap.addOptionHelp("--parser-max-container-size-damaged", "global", "set the maximum container size while parsing damaged files", R"(--parser-max-container-size-damaged=n 1044 ap.addOptionHelp("--parser-max-container-size-damaged", "global", "set the maximum container size while parsing damaged files", R"(--parser-max-container-size-damaged=n
1037 1045
1038 Set the maximum number of top-level objects allowed in a container while 1046 Set the maximum number of top-level objects allowed in a container while
@@ -1041,9 +1049,6 @@ or the object itself is damaged. The limit also applies when parsing @@ -1041,9 +1049,6 @@ or the object itself is damaged. The limit also applies when parsing
1041 xref streams. The default limit is 5,000. 1049 xref streams. The default limit is 5,000.
1042 See also --parser-max-container-size. 1050 See also --parser-max-container-size.
1043 )"); 1051 )");
1044 -}  
1045 -static void add_help_9(QPDFArgParser& ap)  
1046 -{  
1047 ap.addOptionHelp("--max-stream-filters", "global", "set the maximum number of filters allowed when filtering streams", R"(--max-stream-filters=n 1052 ap.addOptionHelp("--max-stream-filters", "global", "set the maximum number of filters allowed when filtering streams", R"(--max-stream-filters=n
1048 1053
1049 An excessive number of stream filters is usually a sign that a file 1054 An excessive number of stream filters is usually a sign that a file
libqpdf/qpdf/auto_job_init.hh
@@ -77,6 +77,7 @@ this->ap.addBare("progress", [this](){c_main->progress();}); @@ -77,6 +77,7 @@ this->ap.addBare("progress", [this](){c_main->progress();});
77 this->ap.addBare("qdf", [this](){c_main->qdf();}); 77 this->ap.addBare("qdf", [this](){c_main->qdf();});
78 this->ap.addBare("raw-stream-data", [this](){c_main->rawStreamData();}); 78 this->ap.addBare("raw-stream-data", [this](){c_main->rawStreamData();});
79 this->ap.addBare("recompress-flate", [this](){c_main->recompressFlate();}); 79 this->ap.addBare("recompress-flate", [this](){c_main->recompressFlate();});
  80 +this->ap.addBare("remove-acroform", [this](){c_main->removeAcroform();});
80 this->ap.addBare("remove-info", [this](){c_main->removeInfo();}); 81 this->ap.addBare("remove-info", [this](){c_main->removeInfo();});
81 this->ap.addBare("remove-metadata", [this](){c_main->removeMetadata();}); 82 this->ap.addBare("remove-metadata", [this](){c_main->removeMetadata();});
82 this->ap.addBare("remove-page-labels", [this](){c_main->removePageLabels();}); 83 this->ap.addBare("remove-page-labels", [this](){c_main->removePageLabels();});
libqpdf/qpdf/auto_job_json_init.hh
@@ -436,6 +436,9 @@ addParameter([this](std::string const& p) { c_pages->range(p); }); @@ -436,6 +436,9 @@ addParameter([this](std::string const& p) { c_pages->range(p); });
436 popHandler(); // key: range 436 popHandler(); // key: range
437 popHandler(); // array: .pages[] 437 popHandler(); // array: .pages[]
438 popHandler(); // key: pages 438 popHandler(); // key: pages
  439 +pushKey("removeAcroform");
  440 +addBare([this]() { c_main->removeAcroform(); });
  441 +popHandler(); // key: removeAcroform
439 pushKey("removeInfo"); 442 pushKey("removeInfo");
440 addBare([this]() { c_main->removeInfo(); }); 443 addBare([this]() { c_main->removeInfo(); });
441 popHandler(); // key: removeInfo 444 popHandler(); // key: removeInfo
libqpdf/qpdf/auto_job_schema.hh
@@ -154,6 +154,7 @@ static constexpr char const* JOB_SCHEMA_DATA = R"({ @@ -154,6 +154,7 @@ static constexpr char const* JOB_SCHEMA_DATA = R"({
154 "range": "page range" 154 "range": "page range"
155 } 155 }
156 ], 156 ],
  157 + "removeAcroform": "remove the interactive form dictionary",
157 "removeInfo": "remove file information", 158 "removeInfo": "remove file information",
158 "removeMetadata": "remove metadata", 159 "removeMetadata": "remove metadata",
159 "removePageLabels": "remove explicit page numbers", 160 "removePageLabels": "remove explicit page numbers",
manual/cli.rst
@@ -1641,6 +1641,14 @@ Related Options @@ -1641,6 +1641,14 @@ Related Options
1641 appearances with some limitations. See the 1641 appearances with some limitations. See the
1642 :qpdf:ref:`--generate-appearances` option for details. 1642 :qpdf:ref:`--generate-appearances` option for details.
1643 1643
  1644 + In some damaged files with interactive form fields the form fields
  1645 + in the document's AcroForm structure may be out-of-sync with the
  1646 + corresponding widget annotations on the page. In this case, some
  1647 + viewers may after flattening show some field values twice with
  1648 + a slight offset. In this situation it may help to remove the
  1649 + AcroForm entry in the document catalog using the
  1650 + :qpdf:ref:`--remove-acroform` option after flattening.
  1651 +
1644 .. qpdf:option:: --rotate=[+|-]angle[:page-range] 1652 .. qpdf:option:: --rotate=[+|-]angle[:page-range]
1645 1653
1646 .. help: rotate pages 1654 .. help: rotate pages
@@ -1810,6 +1818,30 @@ Related Options @@ -1810,6 +1818,30 @@ Related Options
1810 Prevent inline images from being included in image optimization 1818 Prevent inline images from being included in image optimization
1811 done by :qpdf:ref:`--optimize-images`. 1819 done by :qpdf:ref:`--optimize-images`.
1812 1820
  1821 +.. qpdf:option:: --remove-acroform
  1822 +
  1823 + .. help: remove the interactive form dictionary
  1824 +
  1825 + Exclude the interactive form dictionary from the output file. This
  1826 + option only removes the interactive form dictionary from the
  1827 + document catalog. It does not remove form field dictionaries or
  1828 + widget annotations. See the manual for more detail.
  1829 +
  1830 +Exclude the interactive form dictionary from the output file. This
  1831 +option only removes the interactive form dictionary from the
  1832 +document catalog. It does not remove form field dictionaries or the
  1833 +associated widget annotations.
  1834 +
  1835 +In some damaged files with interactive form fields the form fields
  1836 +in the document's AcroForm structure may be out-of-sync with the
  1837 +corresponding widget annotations on the page. In this case,
  1838 +different viewers may display different field values, and after flattening
  1839 +annotations with the :qpdf:ref:`--flatten-annotations` option,
  1840 +some viewers may show some field values twice with
  1841 +a slight offset. In this situation it may help to remove the
  1842 +AcroForm entry in the document catalog using this option. **Users should
  1843 +check the output file carefully after using this option**.
  1844 +
1813 .. qpdf:option:: --remove-info 1845 .. qpdf:option:: --remove-info
1814 1846
1815 .. help: remove file information 1847 .. help: remove file information
manual/qpdf.1
@@ -545,6 +545,12 @@ Don't optimize images whose area in pixels is below the specified value. @@ -545,6 +545,12 @@ Don't optimize images whose area in pixels is below the specified value.
545 .B --keep-inline-images \-\- exclude inline images from optimization 545 .B --keep-inline-images \-\- exclude inline images from optimization
546 Prevent inline images from being considered by --optimize-images. 546 Prevent inline images from being considered by --optimize-images.
547 .TP 547 .TP
  548 +.B --remove-acroform \-\- remove the interactive form dictionary
  549 +Exclude the interactive form dictionary from the output file. This
  550 +option only removes the interactive form dictionary from the
  551 +document catalog. It does not remove form field dictionaries or
  552 +widget annotations. See the manual for more detail.
  553 +.TP
548 .B --remove-info \-\- remove file information 554 .B --remove-info \-\- remove file information
549 Exclude file information (except modification date) from the output file. 555 Exclude file information (except modification date) from the output file.
550 .TP 556 .TP
manual/release-notes.rst
@@ -98,6 +98,11 @@ more detail. @@ -98,6 +98,11 @@ more detail.
98 into the environment during completion and to correctly handle 98 into the environment during completion and to correctly handle
99 ``bashcompinit`` for zsh users. 99 ``bashcompinit`` for zsh users.
100 100
  101 + - Add new :qpdf:ref:`--remove-acroform` option to exclude the AcroForm
  102 + dictionary from the output PDF. This option can be useful particularly
  103 + when the :qpdf:ref:`--flatten-annotations` option is used on damaged
  104 + PDF files.
  105 +
101 - Other enhancements 106 - Other enhancements
102 107
103 - Add new ``inspection mode`` to help with the inspection and manual repair 108 - Add new ``inspection mode`` to help with the inspection and manual repair
qpdf/qtest/interactive-form.test
@@ -26,7 +26,7 @@ my @form_tests = ( @@ -26,7 +26,7 @@ my @form_tests = (
26 'form-document-defaults', 26 'form-document-defaults',
27 ); 27 );
28 28
29 -my $n_tests = scalar(@form_tests) + 6; 29 +my $n_tests = scalar(@form_tests) + 8;
30 30
31 # Many of the form*.pdf files were created by converting the 31 # Many of the form*.pdf files were created by converting the
32 # LibreOffice document storage/form.odt to PDF and then manually 32 # LibreOffice document storage/form.odt to PDF and then manually
@@ -70,5 +70,13 @@ $td->runtest("compare files", @@ -70,5 +70,13 @@ $td->runtest("compare files",
70 {$td->FILE => "a.pdf"}, 70 {$td->FILE => "a.pdf"},
71 {$td->FILE => "button-set-broken-out.pdf"}); 71 {$td->FILE => "button-set-broken-out.pdf"});
72 72
  73 +$td->runtest("remove-acroform",
  74 + {$td->COMMAND => "qpdf form-filled-with-atril.pdf --qdf --static-id --remove-acroform a.pdf"},
  75 + {$td->STRING => "", $td->EXIT_STATUS => 0},
  76 + $td->NORMALIZE_NEWLINES);
  77 +$td->runtest("compare files",
  78 + {$td->FILE => "a.pdf"},
  79 + {$td->FILE => "remove-acroform-out.pdf"});
  80 +
73 cleanup(); 81 cleanup();
74 $td->report($n_tests); 82 $td->report($n_tests);
qpdf/qtest/qpdf/remove-acroform-out.pdf 0 → 100644
No preview for this file type