aboutsummaryrefslogtreecommitdiffstats
path: root/libqpdf
diff options
context:
space:
mode:
Diffstat (limited to 'libqpdf')
-rw-r--r--libqpdf/QPDFJob.cc48
-rw-r--r--libqpdf/QPDFJob_config.cc6
-rw-r--r--libqpdf/QPDFWriter.cc58
-rw-r--r--libqpdf/QPDF_optimization.cc18
-rw-r--r--libqpdf/QUtil.cc31
5 files changed, 76 insertions, 85 deletions
diff --git a/libqpdf/QPDFJob.cc b/libqpdf/QPDFJob.cc
index 87ec32b9..b57a791b 100644
--- a/libqpdf/QPDFJob.cc
+++ b/libqpdf/QPDFJob.cc
@@ -447,11 +447,11 @@ QPDFJob::parseNumrange(char const* range, int max)
return std::vector<int>();
}
-void
-QPDFJob::run()
+std::unique_ptr<QPDF>
+QPDFJob::createQPDF()
{
checkConfiguration();
- std::shared_ptr<QPDF> pdf_sp;
+ std::unique_ptr<QPDF> pdf_sp;
try {
processFile(pdf_sp, m->infilename.get(), m->password.get(), true, true);
} catch (QPDFExc& e) {
@@ -461,12 +461,12 @@ QPDFJob::run()
if (m->check_is_encrypted || m->check_requires_password) {
this->m->encryption_status =
qpdf_es_encrypted | qpdf_es_password_incorrect;
- return;
+ return nullptr;
}
if (m->show_encryption && pdf_sp) {
this->m->log->info("Incorrect password supplied\n");
showEncryption(*pdf_sp);
- return;
+ return nullptr;
}
}
throw e;
@@ -477,7 +477,7 @@ QPDFJob::run()
}
if (m->check_is_encrypted || m->check_requires_password) {
- return;
+ return nullptr;
}
// If we are updating from JSON, this has to be done first before
@@ -486,7 +486,7 @@ QPDFJob::run()
pdf.updateFromJSON(this->m->update_from_json);
}
- std::vector<std::shared_ptr<QPDF>> page_heap;
+ std::vector<std::unique_ptr<QPDF>> page_heap;
if (!m->page_specs.empty()) {
handlePageSpecs(pdf, page_heap);
}
@@ -495,7 +495,12 @@ QPDFJob::run()
}
handleUnderOverlay(pdf);
handleTransformations(pdf);
+ return pdf_sp;
+}
+void
+QPDFJob::writeQPDF(QPDF& pdf)
+{
if (!createsOutput()) {
doInspection(pdf);
} else if (m->split_pages) {
@@ -527,6 +532,15 @@ QPDFJob::run()
}
}
+void
+QPDFJob::run()
+{
+ auto pdf = createQPDF();
+ if (pdf) {
+ writeQPDF(*pdf);
+ }
+}
+
bool
QPDFJob::hasWarnings() const
{
@@ -1868,14 +1882,14 @@ QPDFJob::doInspection(QPDF& pdf)
void
QPDFJob::doProcessOnce(
- std::shared_ptr<QPDF>& pdf,
+ std::unique_ptr<QPDF>& pdf,
std::function<void(QPDF*, char const*)> fn,
char const* password,
bool empty,
bool used_for_input,
bool main_input)
{
- pdf = QPDF::create();
+ pdf = std::make_unique<QPDF>();
setQPDFOptions(*pdf);
if (empty) {
pdf->emptyPDF();
@@ -1892,7 +1906,7 @@ QPDFJob::doProcessOnce(
void
QPDFJob::doProcess(
- std::shared_ptr<QPDF>& pdf,
+ std::unique_ptr<QPDF>& pdf,
std::function<void(QPDF*, char const*)> fn,
char const* password,
bool empty,
@@ -1976,7 +1990,7 @@ QPDFJob::doProcess(
void
QPDFJob::processFile(
- std::shared_ptr<QPDF>& pdf,
+ std::unique_ptr<QPDF>& pdf,
char const* filename,
char const* password,
bool used_for_input,
@@ -1996,7 +2010,7 @@ QPDFJob::processFile(
void
QPDFJob::processInputSource(
- std::shared_ptr<QPDF>& pdf,
+ std::unique_ptr<QPDF>& pdf,
std::shared_ptr<InputSource> is,
char const* password,
bool used_for_input)
@@ -2278,7 +2292,7 @@ QPDFJob::copyAttachments(QPDF& pdf)
v << prefix << ": copying attachments from " << to_copy.path
<< "\n";
});
- std::shared_ptr<QPDF> other;
+ std::unique_ptr<QPDF> other;
processFile(
other,
to_copy.path.c_str(),
@@ -2540,7 +2554,7 @@ added_page(QPDF& pdf, QPDFPageObjectHelper page)
void
QPDFJob::handlePageSpecs(
- QPDF& pdf, std::vector<std::shared_ptr<QPDF>>& page_heap)
+ QPDF& pdf, std::vector<std::unique_ptr<QPDF>>& page_heap)
{
// Parse all page specifications and translate them into lists of
// actual pages.
@@ -2612,10 +2626,10 @@ QPDFJob::handlePageSpecs(
new FileInputSource(page_spec.filename.c_str());
is = std::shared_ptr<InputSource>(fis);
}
- std::shared_ptr<QPDF> qpdf_sp;
+ std::unique_ptr<QPDF> qpdf_sp;
processInputSource(qpdf_sp, is, password, true);
- page_heap.push_back(qpdf_sp);
page_spec_qpdfs[page_spec.filename] = qpdf_sp.get();
+ page_heap.push_back(std::move(qpdf_sp));
if (cis) {
cis->stayOpen(false);
page_spec_cfis[page_spec.filename] = cis;
@@ -3116,7 +3130,7 @@ QPDFJob::setWriterOptions(QPDF& pdf, QPDFWriter& w)
w.setSuppressOriginalObjectIDs(true);
}
if (m->copy_encryption) {
- std::shared_ptr<QPDF> encryption_pdf;
+ std::unique_ptr<QPDF> encryption_pdf;
processFile(
encryption_pdf,
m->encryption_file.c_str(),
diff --git a/libqpdf/QPDFJob_config.cc b/libqpdf/QPDFJob_config.cc
index 3a6bcdf4..a7f22443 100644
--- a/libqpdf/QPDFJob_config.cc
+++ b/libqpdf/QPDFJob_config.cc
@@ -760,11 +760,9 @@ QPDFJob::Config::showObject(std::string const& parameter)
QPDFJob::Config*
QPDFJob::Config::jobJsonFile(std::string const& parameter)
{
- std::shared_ptr<char> file_buf;
- size_t size;
- QUtil::read_file_into_memory(parameter.c_str(), file_buf, size);
try {
- o.initializeFromJson(std::string(file_buf.get(), size), true);
+ o.initializeFromJson(
+ QUtil::read_file_into_string(parameter.c_str()), true);
} catch (std::exception& e) {
throw std::runtime_error(
"error with job-json file " + std::string(parameter) + ": " +
diff --git a/libqpdf/QPDFWriter.cc b/libqpdf/QPDFWriter.cc
index 907cc105..8287412c 100644
--- a/libqpdf/QPDFWriter.cc
+++ b/libqpdf/QPDFWriter.cc
@@ -52,50 +52,9 @@ QPDFWriter::FunctionProgressReporter::reportProgress(int progress)
QPDFWriter::Members::Members(QPDF& pdf) :
pdf(pdf),
- filename("unspecified"),
- file(nullptr),
- close_file(false),
- buffer_pipeline(nullptr),
- output_buffer(nullptr),
- normalize_content_set(false),
- normalize_content(false),
- compress_streams(true),
- compress_streams_set(false),
- stream_decode_level(qpdf_dl_none),
- stream_decode_level_set(false),
- recompress_flate(false),
- qdf_mode(false),
- preserve_unreferenced_objects(false),
- newline_before_endstream(false),
- static_id(false),
- suppress_original_object_ids(false),
- direct_stream_lengths(true),
- encrypted(false),
- preserve_encryption(true),
- linearized(false),
- pclm(false),
- object_stream_mode(qpdf_o_preserve),
- encrypt_metadata(true),
- encrypt_use_aes(false),
- encryption_V(0),
- encryption_R(0),
- final_extension_level(0),
- min_extension_level(0),
- forced_extension_level(0),
- encryption_dict_objid(0),
- pipeline(nullptr),
- next_objid(1),
- cur_stream_length_id(0),
- cur_stream_length(0),
- added_newline(false),
- max_ostream_index(0),
- next_stack_id(0),
- deterministic_id(false),
- md5_pipeline(nullptr),
- did_write_setup(false),
- events_expected(0),
- events_seen(0),
- next_progress_report(0)
+ root_og(
+ pdf.getRoot().getObjGen().isIndirect() ? pdf.getRoot().getObjGen()
+ : QPDFObjGen(-1, 0))
{
}
@@ -1534,14 +1493,12 @@ QPDFWriter::unparseObject(
// is direct through the ADBE dictionary, so we can modify in
// place.
- bool is_root = false;
+ const bool is_root = (old_og == m->root_og);
bool have_extensions_other = false;
bool have_extensions_adbe = false;
QPDFObjectHandle extensions;
- if ((old_og.getObj() != 0) &&
- (old_og == this->m->pdf.getRoot().getObjGen())) {
- is_root = true;
+ if (is_root) {
if (object.hasKey("/Extensions") &&
object.getKey("/Extensions").isDictionary()) {
extensions = object.getKey("/Extensions");
@@ -2396,10 +2353,9 @@ QPDFWriter::doWriteSetup()
// 8.0.0 has a bug that prevents it from being able to handle
// encrypted files with compressed document catalogs, so we
// disable them in that case as well.
- QPDFObjGen og = this->m->pdf.getRoot().getObjGen();
- if (this->m->object_to_object_stream.count(og)) {
+ if (m->object_to_object_stream.count(m->root_og)) {
QTC::TC("qpdf", "QPDFWriter uncompressing root");
- this->m->object_to_object_stream.erase(og);
+ this->m->object_to_object_stream.erase(m->root_og);
}
}
diff --git a/libqpdf/QPDF_optimization.cc b/libqpdf/QPDF_optimization.cc
index 1fe0b74f..41204fbd 100644
--- a/libqpdf/QPDF_optimization.cc
+++ b/libqpdf/QPDF_optimization.cc
@@ -285,7 +285,7 @@ QPDF::updateObjectMaps(
std::function<int(QPDFObjectHandle&)> skip_stream_parameters)
{
std::set<QPDFObjGen> visited;
- updateObjectMapsInternal(ou, oh, skip_stream_parameters, visited, true, 0);
+ updateObjectMapsInternal(ou, oh, skip_stream_parameters, visited, true);
}
void
@@ -294,8 +294,7 @@ QPDF::updateObjectMapsInternal(
QPDFObjectHandle oh,
std::function<int(QPDFObjectHandle&)> skip_stream_parameters,
std::set<QPDFObjGen>& visited,
- bool top,
- int depth)
+ bool top)
{
// Traverse the object tree from this point taking care to avoid
// crossing page boundaries.
@@ -324,12 +323,7 @@ QPDF::updateObjectMapsInternal(
int n = oh.getArrayNItems();
for (int i = 0; i < n; ++i) {
updateObjectMapsInternal(
- ou,
- oh.getArrayItem(i),
- skip_stream_parameters,
- visited,
- false,
- 1 + depth);
+ ou, oh.getArrayItem(i), skip_stream_parameters, visited, false);
}
} else if (oh.isDictionary() || oh.isStream()) {
QPDFObjectHandle dict = oh;
@@ -351,8 +345,7 @@ QPDF::updateObjectMapsInternal(
dict.getKey(key),
skip_stream_parameters,
visited,
- false,
- 1 + depth);
+ false);
} else if (is_page_node && (key == "/Parent")) {
// Don't traverse back up the page tree
} else if (
@@ -367,8 +360,7 @@ QPDF::updateObjectMapsInternal(
dict.getKey(key),
skip_stream_parameters,
visited,
- false,
- 1 + depth);
+ false);
}
}
}
diff --git a/libqpdf/QUtil.cc b/libqpdf/QUtil.cc
index 7f23bd03..bae067b6 100644
--- a/libqpdf/QUtil.cc
+++ b/libqpdf/QUtil.cc
@@ -1243,6 +1243,37 @@ QUtil::read_file_into_memory(
}
}
+std::string
+QUtil::read_file_into_string(char const* filename)
+{
+ FILE* f = safe_fopen(filename, "rb");
+ FileCloser fc(f);
+ return read_file_into_string(f, filename);
+}
+
+std::string
+QUtil::read_file_into_string(FILE* f, std::string_view filename)
+{
+ fseek(f, 0, SEEK_END);
+ auto size = QIntC::to_size(QUtil::tell(f));
+ fseek(f, 0, SEEK_SET);
+ std::string result(size, '\0');
+ if (auto read = fread(result.data(), 1, size, f); read != size) {
+ if (ferror(f)) {
+ throw std::runtime_error(
+ std::string("failure reading file ") + std::string(filename) +
+ " into memory: read " + uint_to_string(read) + "; wanted " +
+ uint_to_string(size));
+ } else {
+ throw std::runtime_error(
+ std::string("premature eof reading file ") +
+ std::string(filename) + " into memory: read " +
+ uint_to_string(read) + "; wanted " + uint_to_string(size));
+ }
+ }
+ return result;
+}
+
static bool
read_char_from_FILE(char& ch, FILE* f)
{