diff options
Diffstat (limited to 'libqpdf')
-rw-r--r-- | libqpdf/QPDFJob.cc | 48 | ||||
-rw-r--r-- | libqpdf/QPDFJob_config.cc | 6 | ||||
-rw-r--r-- | libqpdf/QPDFWriter.cc | 58 | ||||
-rw-r--r-- | libqpdf/QPDF_optimization.cc | 18 | ||||
-rw-r--r-- | libqpdf/QUtil.cc | 31 |
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) { |