2022-01-26 21:48:18 +00:00
|
|
|
#include <qpdf/QPDFJob.hh>
|
2022-02-04 21:31:31 +00:00
|
|
|
|
2022-01-26 21:48:18 +00:00
|
|
|
#include <qpdf/JSONHandler.hh>
|
2022-01-29 17:29:38 +00:00
|
|
|
#include <qpdf/QPDFUsage.hh>
|
2022-01-31 20:56:05 +00:00
|
|
|
#include <qpdf/QTC.hh>
|
2022-04-02 21:14:10 +00:00
|
|
|
#include <qpdf/QUtil.hh>
|
2022-01-26 21:48:18 +00:00
|
|
|
|
2022-04-02 21:14:10 +00:00
|
|
|
#include <cstring>
|
2022-01-26 21:48:18 +00:00
|
|
|
#include <memory>
|
|
|
|
#include <sstream>
|
2022-04-02 21:14:10 +00:00
|
|
|
#include <stdexcept>
|
2022-01-26 21:48:18 +00:00
|
|
|
|
2022-07-31 12:03:18 +00:00
|
|
|
static JSON JOB_SCHEMA = JSON::parse(QPDFJob::job_json_schema(1).c_str());
|
2022-01-26 21:48:18 +00:00
|
|
|
|
2022-01-29 13:54:08 +00:00
|
|
|
namespace
|
|
|
|
{
|
|
|
|
class Handlers
|
|
|
|
{
|
|
|
|
public:
|
2022-01-30 19:39:38 +00:00
|
|
|
Handlers(bool partial, std::shared_ptr<QPDFJob::Config> c_main);
|
2022-01-29 13:54:08 +00:00
|
|
|
void handle(JSON&);
|
|
|
|
|
|
|
|
private:
|
2022-04-02 21:14:10 +00:00
|
|
|
#include <qpdf/auto_job_json_decl.hh>
|
2022-01-29 13:54:08 +00:00
|
|
|
|
|
|
|
void usage(std::string const& message);
|
|
|
|
void initHandlers();
|
|
|
|
|
2022-01-29 23:26:11 +00:00
|
|
|
typedef std::function<void()> bare_handler_t;
|
|
|
|
typedef std::function<void(char const*)> param_handler_t;
|
2022-01-30 13:04:45 +00:00
|
|
|
typedef std::function<void(JSON)> json_handler_t;
|
2022-01-31 12:34:40 +00:00
|
|
|
|
2023-05-27 17:19:52 +00:00
|
|
|
// The code that calls these methods is automatically generated by generate_auto_job. This
|
|
|
|
// describes how we implement what it does. We keep a stack of handlers in json_handlers.
|
2023-10-07 21:46:07 +00:00
|
|
|
// The top of the stack is the "current" json handler, initially for the top-level object.
|
2023-05-27 17:19:52 +00:00
|
|
|
// Whenever we encounter a scalar, we add a handler using addBare, addParameter, or
|
|
|
|
// addChoices. Whenever we encounter a dictionary, we first add the dictionary handlers.
|
|
|
|
// Then we walk into the dictionary and, for each key, we register a dict key handler and
|
|
|
|
// push it to the stack, then do the same process for the key's value. Then we pop the key
|
|
|
|
// handler off the stack. When we encounter an array, we add the array handlers, push an
|
|
|
|
// item handler to the stack, call recursively for the array's single item (as this is what
|
|
|
|
// is expected in a schema), and pop the item handler. Note that we don't pop dictionary
|
|
|
|
// start/end handlers. The dictionary handlers and the key handlers are at the same level in
|
|
|
|
// JSONHandler. This logic is subtle and took several tries to get right. It's best
|
|
|
|
// understood by carefully understanding the behavior of JSONHandler, the JSON schema, and
|
|
|
|
// the code in generate_auto_job.
|
2022-02-01 12:18:23 +00:00
|
|
|
|
2022-01-31 12:34:40 +00:00
|
|
|
void addBare(bare_handler_t);
|
|
|
|
void addParameter(param_handler_t);
|
2022-01-31 23:15:10 +00:00
|
|
|
void addChoices(char const** choices, bool required, param_handler_t);
|
2022-01-31 12:34:40 +00:00
|
|
|
void pushKey(std::string const& key);
|
2022-04-02 21:14:10 +00:00
|
|
|
void beginDict(json_handler_t start_fn, bare_handler_t end_fn);
|
|
|
|
void beginArray(json_handler_t start_fn, bare_handler_t end_fn);
|
2022-01-31 12:34:40 +00:00
|
|
|
void ignoreItem();
|
|
|
|
void popHandler();
|
2022-01-29 17:29:38 +00:00
|
|
|
|
2022-01-29 23:26:11 +00:00
|
|
|
bare_handler_t bindBare(void (Handlers::*f)());
|
2022-01-30 13:04:45 +00:00
|
|
|
json_handler_t bindJSON(void (Handlers::*f)(JSON));
|
2022-01-29 23:26:11 +00:00
|
|
|
|
2022-01-29 17:29:38 +00:00
|
|
|
std::list<std::shared_ptr<JSONHandler>> json_handlers;
|
2022-01-30 19:39:38 +00:00
|
|
|
bool partial;
|
2023-06-01 13:12:39 +00:00
|
|
|
JSONHandler* jh{nullptr}; // points to last of json_handlers
|
2022-01-29 13:54:08 +00:00
|
|
|
std::shared_ptr<QPDFJob::Config> c_main;
|
|
|
|
std::shared_ptr<QPDFJob::CopyAttConfig> c_copy_att;
|
|
|
|
std::shared_ptr<QPDFJob::AttConfig> c_att;
|
|
|
|
std::shared_ptr<QPDFJob::PagesConfig> c_pages;
|
|
|
|
std::shared_ptr<QPDFJob::UOConfig> c_uo;
|
|
|
|
std::shared_ptr<QPDFJob::EncConfig> c_enc;
|
|
|
|
};
|
2022-04-02 21:14:10 +00:00
|
|
|
} // namespace
|
2022-01-29 13:54:08 +00:00
|
|
|
|
2022-01-30 19:39:38 +00:00
|
|
|
Handlers::Handlers(bool partial, std::shared_ptr<QPDFJob::Config> c_main) :
|
|
|
|
partial(partial),
|
2022-01-29 13:54:08 +00:00
|
|
|
c_main(c_main)
|
|
|
|
{
|
|
|
|
initHandlers();
|
|
|
|
}
|
|
|
|
|
2022-01-29 17:29:38 +00:00
|
|
|
void
|
|
|
|
Handlers::usage(std::string const& message)
|
|
|
|
{
|
|
|
|
throw QPDFUsage(message);
|
|
|
|
}
|
|
|
|
|
2022-01-29 23:26:11 +00:00
|
|
|
Handlers::bare_handler_t
|
|
|
|
Handlers::bindBare(void (Handlers::*f)())
|
|
|
|
{
|
|
|
|
return std::bind(std::mem_fn(f), this);
|
|
|
|
}
|
|
|
|
|
2022-01-30 13:04:45 +00:00
|
|
|
Handlers::json_handler_t
|
|
|
|
Handlers::bindJSON(void (Handlers::*f)(JSON))
|
|
|
|
{
|
|
|
|
return std::bind(std::mem_fn(f), this, std::placeholders::_1);
|
|
|
|
}
|
|
|
|
|
2022-01-29 13:54:08 +00:00
|
|
|
void
|
|
|
|
Handlers::initHandlers()
|
|
|
|
{
|
2022-01-29 17:29:38 +00:00
|
|
|
this->json_handlers.push_back(std::make_shared<JSONHandler>());
|
|
|
|
this->jh = this->json_handlers.back().get();
|
|
|
|
jh->addDictHandlers(
|
2022-04-02 21:14:10 +00:00
|
|
|
[](std::string const&, JSON) {},
|
|
|
|
[this](std::string const&) {
|
|
|
|
if (!this->partial) {
|
2022-01-30 19:39:38 +00:00
|
|
|
c_main->checkConfiguration();
|
|
|
|
}
|
|
|
|
});
|
2022-01-29 13:54:08 +00:00
|
|
|
|
2022-04-02 21:14:10 +00:00
|
|
|
#include <qpdf/auto_job_json_init.hh>
|
2022-01-29 13:54:08 +00:00
|
|
|
|
2023-12-22 21:27:56 +00:00
|
|
|
// We have `bits` in the CLI but not in the JSON. Reference this variable so it doesn't generate
|
|
|
|
// a warning.
|
|
|
|
[](char const**) {}(enc_bits_choices);
|
|
|
|
|
2022-04-02 21:14:10 +00:00
|
|
|
if (this->json_handlers.size() != 1) {
|
2022-01-29 17:29:38 +00:00
|
|
|
throw std::logic_error("QPDFJob_json: json_handlers size != 1 at end");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-01-31 12:34:40 +00:00
|
|
|
Handlers::addBare(bare_handler_t fn)
|
2022-01-29 17:29:38 +00:00
|
|
|
{
|
2023-05-21 17:35:09 +00:00
|
|
|
jh->addStringHandler([this, fn](std::string const& path, std::string const& parameter) {
|
|
|
|
if (!parameter.empty()) {
|
|
|
|
QTC::TC("qpdf", "QPDFJob json bare not empty");
|
|
|
|
usage(path + ": value must be the empty string");
|
|
|
|
} else {
|
|
|
|
fn();
|
|
|
|
}
|
|
|
|
});
|
2022-01-29 17:29:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-01-31 12:34:40 +00:00
|
|
|
Handlers::addParameter(param_handler_t fn)
|
2022-01-29 17:29:38 +00:00
|
|
|
{
|
2022-01-31 12:34:40 +00:00
|
|
|
jh->addStringHandler(
|
2023-05-21 17:35:09 +00:00
|
|
|
[fn](std::string const& path, std::string const& parameter) { fn(parameter.c_str()); });
|
2022-01-29 17:29:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-01-31 23:15:10 +00:00
|
|
|
Handlers::addChoices(char const** choices, bool required, param_handler_t fn)
|
2022-01-29 17:29:38 +00:00
|
|
|
{
|
2022-01-31 12:34:40 +00:00
|
|
|
jh->addStringHandler(
|
2023-05-21 17:35:09 +00:00
|
|
|
[fn, choices, required, this](std::string const& path, std::string const& parameter) {
|
2022-01-29 17:29:38 +00:00
|
|
|
char const* p = parameter.c_str();
|
|
|
|
bool matches = false;
|
2022-04-02 21:14:10 +00:00
|
|
|
if ((!required) && (parameter.empty())) {
|
2022-01-31 23:15:10 +00:00
|
|
|
matches = true;
|
|
|
|
}
|
2022-04-02 21:14:10 +00:00
|
|
|
if (!matches) {
|
|
|
|
for (char const** i = choices; *i; ++i) {
|
|
|
|
if (strcmp(*i, p) == 0) {
|
2022-01-31 23:15:10 +00:00
|
|
|
QTC::TC("qpdf", "QPDFJob json choice match");
|
|
|
|
matches = true;
|
|
|
|
break;
|
|
|
|
}
|
2022-01-29 17:29:38 +00:00
|
|
|
}
|
|
|
|
}
|
2022-04-02 21:14:10 +00:00
|
|
|
if (!matches) {
|
2022-01-31 20:56:05 +00:00
|
|
|
QTC::TC("qpdf", "QPDFJob json choice mismatch");
|
2022-01-29 17:29:38 +00:00
|
|
|
std::ostringstream msg;
|
|
|
|
msg << path + ": unexpected value; expected one of ";
|
|
|
|
bool first = true;
|
2022-04-02 21:14:10 +00:00
|
|
|
for (char const** i = choices; *i; ++i) {
|
|
|
|
if (first) {
|
2022-01-29 17:29:38 +00:00
|
|
|
first = false;
|
2022-04-02 21:14:10 +00:00
|
|
|
} else {
|
2022-01-29 17:29:38 +00:00
|
|
|
msg << ", ";
|
|
|
|
}
|
|
|
|
msg << *i;
|
|
|
|
}
|
|
|
|
usage(msg.str());
|
|
|
|
}
|
|
|
|
fn(parameter.c_str());
|
2022-01-29 13:54:08 +00:00
|
|
|
});
|
2022-01-29 17:29:38 +00:00
|
|
|
}
|
|
|
|
|
2022-01-29 23:26:11 +00:00
|
|
|
void
|
2022-01-31 12:34:40 +00:00
|
|
|
Handlers::pushKey(std::string const& key)
|
2022-01-29 23:26:11 +00:00
|
|
|
{
|
2022-01-31 12:34:40 +00:00
|
|
|
auto new_jh = std::make_shared<JSONHandler>();
|
|
|
|
this->jh->addDictKeyHandler(key, new_jh);
|
|
|
|
this->json_handlers.push_back(new_jh);
|
|
|
|
this->jh = new_jh.get();
|
2022-01-29 23:26:11 +00:00
|
|
|
}
|
|
|
|
|
2022-01-29 17:29:38 +00:00
|
|
|
void
|
2022-01-31 12:34:40 +00:00
|
|
|
Handlers::beginDict(json_handler_t start_fn, bare_handler_t end_fn)
|
2022-01-29 17:29:38 +00:00
|
|
|
{
|
2022-01-31 12:34:40 +00:00
|
|
|
jh->addDictHandlers(
|
2022-04-02 21:14:10 +00:00
|
|
|
[start_fn](std::string const&, JSON j) { start_fn(j); },
|
|
|
|
[end_fn](std::string const&) { end_fn(); });
|
2022-01-29 17:29:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-01-31 12:34:40 +00:00
|
|
|
Handlers::beginArray(json_handler_t start_fn, bare_handler_t end_fn)
|
2022-01-30 18:56:05 +00:00
|
|
|
{
|
|
|
|
auto item_jh = std::make_shared<JSONHandler>();
|
2022-01-31 12:34:40 +00:00
|
|
|
jh->addArrayHandlers(
|
2022-04-02 21:14:10 +00:00
|
|
|
[start_fn](std::string const&, JSON j) { start_fn(j); },
|
|
|
|
[end_fn](std::string const&) { end_fn(); },
|
2022-01-30 18:56:05 +00:00
|
|
|
item_jh);
|
|
|
|
this->json_handlers.push_back(item_jh);
|
|
|
|
this->jh = item_jh.get();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-01-31 12:34:40 +00:00
|
|
|
Handlers::ignoreItem()
|
|
|
|
{
|
2022-04-02 21:14:10 +00:00
|
|
|
jh->addAnyHandler([](std::string const&, JSON) {});
|
2022-01-31 12:34:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Handlers::popHandler()
|
2022-01-29 17:29:38 +00:00
|
|
|
{
|
|
|
|
this->json_handlers.pop_back();
|
|
|
|
this->jh = this->json_handlers.back().get();
|
2022-01-29 13:54:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Handlers::handle(JSON& j)
|
|
|
|
{
|
2022-01-29 17:29:38 +00:00
|
|
|
this->json_handlers.back()->handle(".", j);
|
2022-01-29 13:54:08 +00:00
|
|
|
}
|
|
|
|
|
2022-01-29 23:26:11 +00:00
|
|
|
void
|
2022-01-31 18:07:19 +00:00
|
|
|
Handlers::setupInputFile()
|
2022-01-29 23:26:11 +00:00
|
|
|
{
|
2022-04-02 21:14:10 +00:00
|
|
|
addParameter([this](char const* p) { c_main->inputFile(p); });
|
2022-01-29 23:26:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-01-31 23:04:14 +00:00
|
|
|
Handlers::setupPassword()
|
2022-01-29 23:26:11 +00:00
|
|
|
{
|
2022-04-02 21:14:10 +00:00
|
|
|
addParameter([this](char const* p) { c_main->password(p); });
|
2022-01-29 23:26:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-01-31 23:04:14 +00:00
|
|
|
Handlers::setupEmpty()
|
2022-01-29 23:26:11 +00:00
|
|
|
{
|
2022-04-02 21:14:10 +00:00
|
|
|
addBare([this]() { c_main->emptyInput(); });
|
2022-01-29 23:26:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-01-31 18:07:19 +00:00
|
|
|
Handlers::setupOutputFile()
|
2022-01-29 23:26:11 +00:00
|
|
|
{
|
2022-04-02 21:14:10 +00:00
|
|
|
addParameter([this](char const* p) { c_main->outputFile(p); });
|
2022-01-29 23:26:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-01-31 23:04:14 +00:00
|
|
|
Handlers::setupReplaceInput()
|
2022-01-29 23:26:11 +00:00
|
|
|
{
|
2022-04-02 21:14:10 +00:00
|
|
|
addBare([this]() { c_main->replaceInput(); });
|
2022-01-29 23:26:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-01-31 23:04:14 +00:00
|
|
|
Handlers::beginEncrypt(JSON j)
|
2022-01-29 23:26:11 +00:00
|
|
|
{
|
2023-05-27 17:19:52 +00:00
|
|
|
// This method is only called if the overall JSON structure matches the schema, so we already
|
|
|
|
// know that keys that are present have the right types.
|
2022-01-30 18:39:17 +00:00
|
|
|
int key_len = 0;
|
|
|
|
std::string user_password;
|
|
|
|
std::string owner_password;
|
|
|
|
bool user_password_seen = false;
|
|
|
|
bool owner_password_seen = false;
|
2022-04-02 21:14:10 +00:00
|
|
|
j.forEachDictItem([&](std::string const& key, JSON value) {
|
|
|
|
if ((key == "40bit") || (key == "128bit") || (key == "256bit")) {
|
|
|
|
if (key_len != 0) {
|
2022-01-31 20:56:05 +00:00
|
|
|
QTC::TC("qpdf", "QPDFJob json encrypt duplicate key length");
|
2022-01-30 18:39:17 +00:00
|
|
|
usage("exactly one of 40bit, 128bit, or 256bit must be given");
|
|
|
|
}
|
|
|
|
key_len = QUtil::string_to_int(key.c_str());
|
2022-04-02 21:14:10 +00:00
|
|
|
} else if (key == "userPassword") {
|
2022-01-30 18:39:17 +00:00
|
|
|
user_password_seen = value.getString(user_password);
|
2022-04-02 21:14:10 +00:00
|
|
|
} else if (key == "ownerPassword") {
|
2022-01-30 18:39:17 +00:00
|
|
|
owner_password_seen = value.getString(owner_password);
|
|
|
|
}
|
|
|
|
});
|
2022-04-02 21:14:10 +00:00
|
|
|
if (key_len == 0) {
|
2022-01-31 20:56:05 +00:00
|
|
|
QTC::TC("qpdf", "QPDFJob json encrypt no key length");
|
2023-05-27 17:19:52 +00:00
|
|
|
usage("exactly one of 40bit, 128bit, or 256bit must be given; an empty dictionary may be "
|
|
|
|
"supplied for one of them to set the key length without imposing any restrictions");
|
2022-01-30 18:39:17 +00:00
|
|
|
}
|
2022-04-02 21:14:10 +00:00
|
|
|
if (!(user_password_seen && owner_password_seen)) {
|
2022-01-31 20:56:05 +00:00
|
|
|
QTC::TC("qpdf", "QPDFJob json encrypt missing password");
|
2023-05-27 17:19:52 +00:00
|
|
|
usage("the user and owner password are both required; use the empty string for the user "
|
|
|
|
"password if you don't want a password");
|
2022-01-30 18:39:17 +00:00
|
|
|
}
|
|
|
|
this->c_enc = c_main->encrypt(key_len, user_password, owner_password);
|
2022-01-29 23:26:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-01-31 23:04:14 +00:00
|
|
|
Handlers::endEncrypt()
|
2022-01-29 23:26:11 +00:00
|
|
|
{
|
2022-01-30 18:39:17 +00:00
|
|
|
this->c_enc->endEncrypt();
|
|
|
|
this->c_enc = nullptr;
|
2022-01-29 23:26:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-01-31 23:04:14 +00:00
|
|
|
Handlers::setupEncryptUserPassword()
|
2022-01-29 23:26:11 +00:00
|
|
|
{
|
2022-01-31 23:04:14 +00:00
|
|
|
// handled in beginEncrypt
|
2022-01-31 12:34:40 +00:00
|
|
|
ignoreItem();
|
2022-01-29 23:26:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-01-31 23:04:14 +00:00
|
|
|
Handlers::setupEncryptOwnerPassword()
|
2022-01-29 23:26:11 +00:00
|
|
|
{
|
2022-01-31 23:04:14 +00:00
|
|
|
// handled in beginEncrypt
|
2022-01-31 12:34:40 +00:00
|
|
|
ignoreItem();
|
2022-01-29 23:26:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-01-31 23:04:14 +00:00
|
|
|
Handlers::beginEncrypt40bit(JSON)
|
2022-01-29 23:26:11 +00:00
|
|
|
{
|
2022-01-30 13:04:45 +00:00
|
|
|
// nothing needed
|
2022-01-29 23:26:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-01-31 23:04:14 +00:00
|
|
|
Handlers::endEncrypt40bit()
|
2022-01-29 23:26:11 +00:00
|
|
|
{
|
2022-01-30 13:04:45 +00:00
|
|
|
// nothing needed
|
2022-01-29 23:26:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-01-31 23:04:14 +00:00
|
|
|
Handlers::beginEncrypt128bit(JSON)
|
2022-01-29 23:26:11 +00:00
|
|
|
{
|
|
|
|
// nothing needed
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-01-31 23:04:14 +00:00
|
|
|
Handlers::endEncrypt128bit()
|
2022-01-29 23:26:11 +00:00
|
|
|
{
|
|
|
|
// nothing needed
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-01-31 23:04:14 +00:00
|
|
|
Handlers::beginEncrypt256bit(JSON)
|
2022-01-29 23:26:11 +00:00
|
|
|
{
|
|
|
|
// nothing needed
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-01-31 23:04:14 +00:00
|
|
|
Handlers::endEncrypt256bit()
|
2022-01-29 23:26:11 +00:00
|
|
|
{
|
|
|
|
// nothing needed
|
|
|
|
}
|
|
|
|
|
2022-01-31 12:34:40 +00:00
|
|
|
void
|
2022-01-31 23:04:14 +00:00
|
|
|
Handlers::beginJsonKeyArray(JSON)
|
2022-01-31 12:34:40 +00:00
|
|
|
{
|
|
|
|
// nothing needed
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-01-31 23:04:14 +00:00
|
|
|
Handlers::endJsonKeyArray()
|
2022-01-31 12:34:40 +00:00
|
|
|
{
|
|
|
|
// nothing needed
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-01-31 23:04:14 +00:00
|
|
|
Handlers::beginJsonObjectArray(JSON)
|
2022-01-31 12:34:40 +00:00
|
|
|
{
|
|
|
|
// nothing needed
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-01-31 23:04:14 +00:00
|
|
|
Handlers::endJsonObjectArray()
|
2022-01-31 12:34:40 +00:00
|
|
|
{
|
|
|
|
// nothing needed
|
|
|
|
}
|
|
|
|
|
2022-01-30 18:56:05 +00:00
|
|
|
void
|
2022-01-31 23:04:14 +00:00
|
|
|
Handlers::beginAddAttachmentArray(JSON)
|
2022-01-30 18:56:05 +00:00
|
|
|
{
|
2022-01-30 19:06:57 +00:00
|
|
|
// nothing needed
|
2022-01-30 18:56:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-01-31 23:04:14 +00:00
|
|
|
Handlers::endAddAttachmentArray()
|
2022-01-30 18:56:05 +00:00
|
|
|
{
|
2022-01-30 19:06:57 +00:00
|
|
|
// nothing needed
|
2022-01-30 18:56:05 +00:00
|
|
|
}
|
|
|
|
|
2022-01-29 23:26:11 +00:00
|
|
|
void
|
2022-01-31 23:04:14 +00:00
|
|
|
Handlers::beginAddAttachment(JSON)
|
2022-01-29 23:26:11 +00:00
|
|
|
{
|
2022-01-30 18:39:17 +00:00
|
|
|
this->c_att = c_main->addAttachment();
|
2022-01-29 23:26:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-01-31 23:04:14 +00:00
|
|
|
Handlers::endAddAttachment()
|
2022-01-29 23:26:11 +00:00
|
|
|
{
|
2022-01-30 18:39:17 +00:00
|
|
|
this->c_att->endAddAttachment();
|
|
|
|
this->c_att = nullptr;
|
2022-01-29 23:26:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-01-31 23:04:14 +00:00
|
|
|
Handlers::setupAddAttachmentFile()
|
2022-01-29 23:26:11 +00:00
|
|
|
{
|
2022-04-02 21:14:10 +00:00
|
|
|
addParameter([this](char const* p) { c_att->file(p); });
|
2022-01-29 23:26:11 +00:00
|
|
|
}
|
|
|
|
|
2022-01-30 18:56:05 +00:00
|
|
|
void
|
2022-04-24 16:47:24 +00:00
|
|
|
Handlers::beginRemoveAttachmentArray(JSON)
|
|
|
|
{
|
|
|
|
// nothing needed
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Handlers::endRemoveAttachmentArray()
|
|
|
|
{
|
|
|
|
// nothing needed
|
|
|
|
}
|
|
|
|
void
|
2022-01-31 23:04:14 +00:00
|
|
|
Handlers::beginCopyAttachmentsFromArray(JSON)
|
2022-01-30 18:56:05 +00:00
|
|
|
{
|
2022-01-30 19:06:57 +00:00
|
|
|
// nothing needed
|
2022-01-30 18:56:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-01-31 23:04:14 +00:00
|
|
|
Handlers::endCopyAttachmentsFromArray()
|
2022-01-30 18:56:05 +00:00
|
|
|
{
|
2022-01-30 19:06:57 +00:00
|
|
|
// nothing needed
|
2022-01-30 18:56:05 +00:00
|
|
|
}
|
|
|
|
|
2022-01-29 23:26:11 +00:00
|
|
|
void
|
2022-01-31 23:04:14 +00:00
|
|
|
Handlers::beginCopyAttachmentsFrom(JSON)
|
2022-01-29 23:26:11 +00:00
|
|
|
{
|
2022-01-30 18:39:17 +00:00
|
|
|
this->c_copy_att = c_main->copyAttachmentsFrom();
|
2022-01-29 23:26:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-01-31 23:04:14 +00:00
|
|
|
Handlers::endCopyAttachmentsFrom()
|
2022-01-29 23:26:11 +00:00
|
|
|
{
|
2022-01-30 18:39:17 +00:00
|
|
|
this->c_copy_att->endCopyAttachmentsFrom();
|
|
|
|
this->c_copy_att = nullptr;
|
2022-01-29 23:26:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-01-31 23:04:14 +00:00
|
|
|
Handlers::setupCopyAttachmentsFromFile()
|
2022-01-29 23:26:11 +00:00
|
|
|
{
|
2022-04-02 21:14:10 +00:00
|
|
|
addParameter([this](char const* p) { c_copy_att->file(p); });
|
2022-01-29 23:26:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-01-31 23:04:14 +00:00
|
|
|
Handlers::setupCopyAttachmentsFromPassword()
|
2022-01-29 23:26:11 +00:00
|
|
|
{
|
2022-04-02 21:14:10 +00:00
|
|
|
addParameter([this](char const* p) { c_copy_att->password(p); });
|
2022-01-29 23:26:11 +00:00
|
|
|
}
|
|
|
|
|
2022-01-30 18:56:05 +00:00
|
|
|
void
|
2022-01-31 23:04:14 +00:00
|
|
|
Handlers::beginPagesArray(JSON)
|
2022-01-30 18:56:05 +00:00
|
|
|
{
|
2022-01-30 19:06:57 +00:00
|
|
|
this->c_pages = c_main->pages();
|
2022-01-30 18:56:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-01-31 23:04:14 +00:00
|
|
|
Handlers::endPagesArray()
|
2022-01-30 18:56:05 +00:00
|
|
|
{
|
2022-01-30 19:06:57 +00:00
|
|
|
c_pages->endPages();
|
|
|
|
c_pages = nullptr;
|
2022-01-30 18:56:05 +00:00
|
|
|
}
|
|
|
|
|
2022-01-29 23:26:11 +00:00
|
|
|
void
|
2022-01-31 23:04:14 +00:00
|
|
|
Handlers::beginPages(JSON j)
|
2022-01-29 23:26:11 +00:00
|
|
|
{
|
2022-01-30 19:06:57 +00:00
|
|
|
std::string file;
|
|
|
|
std::string range("1-z");
|
|
|
|
std::string password;
|
|
|
|
bool file_seen = false;
|
|
|
|
bool password_seen = false;
|
2022-04-02 21:14:10 +00:00
|
|
|
j.forEachDictItem([&](std::string const& key, JSON value) {
|
|
|
|
if (key == "file") {
|
2022-01-30 19:06:57 +00:00
|
|
|
file_seen = value.getString(file);
|
2022-04-02 21:14:10 +00:00
|
|
|
} else if (key == "range") {
|
2022-01-30 19:06:57 +00:00
|
|
|
value.getString(range);
|
2022-04-02 21:14:10 +00:00
|
|
|
} else if (key == "password") {
|
2022-01-30 19:06:57 +00:00
|
|
|
password_seen = value.getString(password);
|
|
|
|
}
|
|
|
|
});
|
2022-04-02 21:14:10 +00:00
|
|
|
if (!file_seen) {
|
2022-01-31 20:56:05 +00:00
|
|
|
QTC::TC("qpdf", "QPDFJob json pages no file");
|
2022-01-30 19:06:57 +00:00
|
|
|
usage("file is required in page specification");
|
|
|
|
}
|
2023-05-21 17:35:09 +00:00
|
|
|
this->c_pages->pageSpec(file, range, password_seen ? password.c_str() : nullptr);
|
2022-01-29 23:26:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-01-31 23:04:14 +00:00
|
|
|
Handlers::endPages()
|
2022-01-29 23:26:11 +00:00
|
|
|
{
|
2022-01-30 19:06:57 +00:00
|
|
|
// nothing needed
|
2022-01-29 23:26:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-01-31 23:04:14 +00:00
|
|
|
Handlers::setupPagesFile()
|
2022-01-29 23:26:11 +00:00
|
|
|
{
|
2022-01-31 23:04:14 +00:00
|
|
|
// handled in beginPages
|
2022-01-31 12:34:40 +00:00
|
|
|
ignoreItem();
|
2022-01-29 23:26:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-01-31 23:04:14 +00:00
|
|
|
Handlers::setupPagesPassword()
|
2022-01-29 23:26:11 +00:00
|
|
|
{
|
2022-01-31 23:04:14 +00:00
|
|
|
// handled in beginPages
|
2022-01-31 12:34:40 +00:00
|
|
|
ignoreItem();
|
2022-01-29 23:26:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-01-31 23:04:14 +00:00
|
|
|
Handlers::setupPagesRange()
|
2022-01-29 23:26:11 +00:00
|
|
|
{
|
2022-01-31 23:04:14 +00:00
|
|
|
// handled in beginPages
|
2022-01-31 12:34:40 +00:00
|
|
|
ignoreItem();
|
2022-01-29 23:26:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-01-31 23:04:14 +00:00
|
|
|
Handlers::beginOverlay(JSON)
|
2022-01-29 23:26:11 +00:00
|
|
|
{
|
2022-01-30 18:39:17 +00:00
|
|
|
this->c_uo = c_main->overlay();
|
2022-01-29 23:26:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-01-31 23:04:14 +00:00
|
|
|
Handlers::endOverlay()
|
2022-01-29 23:26:11 +00:00
|
|
|
{
|
2022-01-30 18:39:17 +00:00
|
|
|
c_uo->endUnderlayOverlay();
|
|
|
|
c_uo = nullptr;
|
2022-01-29 23:26:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-01-31 23:04:14 +00:00
|
|
|
Handlers::setupOverlayFile()
|
2022-01-29 23:26:11 +00:00
|
|
|
{
|
2022-04-02 21:14:10 +00:00
|
|
|
addParameter([this](char const* p) { c_uo->file(p); });
|
2022-01-29 23:26:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-01-31 23:04:14 +00:00
|
|
|
Handlers::setupOverlayPassword()
|
2022-01-29 23:26:11 +00:00
|
|
|
{
|
2022-04-02 21:14:10 +00:00
|
|
|
addParameter([this](char const* p) { c_uo->password(p); });
|
2022-01-29 23:26:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-01-31 23:04:14 +00:00
|
|
|
Handlers::beginUnderlay(JSON)
|
2022-01-29 23:26:11 +00:00
|
|
|
{
|
2022-01-30 18:39:17 +00:00
|
|
|
this->c_uo = c_main->underlay();
|
2022-01-29 23:26:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-01-31 23:04:14 +00:00
|
|
|
Handlers::endUnderlay()
|
2022-01-29 23:26:11 +00:00
|
|
|
{
|
2022-01-30 18:39:17 +00:00
|
|
|
c_uo->endUnderlayOverlay();
|
|
|
|
c_uo = nullptr;
|
2022-01-29 23:26:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-01-31 23:04:14 +00:00
|
|
|
Handlers::setupUnderlayFile()
|
2022-01-29 23:26:11 +00:00
|
|
|
{
|
2022-04-02 21:14:10 +00:00
|
|
|
addParameter([this](char const* p) { c_uo->file(p); });
|
2022-01-29 23:26:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-01-31 23:04:14 +00:00
|
|
|
Handlers::setupUnderlayPassword()
|
2022-01-29 23:26:11 +00:00
|
|
|
{
|
2022-04-02 21:14:10 +00:00
|
|
|
addParameter([this](char const* p) { c_uo->password(p); });
|
2022-01-29 23:26:11 +00:00
|
|
|
}
|
|
|
|
|
2022-01-26 21:48:18 +00:00
|
|
|
void
|
2022-01-30 19:39:38 +00:00
|
|
|
QPDFJob::initializeFromJson(std::string const& json, bool partial)
|
2022-01-26 21:48:18 +00:00
|
|
|
{
|
|
|
|
std::list<std::string> errors;
|
|
|
|
JSON j = JSON::parse(json);
|
2022-04-02 21:14:10 +00:00
|
|
|
if (!j.checkSchema(JOB_SCHEMA, JSON::f_optional, errors)) {
|
2022-01-26 21:48:18 +00:00
|
|
|
std::ostringstream msg;
|
2023-05-21 13:42:34 +00:00
|
|
|
msg << m->message_prefix << ": job json has errors:";
|
2022-04-30 13:43:07 +00:00
|
|
|
for (auto const& error: errors) {
|
2022-01-26 21:48:18 +00:00
|
|
|
msg << std::endl << " " << error;
|
|
|
|
}
|
|
|
|
throw std::runtime_error(msg.str());
|
|
|
|
}
|
|
|
|
|
2022-01-30 19:39:38 +00:00
|
|
|
Handlers(partial, config()).handle(j);
|
2022-01-26 21:48:18 +00:00
|
|
|
}
|