Commit 700dfa40d3d2c5b60bf5937f74c0ab59561115f8

Authored by Jay Berkenbilt
1 parent b5d41b16

QPDFJob: convert encryption handlers

generate_auto_job
... ... @@ -70,6 +70,7 @@ class Main:
70 70 with open('job.yml', 'r') as f:
71 71 data = yaml.safe_load(f.read())
72 72 self.config_decls = {}
  73 + self.declared_configs = set()
73 74 for o in data['options']:
74 75 table = o['table']
75 76 config = o.get('config', None)
... ... @@ -311,14 +312,17 @@ class Main:
311 312 self.init.append(f'this->ap.addChoices("{i}", '
312 313 f'[this](char *x){{{cfg}->{identifier}(x);}}'
313 314 f', false, {v}_choices);')
  315 +
314 316 # Generate declarations for config methods separately by
315 317 # config object.
316 318 config_class = prefix + 'Config'
317 319 arg = ''
318 320 if decl_arg:
319 321 arg = 'char const* parameter'
320   - self.config_decls[cfg].append(
321   - f'QPDF_DLL {config_class}& {identifier}({arg});')
  322 + fn = f'{config_class}& {identifier}({arg})'
  323 + if fn not in self.declared_configs:
  324 + self.declared_configs.add(fn)
  325 + self.config_decls[cfg].append(f'QPDF_DLL {fn};')
322 326  
323 327 def handle_flag(self, i, identifier, kind, v):
324 328 if kind == 'bare':
... ... @@ -393,7 +397,6 @@ class Main:
393 397 config = o.get('config', None)
394 398 table_prefix = o.get('prefix', '')
395 399 arg_prefix = 'arg' + table_prefix
396   - jdata_prefix = table_prefix or table
397 400 if table == 'main':
398 401 self.init.append('this->ap.selectMainOptionTable();')
399 402 elif table == 'help':
... ... @@ -428,29 +431,13 @@ class Main:
428 431 self.handle_flag(i, identifier, kind, v)
429 432 else:
430 433 identifier = self.to_identifier(i, '', False)
  434 + prefix = o.get('config_class', table_prefix)
431 435 self.handle_trivial(
432   - i, identifier, config, table_prefix, kind, v)
  436 + i, identifier, config, prefix, kind, v)
433 437  
434 438 if table not in ('main', 'help'):
435 439 identifier = self.to_identifier(table, 'argEnd', False)
436 440 self.decls.append(f'void {identifier}();')
437   - for o in data['options']:
438   - table = o['table']
439   - jdata_prefix = o.get('prefix', table)
440   - if 'from_table' not in o:
441   - continue
442   - if table == 'main':
443   - self.init.append('this->ap.selectMainOptionTable();')
444   - elif table == 'help':
445   - self.init.append('this->ap.selectHelpOptionTable();')
446   - else:
447   - self.init.append(f'this->ap.selectOptionTable("{table}");')
448   - ft = o['from_table']
449   - other_table = ft['table']
450   - for j in ft['options']:
451   - self.init.append('this->ap.copyFromOtherTable'
452   - f'("{j}", "{other_table}");')
453   - add_jdata(j, jdata_prefix or table)
454 441  
455 442 def generate_schema(self, data):
456 443 # XXX check data['json'] against what we know from jdata.
... ... @@ -537,9 +524,10 @@ class Main:
537 524 ['choices', 'options', 'no-json', 'json']))
538 525 for o in data['options']:
539 526 self.check_keys('top', o, set(
540   - ['table', 'prefix', 'config', 'manual', 'bare', 'positional',
  527 + ['table', 'prefix', 'config', 'config_class',
  528 + 'manual', 'bare', 'positional',
541 529 'optional_parameter', 'required_parameter',
542   - 'required_choices', 'optional_choices', 'from_table']))
  530 + 'required_choices', 'optional_choices']))
543 531  
544 532 def to_identifier(self, label, prefix, const):
545 533 identifier = re.sub(r'[^a-zA-Z0-9]', '_', label)
... ...
include/qpdf/QPDFJob.hh
... ... @@ -217,6 +217,22 @@ class QPDFJob
217 217 Config& config;
218 218 };
219 219  
  220 + class EncConfig
  221 + {
  222 + friend class QPDFJob;
  223 + friend class Config;
  224 + public:
  225 + QPDF_DLL EncConfig& path(char const* parameter);
  226 +
  227 +# include <qpdf/auto_job_c_enc.hh>
  228 +
  229 + private:
  230 + EncConfig(Config&);
  231 + EncConfig(PagesConfig const&) = delete;
  232 +
  233 + Config& config;
  234 + };
  235 +
220 236 // Configuration is performed by calling methods XXX QXXXQ document
221 237 class Config
222 238 {
... ... @@ -228,6 +244,10 @@ class QPDFJob
228 244 std::shared_ptr<PagesConfig> pages();
229 245 std::shared_ptr<UOConfig> overlay();
230 246 std::shared_ptr<UOConfig> underlay();
  247 + std::shared_ptr<EncConfig> encrypt(
  248 + int keylen,
  249 + std::string const& user_password,
  250 + std::string const& owner_password);
231 251  
232 252 # include <qpdf/auto_job_c_main.hh>
233 253  
... ...
include/qpdf/auto_job_c_enc.hh 0 โ†’ 100644
  1 +//
  2 +// This file is automatically generated by generate_auto_job.
  3 +// Edits will be automatically overwritten if the build is
  4 +// run in maintainer mode.
  5 +//
  6 +QPDF_DLL Config& end();
  7 +QPDF_DLL EncConfig& extract(char const* parameter);
  8 +QPDF_DLL EncConfig& annotate(char const* parameter);
  9 +QPDF_DLL EncConfig& print(char const* parameter);
  10 +QPDF_DLL EncConfig& modify(char const* parameter);
  11 +QPDF_DLL EncConfig& cleartextMetadata();
  12 +QPDF_DLL EncConfig& forceV4();
  13 +QPDF_DLL EncConfig& accessibility(char const* parameter);
  14 +QPDF_DLL EncConfig& assemble(char const* parameter);
  15 +QPDF_DLL EncConfig& form(char const* parameter);
  16 +QPDF_DLL EncConfig& modifyOther(char const* parameter);
  17 +QPDF_DLL EncConfig& useAes(char const* parameter);
  18 +QPDF_DLL EncConfig& forceR5();
  19 +QPDF_DLL EncConfig& allowInsecure();
... ...
job.sums
1 1 # Generated by generate_auto_job
2   -generate_auto_job 7a539a822d332e33e08495a82a3fb86ceed2da2bb92ca492dd7ed888d226ab6a
  2 +generate_auto_job 0eaf9d7724199a2a0a57732ea100f2eb55aaa8a1eccea99196190ff4b79fd6e5
3 3 include/qpdf/auto_job_c_att.hh ecc3f8f711b486b491e811176362a90c022eb225ff12157df3a10ca021be87b1
4 4 include/qpdf/auto_job_c_copy_att.hh caffae3d1faf2cd92a07ba77da638cce31da3e074a047918834195c0f3ed508a
  5 +include/qpdf/auto_job_c_enc.hh e2e1a163a7ffebbf8af169dc4a28ab00df3b8d229864bca7d203dde8b56f0864
5 6 include/qpdf/auto_job_c_main.hh 7f7c0a4d8e640a2d24908af348f7b658ca81d3d8aa5346cf4327f6c1d4021119
6 7 include/qpdf/auto_job_c_pages.hh 79ee6e52a36fedfd0e6ca60bd926bc25a3e975ab6fa984a7e798a48791e8ba86
7 8 include/qpdf/auto_job_c_uo.hh 80404376f19fe57d67421ad0c5fb1755811758c73870df96f081f032b196deff
8   -job.yml 1f508cb7108c55885fbe98537676573bbfddf7b476b2023fd10a975d47afc037
9   -libqpdf/qpdf/auto_job_decl.hh dc9232ed6961d709abacbbf71eb7d19c5e6951894aec6f480afcd3b6ba463206
  9 +job.yml c5dbc36d984cdb325b2baf1bd7a788fea58c7054e1da94b107283094da3d102c
  10 +libqpdf/qpdf/auto_job_decl.hh 12b96d3201681d9805bc04767ed34f9cd2243e7a5f8930da968518aa22388f36
10 11 libqpdf/qpdf/auto_job_help.hh 383eea80e2c185ef5295fc126246457a7ceeffea759fdb90bb2e6727532ea538
11   -libqpdf/qpdf/auto_job_init.hh 25a93a4ded91e1faa2d6a9d2bb85d811b5b49ae54c9fbdccad65b94538365418
12   -libqpdf/qpdf/auto_job_schema.hh 6e6d72e99dacd02c22d9ac70f4dc78a935f879d2a16c89f07f2bdfa936cc2ae3
  12 +libqpdf/qpdf/auto_job_init.hh c9f3c31d7c52f1a5159807763becbf15f039f9aa06e41a14f578ee407462ba94
  13 +libqpdf/qpdf/auto_job_schema.hh c33c5953b589993334d49f71f0b6ce4b3a12af6e14a7a925be257de04c05f7d6
13 14 manual/_ext/qpdf.py 855fe12de5af7a10bb24be6ecc4d5dff4c84ac58cf388a13be6bbb394346a67d
14 15 manual/cli.rst 68122ff8179c10df3fe6d577adde4973c346f7866ba9a511bab5a6e6f292a6f1
... ...
... ... @@ -166,6 +166,8 @@ options:
166 166 prefix: Enc
167 167 positional: true
168 168 - table: 40-bit encryption
  169 + config: c_enc
  170 + config_class: Enc
169 171 prefix: Enc40
170 172 required_choices:
171 173 extract: yn
... ... @@ -173,6 +175,8 @@ options:
173 175 print: yn
174 176 modify: yn
175 177 - table: 128-bit encryption
  178 + config: c_enc
  179 + config_class: Enc
176 180 prefix: Enc128
177 181 bare:
178 182 - cleartext-metadata
... ... @@ -188,22 +192,22 @@ options:
188 192 modify: modify128
189 193 use-aes: yn
190 194 - table: 256-bit encryption
  195 + config: c_enc
  196 + config_class: Enc
191 197 prefix: Enc256
192   - from_table:
193   - table: 128-bit encryption
194   - options:
195   - - cleartext-metadata
196   - - accessibility
197   - - extract
198   - - print
199   - - assemble
200   - - annotate
201   - - form
202   - - modify-other
203   - - modify
204 198 bare:
  199 + - cleartext-metadata
205 200 - force-R5
206 201 - allow-insecure
  202 + required_choices:
  203 + accessibility: yn
  204 + extract: yn
  205 + print: print128
  206 + assemble: yn
  207 + annotate: yn
  208 + form: yn
  209 + modify-other: yn
  210 + modify: modify128
207 211 - table: underlay/overlay
208 212 config: c_uo
209 213 prefix: UO
... ... @@ -277,9 +281,9 @@ json:
277 281 force-version:
278 282 progress:
279 283 encrypt:
  284 + key-length: "key length: 48, 128, 256"
280 285 user-password: "user password"
281 286 owner-password: "owner password"
282   - key-length: "key length: 48, 128, 256"
283 287 _40-bit:
284 288 Enc40.annotate:
285 289 Enc40.extract:
... ...
libqpdf/QPDFJob_argv.cc
... ... @@ -44,6 +44,7 @@ namespace
44 44 std::shared_ptr<QPDFJob::AttConfig> c_att;
45 45 std::shared_ptr<QPDFJob::PagesConfig> c_pages;
46 46 std::shared_ptr<QPDFJob::UOConfig> c_uo;
  47 + std::shared_ptr<QPDFJob::EncConfig> c_enc;
47 48 std::vector<char*> accumulated_args; // points to member in ap
48 49 char* pages_password;
49 50 };
... ... @@ -217,35 +218,30 @@ ArgParser::argEncPositional(char* arg)
217 218 }
218 219 return;
219 220 }
220   - o.user_password = this->accumulated_args.at(0);
221   - o.owner_password = this->accumulated_args.at(1);
  221 + std::string user_password = this->accumulated_args.at(0);
  222 + std::string owner_password = this->accumulated_args.at(1);
222 223 std::string len_str = this->accumulated_args.at(2);
  224 + int keylen = 0;
223 225 if (len_str == "40")
224 226 {
225   - o.keylen = 40;
  227 + keylen = 40;
226 228 this->ap.selectOptionTable(O_40_BIT_ENCRYPTION);
227 229 }
228 230 else if (len_str == "128")
229 231 {
230   - o.keylen = 128;
  232 + keylen = 128;
231 233 this->ap.selectOptionTable(O_128_BIT_ENCRYPTION);
232 234 }
233 235 else if (len_str == "256")
234 236 {
235   - o.keylen = 256;
236   - o.use_aes = true;
  237 + keylen = 256;
237 238 this->ap.selectOptionTable(O_256_BIT_ENCRYPTION);
238 239 }
239 240 else
240 241 {
241 242 usage("encryption key length must be 40, 128, or 256");
242 243 }
243   -}
244   -
245   -void
246   -ArgParser::argEnc256AllowInsecure()
247   -{
248   - o.allow_insecure = true;
  244 + this->c_enc = c_main->encrypt(keylen, user_password, owner_password);
249 245 }
250 246  
251 247 void
... ... @@ -395,160 +391,10 @@ ArgParser::argCopyAttachmentsFrom()
395 391 }
396 392  
397 393 void
398   -ArgParser::argEnc40Print(char* parameter)
399   -{
400   - o.r2_print = (strcmp(parameter, "y") == 0);
401   -}
402   -
403   -void
404   -ArgParser::argEnc40Modify(char* parameter)
405   -{
406   - o.r2_modify = (strcmp(parameter, "y") == 0);
407   -}
408   -
409   -void
410   -ArgParser::argEnc40Extract(char* parameter)
411   -{
412   - o.r2_extract = (strcmp(parameter, "y") == 0);
413   -}
414   -
415   -void
416   -ArgParser::argEnc40Annotate(char* parameter)
417   -{
418   - o.r2_annotate = (strcmp(parameter, "y") == 0);
419   -}
420   -
421   -void
422   -ArgParser::argEnc128Accessibility(char* parameter)
423   -{
424   - o.r3_accessibility = (strcmp(parameter, "y") == 0);
425   -}
426   -
427   -void
428   -ArgParser::argEnc128Extract(char* parameter)
429   -{
430   - o.r3_extract = (strcmp(parameter, "y") == 0);
431   -}
432   -
433   -void
434   -ArgParser::argEnc128Print(char* parameter)
435   -{
436   - if (strcmp(parameter, "full") == 0)
437   - {
438   - o.r3_print = qpdf_r3p_full;
439   - }
440   - else if (strcmp(parameter, "low") == 0)
441   - {
442   - o.r3_print = qpdf_r3p_low;
443   - }
444   - else if (strcmp(parameter, "none") == 0)
445   - {
446   - o.r3_print = qpdf_r3p_none;
447   - }
448   - else
449   - {
450   - usage("invalid print option");
451   - }
452   -}
453   -
454   -void
455   -ArgParser::argEnc128Modify(char* parameter)
456   -{
457   - if (strcmp(parameter, "all") == 0)
458   - {
459   - o.r3_assemble = true;
460   - o.r3_annotate_and_form = true;
461   - o.r3_form_filling = true;
462   - o.r3_modify_other = true;
463   - }
464   - else if (strcmp(parameter, "annotate") == 0)
465   - {
466   - o.r3_assemble = true;
467   - o.r3_annotate_and_form = true;
468   - o.r3_form_filling = true;
469   - o.r3_modify_other = false;
470   - }
471   - else if (strcmp(parameter, "form") == 0)
472   - {
473   - o.r3_assemble = true;
474   - o.r3_annotate_and_form = false;
475   - o.r3_form_filling = true;
476   - o.r3_modify_other = false;
477   - }
478   - else if (strcmp(parameter, "assembly") == 0)
479   - {
480   - o.r3_assemble = true;
481   - o.r3_annotate_and_form = false;
482   - o.r3_form_filling = false;
483   - o.r3_modify_other = false;
484   - }
485   - else if (strcmp(parameter, "none") == 0)
486   - {
487   - o.r3_assemble = false;
488   - o.r3_annotate_and_form = false;
489   - o.r3_form_filling = false;
490   - o.r3_modify_other = false;
491   - }
492   - else
493   - {
494   - usage("invalid modify option");
495   - }
496   -}
497   -
498   -void
499   -ArgParser::argEnc128CleartextMetadata()
500   -{
501   - o.cleartext_metadata = true;
502   -}
503   -
504   -void
505   -ArgParser::argEnc128Assemble(char* parameter)
506   -{
507   - o.r3_assemble = (strcmp(parameter, "y") == 0);
508   -}
509   -
510   -void
511   -ArgParser::argEnc128Annotate(char* parameter)
512   -{
513   - o.r3_annotate_and_form = (strcmp(parameter, "y") == 0);
514   -}
515   -
516   -void
517   -ArgParser::argEnc128Form(char* parameter)
518   -{
519   - o.r3_form_filling = (strcmp(parameter, "y") == 0);
520   -}
521   -
522   -void
523   -ArgParser::argEnc128ModifyOther(char* parameter)
524   -{
525   - o.r3_modify_other = (strcmp(parameter, "y") == 0);
526   -}
527   -
528   -void
529   -ArgParser::argEnc128UseAes(char* parameter)
530   -{
531   - o.use_aes = (strcmp(parameter, "y") == 0);
532   -}
533   -
534   -void
535   -ArgParser::argEnc128ForceV4()
536   -{
537   - o.force_V4 = true;
538   -}
539   -
540   -void
541   -ArgParser::argEnc256ForceR5()
542   -{
543   - o.force_R5 = true;
544   -}
545   -
546   -void
547 394 ArgParser::argEndEncryption()
548 395 {
549   - o.encrypt = true;
550   - o.decrypt = false;
551   - o.copy_encryption = false;
  396 + c_enc->end();
  397 + c_enc = nullptr;
552 398 }
553 399  
554 400 void
... ...
libqpdf/QPDFJob_config.cc
... ... @@ -963,3 +963,198 @@ QPDFJob::UOConfig::password(char const* parameter)
963 963 config.o.under_overlay->password = QUtil::make_shared_cstr(parameter);
964 964 return *this;
965 965 }
  966 +
  967 +std::shared_ptr<QPDFJob::EncConfig>
  968 +QPDFJob::Config::encrypt(int keylen,
  969 + std::string const& user_password,
  970 + std::string const& owner_password)
  971 +{
  972 + o.keylen = keylen;
  973 + if (keylen == 256)
  974 + {
  975 + o.use_aes = true;
  976 + }
  977 + o.user_password = user_password;
  978 + o.owner_password = owner_password;
  979 + return std::shared_ptr<EncConfig>(new EncConfig(*this));
  980 +}
  981 +
  982 +QPDFJob::EncConfig::EncConfig(Config& c) :
  983 + config(c)
  984 +{
  985 +}
  986 +
  987 +QPDFJob::Config&
  988 +QPDFJob::EncConfig::end()
  989 +{
  990 + config.o.encrypt = true;
  991 + config.o.decrypt = false;
  992 + config.o.copy_encryption = false;
  993 + return this->config;
  994 +}
  995 +
  996 +QPDFJob::EncConfig&
  997 +QPDFJob::EncConfig::allowInsecure()
  998 +{
  999 + config.o.allow_insecure = true;
  1000 + return *this;
  1001 +}
  1002 +
  1003 +QPDFJob::EncConfig&
  1004 +QPDFJob::EncConfig::accessibility(char const* parameter)
  1005 +{
  1006 + config.o.r3_accessibility = (strcmp(parameter, "y") == 0);
  1007 + return *this;
  1008 +}
  1009 +
  1010 +QPDFJob::EncConfig&
  1011 +QPDFJob::EncConfig::extract(char const* parameter)
  1012 +{
  1013 + if (config.o.keylen == 40)
  1014 + {
  1015 + config.o.r2_extract = (strcmp(parameter, "y") == 0);
  1016 + }
  1017 + else
  1018 + {
  1019 + config.o.r3_extract = (strcmp(parameter, "y") == 0);
  1020 + }
  1021 + return *this;
  1022 +}
  1023 +
  1024 +QPDFJob::EncConfig&
  1025 +QPDFJob::EncConfig::print(char const* parameter)
  1026 +{
  1027 + if (config.o.keylen == 40)
  1028 + {
  1029 + config.o.r2_print = (strcmp(parameter, "y") == 0);
  1030 + }
  1031 + else if (strcmp(parameter, "full") == 0)
  1032 + {
  1033 + config.o.r3_print = qpdf_r3p_full;
  1034 + }
  1035 + else if (strcmp(parameter, "low") == 0)
  1036 + {
  1037 + config.o.r3_print = qpdf_r3p_low;
  1038 + }
  1039 + else if (strcmp(parameter, "none") == 0)
  1040 + {
  1041 + config.o.r3_print = qpdf_r3p_none;
  1042 + }
  1043 + else
  1044 + {
  1045 + usage("invalid print option");
  1046 + }
  1047 + return *this;
  1048 +}
  1049 +
  1050 +QPDFJob::EncConfig&
  1051 +QPDFJob::EncConfig::modify(char const* parameter)
  1052 +{
  1053 + if (config.o.keylen == 40)
  1054 + {
  1055 + config.o.r2_modify = (strcmp(parameter, "y") == 0);
  1056 + }
  1057 + else if (strcmp(parameter, "all") == 0)
  1058 + {
  1059 + config.o.r3_assemble = true;
  1060 + config.o.r3_annotate_and_form = true;
  1061 + config.o.r3_form_filling = true;
  1062 + config.o.r3_modify_other = true;
  1063 + }
  1064 + else if (strcmp(parameter, "annotate") == 0)
  1065 + {
  1066 + config.o.r3_assemble = true;
  1067 + config.o.r3_annotate_and_form = true;
  1068 + config.o.r3_form_filling = true;
  1069 + config.o.r3_modify_other = false;
  1070 + }
  1071 + else if (strcmp(parameter, "form") == 0)
  1072 + {
  1073 + config.o.r3_assemble = true;
  1074 + config.o.r3_annotate_and_form = false;
  1075 + config.o.r3_form_filling = true;
  1076 + config.o.r3_modify_other = false;
  1077 + }
  1078 + else if (strcmp(parameter, "assembly") == 0)
  1079 + {
  1080 + config.o.r3_assemble = true;
  1081 + config.o.r3_annotate_and_form = false;
  1082 + config.o.r3_form_filling = false;
  1083 + config.o.r3_modify_other = false;
  1084 + }
  1085 + else if (strcmp(parameter, "none") == 0)
  1086 + {
  1087 + config.o.r3_assemble = false;
  1088 + config.o.r3_annotate_and_form = false;
  1089 + config.o.r3_form_filling = false;
  1090 + config.o.r3_modify_other = false;
  1091 + }
  1092 + else
  1093 + {
  1094 + usage("invalid modify option");
  1095 + }
  1096 + return *this;
  1097 +}
  1098 +
  1099 +QPDFJob::EncConfig&
  1100 +QPDFJob::EncConfig::cleartextMetadata()
  1101 +{
  1102 + config.o.cleartext_metadata = true;
  1103 + return *this;
  1104 +}
  1105 +
  1106 +QPDFJob::EncConfig&
  1107 +QPDFJob::EncConfig::assemble(char const* parameter)
  1108 +{
  1109 + config.o.r3_assemble = (strcmp(parameter, "y") == 0);
  1110 + return *this;
  1111 +}
  1112 +
  1113 +QPDFJob::EncConfig&
  1114 +QPDFJob::EncConfig::annotate(char const* parameter)
  1115 +{
  1116 + if (config.o.keylen == 40)
  1117 + {
  1118 + config.o.r2_annotate = (strcmp(parameter, "y") == 0);
  1119 + }
  1120 + else
  1121 + {
  1122 + config.o.r3_annotate_and_form = (strcmp(parameter, "y") == 0);
  1123 + }
  1124 + return *this;
  1125 +}
  1126 +
  1127 +QPDFJob::EncConfig&
  1128 +QPDFJob::EncConfig::form(char const* parameter)
  1129 +{
  1130 + config.o.r3_form_filling = (strcmp(parameter, "y") == 0);
  1131 + return *this;
  1132 +}
  1133 +
  1134 +QPDFJob::EncConfig&
  1135 +QPDFJob::EncConfig::modifyOther(char const* parameter)
  1136 +{
  1137 + config.o.r3_modify_other = (strcmp(parameter, "y") == 0);
  1138 + return *this;
  1139 +}
  1140 +
  1141 +QPDFJob::EncConfig&
  1142 +QPDFJob::EncConfig::useAes(char const* parameter)
  1143 +{
  1144 + config.o.use_aes = (strcmp(parameter, "y") == 0);
  1145 + return *this;
  1146 +}
  1147 +
  1148 +QPDFJob::EncConfig&
  1149 +QPDFJob::EncConfig::forceV4()
  1150 +{
  1151 + config.o.force_V4 = true;
  1152 + return *this;
  1153 +}
  1154 +
  1155 +QPDFJob::EncConfig&
  1156 +QPDFJob::EncConfig::forceR5()
  1157 +{
  1158 + config.o.force_R5 = true;
  1159 + return *this;
  1160 +}
... ...
libqpdf/qpdf/auto_job_decl.hh
... ... @@ -29,25 +29,8 @@ void argPagesPassword(char *);
29 29 void argEndPages();
30 30 void argEncPositional(char*);
31 31 void argEndEncryption();
32   -void argEnc40Extract(char *);
33   -void argEnc40Annotate(char *);
34   -void argEnc40Print(char *);
35   -void argEnc40Modify(char *);
36 32 void argEnd40BitEncryption();
37   -void argEnc128CleartextMetadata();
38   -void argEnc128ForceV4();
39   -void argEnc128Accessibility(char *);
40   -void argEnc128Extract(char *);
41   -void argEnc128Print(char *);
42   -void argEnc128Assemble(char *);
43   -void argEnc128Annotate(char *);
44   -void argEnc128Form(char *);
45   -void argEnc128ModifyOther(char *);
46   -void argEnc128Modify(char *);
47   -void argEnc128UseAes(char *);
48 33 void argEnd128BitEncryption();
49   -void argEnc256ForceR5();
50   -void argEnc256AllowInsecure();
51 34 void argEnd256BitEncryption();
52 35 void argUOPositional(char*);
53 36 void argEndUnderlayOverlay();
... ...
libqpdf/qpdf/auto_job_init.hh
... ... @@ -116,25 +116,34 @@ this-&gt;ap.addRequiredParameter(&quot;password&quot;, p(&amp;ArgParser::argPagesPassword), &quot;pass
116 116 this->ap.registerOptionTable("encryption", b(&ArgParser::argEndEncryption));
117 117 this->ap.addPositional(p(&ArgParser::argEncPositional));
118 118 this->ap.registerOptionTable("40-bit encryption", b(&ArgParser::argEnd40BitEncryption));
119   -this->ap.addChoices("extract", p(&ArgParser::argEnc40Extract), true, yn_choices);
120   -this->ap.addChoices("annotate", p(&ArgParser::argEnc40Annotate), true, yn_choices);
121   -this->ap.addChoices("print", p(&ArgParser::argEnc40Print), true, yn_choices);
122   -this->ap.addChoices("modify", p(&ArgParser::argEnc40Modify), true, yn_choices);
  119 +this->ap.addChoices("extract", [this](char *x){c_enc->extract(x);}, true, yn_choices);
  120 +this->ap.addChoices("annotate", [this](char *x){c_enc->annotate(x);}, true, yn_choices);
  121 +this->ap.addChoices("print", [this](char *x){c_enc->print(x);}, true, yn_choices);
  122 +this->ap.addChoices("modify", [this](char *x){c_enc->modify(x);}, true, yn_choices);
123 123 this->ap.registerOptionTable("128-bit encryption", b(&ArgParser::argEnd128BitEncryption));
124   -this->ap.addBare("cleartext-metadata", b(&ArgParser::argEnc128CleartextMetadata));
125   -this->ap.addBare("force-V4", b(&ArgParser::argEnc128ForceV4));
126   -this->ap.addChoices("accessibility", p(&ArgParser::argEnc128Accessibility), true, yn_choices);
127   -this->ap.addChoices("extract", p(&ArgParser::argEnc128Extract), true, yn_choices);
128   -this->ap.addChoices("print", p(&ArgParser::argEnc128Print), true, print128_choices);
129   -this->ap.addChoices("assemble", p(&ArgParser::argEnc128Assemble), true, yn_choices);
130   -this->ap.addChoices("annotate", p(&ArgParser::argEnc128Annotate), true, yn_choices);
131   -this->ap.addChoices("form", p(&ArgParser::argEnc128Form), true, yn_choices);
132   -this->ap.addChoices("modify-other", p(&ArgParser::argEnc128ModifyOther), true, yn_choices);
133   -this->ap.addChoices("modify", p(&ArgParser::argEnc128Modify), true, modify128_choices);
134   -this->ap.addChoices("use-aes", p(&ArgParser::argEnc128UseAes), true, yn_choices);
  124 +this->ap.addBare("cleartext-metadata", [this](){c_enc->cleartextMetadata();});
  125 +this->ap.addBare("force-V4", [this](){c_enc->forceV4();});
  126 +this->ap.addChoices("accessibility", [this](char *x){c_enc->accessibility(x);}, true, yn_choices);
  127 +this->ap.addChoices("extract", [this](char *x){c_enc->extract(x);}, true, yn_choices);
  128 +this->ap.addChoices("print", [this](char *x){c_enc->print(x);}, true, print128_choices);
  129 +this->ap.addChoices("assemble", [this](char *x){c_enc->assemble(x);}, true, yn_choices);
  130 +this->ap.addChoices("annotate", [this](char *x){c_enc->annotate(x);}, true, yn_choices);
  131 +this->ap.addChoices("form", [this](char *x){c_enc->form(x);}, true, yn_choices);
  132 +this->ap.addChoices("modify-other", [this](char *x){c_enc->modifyOther(x);}, true, yn_choices);
  133 +this->ap.addChoices("modify", [this](char *x){c_enc->modify(x);}, true, modify128_choices);
  134 +this->ap.addChoices("use-aes", [this](char *x){c_enc->useAes(x);}, true, yn_choices);
135 135 this->ap.registerOptionTable("256-bit encryption", b(&ArgParser::argEnd256BitEncryption));
136   -this->ap.addBare("force-R5", b(&ArgParser::argEnc256ForceR5));
137   -this->ap.addBare("allow-insecure", b(&ArgParser::argEnc256AllowInsecure));
  136 +this->ap.addBare("cleartext-metadata", [this](){c_enc->cleartextMetadata();});
  137 +this->ap.addBare("force-R5", [this](){c_enc->forceR5();});
  138 +this->ap.addBare("allow-insecure", [this](){c_enc->allowInsecure();});
  139 +this->ap.addChoices("accessibility", [this](char *x){c_enc->accessibility(x);}, true, yn_choices);
  140 +this->ap.addChoices("extract", [this](char *x){c_enc->extract(x);}, true, yn_choices);
  141 +this->ap.addChoices("print", [this](char *x){c_enc->print(x);}, true, print128_choices);
  142 +this->ap.addChoices("assemble", [this](char *x){c_enc->assemble(x);}, true, yn_choices);
  143 +this->ap.addChoices("annotate", [this](char *x){c_enc->annotate(x);}, true, yn_choices);
  144 +this->ap.addChoices("form", [this](char *x){c_enc->form(x);}, true, yn_choices);
  145 +this->ap.addChoices("modify-other", [this](char *x){c_enc->modifyOther(x);}, true, yn_choices);
  146 +this->ap.addChoices("modify", [this](char *x){c_enc->modify(x);}, true, modify128_choices);
138 147 this->ap.registerOptionTable("underlay/overlay", b(&ArgParser::argEndUnderlayOverlay));
139 148 this->ap.addPositional(p(&ArgParser::argUOPositional));
140 149 this->ap.addRequiredParameter("to", [this](char *x){c_uo->to(x);}, "page-range");
... ... @@ -154,13 +163,3 @@ this-&gt;ap.registerOptionTable(&quot;copy attachment&quot;, b(&amp;ArgParser::argEndCopyAttachme
154 163 this->ap.addPositional(p(&ArgParser::argCopyAttPositional));
155 164 this->ap.addRequiredParameter("prefix", [this](char *x){c_copy_att->prefix(x);}, "prefix");
156 165 this->ap.addRequiredParameter("password", [this](char *x){c_copy_att->password(x);}, "password");
157   -this->ap.selectOptionTable("256-bit encryption");
158   -this->ap.copyFromOtherTable("cleartext-metadata", "128-bit encryption");
159   -this->ap.copyFromOtherTable("accessibility", "128-bit encryption");
160   -this->ap.copyFromOtherTable("extract", "128-bit encryption");
161   -this->ap.copyFromOtherTable("print", "128-bit encryption");
162   -this->ap.copyFromOtherTable("assemble", "128-bit encryption");
163   -this->ap.copyFromOtherTable("annotate", "128-bit encryption");
164   -this->ap.copyFromOtherTable("form", "128-bit encryption");
165   -this->ap.copyFromOtherTable("modify-other", "128-bit encryption");
166   -this->ap.copyFromOtherTable("modify", "128-bit encryption");
... ...
libqpdf/qpdf/auto_job_schema.hh
... ... @@ -35,9 +35,9 @@ static constexpr char const* JOB_SCHEMA_DATA = R&quot;({
35 35 "forceVersion": "set output PDF version",
36 36 "progress": "show progress when writing",
37 37 "encrypt": {
  38 + "keyLength": "key length: 48, 128, 256",
38 39 "userPassword": "user password",
39 40 "ownerPassword": "owner password",
40   - "keyLength": "key length: 48, 128, 256",
41 41 "40Bit": {
42 42 "annotate": "restrict document annotation",
43 43 "extract": "restrict text/graphic extraction",
... ...