diff options
128 files changed, 740 insertions, 810 deletions
diff --git a/.clang-format b/.clang-format index 4f806d16..debe191b 100644 --- a/.clang-format +++ b/.clang-format @@ -1,5 +1,6 @@ # -*- yaml -*- -# This configuration works with clang-format-15. +# This configuration requires at least clang-format 15. +# See ./format-code for comments about the minimum version. # See https://clang.llvm.org/docs/ClangFormatStyleOptions.html --- Language: Cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index d2ec8ffd..ac0c0435 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -104,6 +104,8 @@ option(INSTALL_PKGCONFIG "Install pkgconfig file" ON) option(INSTALL_CMAKE_PACKAGE "Install cmake package files" ON) option(INSTALL_EXAMPLES "Install example files" ON) +option(FUTURE "Include ABI-breaking changes CONSIDERED for the next major release" OFF) + # *** END OPTIONS *** if(NOT (BUILD_STATIC_LIBS OR BUILD_SHARED_LIBS)) @@ -121,6 +123,10 @@ else() set(ENABLE_QTC_ARG --disable-tc) endif() +if(FUTURE) + add_compile_definitions(QPDF_FUTURE=1) +endif() + enable_testing() set(RUN_QTEST perl ${qpdf_SOURCE_DIR}/run-qtest ${ENABLE_QTC_ARG}) @@ -347,6 +353,7 @@ message(STATUS " build static libraries: ${BUILD_STATIC_LIBS}") message(STATUS " build manual: ${BUILD_DOC}") message(STATUS " compiler warnings are errors: ${WERROR}") message(STATUS " QTC test coverage: ${ENABLE_QTC}") +message(STATUS " include future changes: ${FUTURE}") message(STATUS " system: ${CPACK_SYSTEM_NAME}") message(STATUS "") message(STATUS "*** Options Summary ***") diff --git a/README-maintainer b/README-maintainer.md index 0968e645..2809a7e1 100644 --- a/README-maintainer +++ b/README-maintainer.md @@ -1,30 +1,59 @@ -ROUTINE DEVELOPMENT +# Maintainer Notes + +## Contents + +* [ROUTINE DEVELOPMENT](#routine-development) +* [VERSIONS](#versions) +* [CHECKING DOCS ON readthedocs](#checking-docs-on-readthedocs) +* [GOOGLE OSS-FUZZ](#google-oss-fuzz) +* [CODING RULES](#coding-rules) +* [HOW TO ADD A COMMAND-LINE ARGUMENT](#how-to-add-a-command-line-argument) +* [RELEASE PREPARATION](#release-preparation) +* [CREATING A RELEASE](#creating-a-release) +* [RUNNING pikepdf's TEST SUITE](#running-pikepdfs-test-suite) +* [OTHER NOTES](#other-notes) +* [DEPRECATION](#deprecation) +* [LOCAL WINDOWS TESTING PROCEDURE](#local-windows-testing-procedure) +* [DOCS ON readthedocs.org](#docs-on-readthedocsorg) +* [CMAKE notes](#cmake-notes) +* [ABI checks](#abi-checks) +* [CODE FORMATTING](#code-formatting) + + +## ROUTINE DEVELOPMENT **Remember to check pull requests as well as issues in github.** Default: +``` cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=1 \ -DMAINTAINER_MODE=1 -DBUILD_STATIC_LIBS=0 \ -DCMAKE_BUILD_TYPE=RelWithDebInfo .. +``` Debugging: +``` cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=1 \ -DMAINTAINER_MODE=1 -DBUILD_SHARED_LIBS=0 \ -DCMAKE_BUILD_TYPE=Debug .. +``` Profiling: +``` CFLAGS=-pg LDFLAGS=-pg \ cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=1 \ -DMAINTAINER_MODE=1 -DBUILD_SHARED_LIBS=0 \ -DCMAKE_BUILD_TYPE=Debug .. +``` Then run `gprof gmon.out`. Note that gmon.out is not cumulative. Memory checks: +``` CFLAGS="-fsanitize=address -fsanitize=undefined" \ CXXFLAGS="-fsanitize=address -fsanitize=undefined" \ LDFLAGS="-fsanitize=address -fsanitize=undefined" \ @@ -32,16 +61,18 @@ CFLAGS="-fsanitize=address -fsanitize=undefined" \ cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=1 \ -DMAINTAINER_MODE=1 -DBUILD_SHARED_LIBS=0 \ -DCMAKE_BUILD_TYPE=Debug .. +``` Windows: +``` ../cmake-win {mingw|msvc} maint +``` See ./build-scripts for other ways to run the build for different configurations. - -VERSIONS +## VERSIONS * The version number on the main branch is whatever the version would be if the top of the branch were released. If the most recent @@ -65,15 +96,13 @@ VERSIONS there or the changes can be merged back, depending on the amount of drift. - -CHECKING DOCS ON readthedocs +## CHECKING DOCS ON readthedocs To check docs on readthedocs.io without running all of CI, push to the doc-check branch. Then visit https://qpdf.readthedocs.io/en/doc-check/ Building docs from pull requests is also enabled. - -GOOGLE OSS-FUZZ +## GOOGLE OSS-FUZZ * See ../misc/fuzz (not in repo) for unfixed, downloaded fuzz test cases @@ -90,11 +119,13 @@ GOOGLE OSS-FUZZ Clone the oss-fuzz project. From the root directory of the repository: + ``` python3 infra/helper.py build_image --pull qpdf python3 infra/helper.py build_fuzzers [ --sanitizer memory|undefined|address ] qpdf [path-to-qpdf-source] python3 infra/helper.py check_build qpdf python3 infra/helper.py build_fuzzers --sanitizer coverage qpdf python3 infra/helper.py coverage qpdf + ``` To reproduce a test case, build with the correct sanitizer, then run @@ -120,10 +151,9 @@ GOOGLE OSS-FUZZ * Latest corpus: gs://qpdf-backup.clusterfuzz-external.appspot.com/corpus/libFuzzer/qpdf_fuzzer/latest.zip +## CODING RULES -CODING RULES - -* Code is formatted with clang-format >= 15. See .clang-format and the +* Code is formatted with clang-format-16. See .clang-format and the "Code Formatting" section in manual/contributing.rst for details. See also "CODE FORMATTING" below. @@ -200,19 +230,41 @@ CODING RULES `= default` and provide a non-inline implementation in the source file. Add this comment to the implementation: + ```cpp // Must be explicit and not inline -- see QPDF_DLL_CLASS in // README-maintainer - -* Put private member variables in std::shared_ptr<Members> for all - public classes. Remember to use QPDF_DLL on ~Members(). Exception: - indirection through std::shared_ptr<Members> is expensive, so don't - do it for classes that are copied a lot, like QPDFObjectHandle and - QPDFObject. It may be possible to declare - std::shared_ptr<Members> m_ph; - Member* m; - with m = m_ph.get(), and then indirect through m in - performance-critical settings, though in 2022, std::shared_ptr is - sufficiently performant that this may not be worth it. + ``` + +* Put private member variables in std::unique_ptr<Members> for all + public classes. Forward declare Members in the header file and define + Members in the implementation file. One of the major benefits of + defining Members in the implementation file is that it makes it easier + to use private classes as data members and simplifies the include order. + Remember that Members must be fully defined before the destructor of the + main class. For an example of this pattern see class JSONHandler. + + Exception: indirection through std::unique_ptr<Members> incurs an overhead, + so don't do it for: + * (especially private) classes that are copied a lot, like QPDFObjectHandle + and QPDFObject. + * classes that are a shared pointer to another class, such as QPDFObjectHandle + or JSON. + + For exported classes that do not use the member pattern for performance + reasons it is worth considering adding a std::unique_ptr to an empty Members + class initialized to nullptr to give the flexibility to add data members + without breaking the ABI. + + Note that, as of qpdf 11, many public classes use `std::shared_ptr` + instead. Changing this to `std::unique_ptr` is ABI-breaking. If the + class doesn't allow copying, we can switch it to std::unique_ptr and + let that be the thing that prevents copying. If the intention is to + allow the object to be copied by value and treated as if it were + copied by reference, then `std::shared_ptr<Members>` should be used. + The `JSON` class is an example of this. As a rule, we should avoid + this design pattern. It's better to make things non-copiable and to + require explicit use of shared pointers, so going forward, + `std::unique_ptr` should be preferred. * Traversal of objects is expensive. It's worth adding some complexity to avoid needless traversals of objects. @@ -220,8 +272,7 @@ CODING RULES * Avoid attaching too much metadata to objects and object handles since those have to get copied around a lot. - -HOW TO ADD A COMMAND-LINE ARGUMENT +## HOW TO ADD A COMMAND-LINE ARGUMENT Quick reminder: @@ -278,8 +329,7 @@ When done, the following should happen: * The job JSON file should have a new key in the schema corresponding to the new option - -RELEASE PREPARATION +## RELEASE PREPARATION * Each year, update copyright notices. This will find all relevant places (assuming current copyright is from last year): @@ -389,8 +439,7 @@ env PKG_CONFIG_PATH=/tmp/inst/lib/pkgconfig \ CMAKE_PREFIX_PATH=/tmp/inst \ ./pkg-test/run-all - -CREATING A RELEASE +## CREATING A RELEASE * Push to main. This will create an artifact called distribution which will contain all the distribution files. Download these, @@ -442,7 +491,9 @@ git push qpdf @:stable * Create a github release after pushing the tag. `gcurl` is an alias that includes the auth token. +``` # Create release + GITHUB_TOKEN=$(qdata-show cred github-token) function gcurl() { curl -H "Authorization: token $GITHUB_TOKEN" ${1+"$@"}; } @@ -458,6 +509,7 @@ for i in *; do mime=$(file -b --mime-type $i) gcurl -H "Content-Type: $mime" --data-binary @$i "$upload_url?name=$i" done +``` If needed, go onto github and make any manual updates such as indicating a pre-release, adding release notes, etc. @@ -470,8 +522,10 @@ This is qpdf version x.y.z. (Brief description) For a full list of changes from previous releases, please see the [release notes](https://qpdf.readthedocs.io/en/stable/release-notes.html). See also [README-what-to-download](./README-what-to-download.md) for details about the available source and binary distributions. ``` +``` # Publish release gcurl -XPOST $url -d'{"draft": false}' +``` * Upload files to sourceforge. @@ -486,14 +540,14 @@ rsync -vrlcO ./ jay_berkenbilt,qpdf@frs.sourceforge.net:/home/frs/project/q/qp/q * Email the qpdf-announce list. - -RUNNING pikepdf's TEST SUITE +## RUNNING pikepdf's TEST SUITE We run pikepdf's test suite from CI. These instructions show how to do it manually. Do this in a separate shell. +``` cd ...qpdf-source-tree... export QPDF_SOURCE_TREE=$PWD export QPDF_BUILD_LIBDIR=$QPDF_SOURCE_TREE/build/libqpdf @@ -510,10 +564,12 @@ python3 -m pip install '.[test]' rehash python3 -m pip install . pytest -n auto +``` If there are failures, use git bisect to figure out where the failure was introduced. For example, set up a work area like this: +``` rm -rf /tmp/z mkdir /tmp/z cd /tmp/z @@ -541,12 +597,12 @@ python3 -m pip install . pytest -n auto EOF chmod +x /tmp/check +``` Then in /tmp/z/qpdf, run git bisect. Use /tmp/check at each stage to test whether it's a good or bad commit. - -OTHER NOTES +## OTHER NOTES For local iteration on the AppImage generation, it works to just ./build-scripts/build-appimage and get the resulting AppImage from the @@ -558,9 +614,11 @@ Use -ti -e RUN_SHELL=1 to run a shell instead of the build script. To iterate on the scripts directly in the source tree, you can run +``` docker build -t qpdfbuild appimage docker run --privileged --rm -ti -e SKIP_TESTS=1 -e RUN_SHELL=1 \ -v $PWD/..:/tmp/build ${1+"$@"} qpdfbuild +``` This will put you at a shell prompt inside the container with your current directory set to the top of the source tree and your uid equal @@ -569,12 +627,13 @@ to the owner of the parent directory source tree. Note: this will leave some extra files (like .bash_history) in the parent directory of the source tree. You will want to clean those up. -DEPRECATION +## DEPRECATION This is a reminder of how to use and test deprecation. To temporarily disable deprecation warnings for testing: +```cpp #ifdef _MSC_VER # pragma warning(disable : 4996) #endif @@ -586,13 +645,15 @@ To temporarily disable deprecation warnings for testing: #if (defined(__GNUC__) || defined(__clang__)) # pragma GCC diagnostic pop #endif +``` To declare something as deprecated: +```cpp [[deprecated("explanation")]] +``` - -LOCAL WINDOWS TESTING PROCEDURE +## LOCAL WINDOWS TESTING PROCEDURE This is what I do for routine testing on Windows. @@ -612,8 +673,7 @@ This is what I do for routine testing on Windows. * Test with mingw: `ctest --verbose -C RelWithDebInfo` - -DOCS ON readthedocs.org +## DOCS ON readthedocs.org * Registered for an account at readthedocs.org with my github account * Project page: https://readthedocs.org/projects/qpdf/ @@ -640,8 +700,7 @@ following branching strategy to support docs: The release process includes updating the approach branches and activating versions. - -CMAKE notes +## CMAKE notes To verify the various cmake options and their interactions, several manual tests were done: @@ -662,8 +721,7 @@ We are using RelWithDebInfo for mingw and other non-Windows builds but Release for MSVC. There are linker warnings if MSVC is built with RelWithDebInfo when using external-libs. - -ABI checks +## ABI checks Until the conversion of the build to cmake, we relied on running the test suite with old executables and a new library. When QPDFJob was @@ -698,8 +756,7 @@ steps. See comments in check_abi for additional notes. Running "check_abi check-sizes" is run by ctest on Linux when CHECK_SIZES is on. - -CODE FORMATTING +## CODE FORMATTING * Emacs doesn't indent breaking strings concatenated with + over lines but clang-format does. It's clearer with clang-format. To @@ -708,17 +765,21 @@ CODE FORMATTING * With + ```cpp long_function(long_function( args) + ``` + clang-format anchors relative to the first function, and emacs anchors relative to the second function. Use + ```cpp long_function( // line-break long_function( args) - + ``` to resolve. In the revision control history, there is a commit around April 3, @@ -730,3 +791,4 @@ that clang-format produces several results. (In git this is commit The commits that have the bulk of automatic or mechanical reformatting are listed in .git-blame-ignore-revs. Any new bulk updates should be added there. +[//]: # (cSpell:ignore pikepdfs readthedocsorg .) diff --git a/cSpell.json b/cSpell.json index cc7ebbb2..c73ecdbf 100644 --- a/cSpell.json +++ b/cSpell.json @@ -300,6 +300,7 @@ "nobjects", "nocase", "nodefaultlib", + "nolint", "noout", "notfound", "nowarn", diff --git a/examples/pdf-count-strings.cc b/examples/pdf-count-strings.cc index 2061a499..2b5b5573 100644 --- a/examples/pdf-count-strings.cc +++ b/examples/pdf-count-strings.cc @@ -26,17 +26,14 @@ usage() class StringCounter: public QPDFObjectHandle::TokenFilter { public: - StringCounter() : - count(0) - { - } + StringCounter() = default; ~StringCounter() override = default; void handleToken(QPDFTokenizer::Token const&) override; void handleEOF() override; int getCount() const; private: - int count; + int count{0}; }; void diff --git a/examples/pdf-create.cc b/examples/pdf-create.cc index c793b5f8..136643d1 100644 --- a/examples/pdf-create.cc +++ b/examples/pdf-create.cc @@ -31,47 +31,43 @@ class ImageProvider: public QPDFObjectHandle::StreamDataProvider size_t getHeight() const; private: - size_t width; - size_t stripe_height; + size_t width{400}; + size_t stripe_height{80}; std::string color_space; std::string filter; - size_t n_stripes; + size_t n_stripes{6}; std::vector<std::string> stripes; - J_COLOR_SPACE j_color_space; + J_COLOR_SPACE j_color_space{JCS_UNKNOWN}; }; ImageProvider::ImageProvider(std::string const& color_space, std::string const& filter) : - width(400), - stripe_height(80), color_space(color_space), - filter(filter), - n_stripes(6), - j_color_space(JCS_UNKNOWN) + filter(filter) { if (color_space == "/DeviceCMYK") { j_color_space = JCS_CMYK; - stripes.push_back(std::string("\xff\x00\x00\x00", 4)); - stripes.push_back(std::string("\x00\xff\x00\x00", 4)); - stripes.push_back(std::string("\x00\x00\xff\x00", 4)); - stripes.push_back(std::string("\xff\x00\xff\x00", 4)); - stripes.push_back(std::string("\xff\xff\x00\x00", 4)); - stripes.push_back(std::string("\x00\x00\x00\xff", 4)); + stripes.emplace_back("\xff\x00\x00\x00", 4); + stripes.emplace_back("\x00\xff\x00\x00", 4); + stripes.emplace_back("\x00\x00\xff\x00", 4); + stripes.emplace_back("\xff\x00\xff\x00", 4); + stripes.emplace_back("\xff\xff\x00\x00", 4); + stripes.emplace_back("\x00\x00\x00\xff", 4); } else if (color_space == "/DeviceRGB") { j_color_space = JCS_RGB; - stripes.push_back(std::string("\xff\x00\x00", 3)); - stripes.push_back(std::string("\x00\xff\x00", 3)); - stripes.push_back(std::string("\x00\x00\xff", 3)); - stripes.push_back(std::string("\xff\x00\xff", 3)); - stripes.push_back(std::string("\xff\xff\x00", 3)); - stripes.push_back(std::string("\x00\x00\x00", 3)); + stripes.emplace_back("\xff\x00\x00", 3); + stripes.emplace_back("\x00\xff\x00", 3); + stripes.emplace_back("\x00\x00\xff", 3); + stripes.emplace_back("\xff\x00\xff", 3); + stripes.emplace_back("\xff\xff\x00", 3); + stripes.emplace_back("\x00\x00\x00", 3); } else if (color_space == "/DeviceGray") { j_color_space = JCS_GRAYSCALE; - stripes.push_back(std::string("\xee", 1)); - stripes.push_back(std::string("\xcc", 1)); - stripes.push_back(std::string("\x99", 1)); - stripes.push_back(std::string("\x66", 1)); - stripes.push_back(std::string("\x33", 1)); - stripes.push_back(std::string("\x00", 1)); + stripes.emplace_back("\xee", 1); + stripes.emplace_back("\xcc", 1); + stripes.emplace_back("\x99", 1); + stripes.emplace_back("\x66", 1); + stripes.emplace_back("\x33", 1); + stripes.emplace_back("\x00", 1); } } @@ -335,13 +331,13 @@ create_pdf(char const* filename) ">>"_qpdf); std::vector<std::string> color_spaces; - color_spaces.push_back("/DeviceCMYK"); - color_spaces.push_back("/DeviceRGB"); - color_spaces.push_back("/DeviceGray"); + color_spaces.emplace_back("/DeviceCMYK"); + color_spaces.emplace_back("/DeviceRGB"); + color_spaces.emplace_back("/DeviceGray"); std::vector<std::string> filters; - filters.push_back("null"); - filters.push_back("/DCTDecode"); - filters.push_back("/RunLengthDecode"); + filters.emplace_back("null"); + filters.emplace_back("/DCTDecode"); + filters.emplace_back("/RunLengthDecode"); QPDFPageDocumentHelper dh(pdf); for (auto const& color_space: color_spaces) { for (auto const& filter: filters) { diff --git a/format-code b/format-code index 5ec5275d..295c5d05 100755 --- a/format-code +++ b/format-code @@ -19,6 +19,19 @@ # Please see "Code Formatting" in the manual for additional notes. +# If a newer version of clang-format causes changes to the output that +# are improvements, bump the minimum required version of clang-format +# here, and update manual/contributing.rst. There's a comment there +# that refers to this comment. See also .clang-format. +min_version=16 + +clang_version=$(clang-format --version | \ + awk '{for (i=1; i<=NF; i++) if ($i == "version") {print int($(i+1)); exit}}') +if [ "$clang_version" -lt "$min_version" ]; then + echo "clang-format version >= $min_version is required" + exit 2 +fi + cd $(dirname $0) for i in $(find . -name 'build*' -prune -o '(' \ -name '*.hh' -o -name '*.h' -o -name '*.cc' -o -name '*.c' \ diff --git a/include/qpdf/BufferInputSource.hh b/include/qpdf/BufferInputSource.hh index 2ef04a28..bd63f788 100644 --- a/include/qpdf/BufferInputSource.hh +++ b/include/qpdf/BufferInputSource.hh @@ -32,21 +32,21 @@ class QPDF_DLL_CLASS BufferInputSource: public InputSource QPDF_DLL BufferInputSource(std::string const& description, std::string const& contents); QPDF_DLL - virtual ~BufferInputSource(); + ~BufferInputSource() override; QPDF_DLL - virtual qpdf_offset_t findAndSkipNextEOL(); + qpdf_offset_t findAndSkipNextEOL() override; QPDF_DLL - virtual std::string const& getName() const; + std::string const& getName() const override; QPDF_DLL - virtual qpdf_offset_t tell(); + qpdf_offset_t tell() override; QPDF_DLL - virtual void seek(qpdf_offset_t offset, int whence); + void seek(qpdf_offset_t offset, int whence) override; QPDF_DLL - virtual void rewind(); + void rewind() override; QPDF_DLL - virtual size_t read(char* buffer, size_t length); + size_t read(char* buffer, size_t length) override; QPDF_DLL - virtual void unreadCh(char ch); + void unreadCh(char ch) override; private: bool own_memory; diff --git a/include/qpdf/ClosedFileInputSource.hh b/include/qpdf/ClosedFileInputSource.hh index 41c46242..1a6a9a0b 100644 --- a/include/qpdf/ClosedFileInputSource.hh +++ b/include/qpdf/ClosedFileInputSource.hh @@ -37,21 +37,21 @@ class QPDF_DLL_CLASS ClosedFileInputSource: public InputSource QPDF_DLL ClosedFileInputSource(char const* filename); QPDF_DLL - virtual ~ClosedFileInputSource(); + ~ClosedFileInputSource() override; QPDF_DLL - virtual qpdf_offset_t findAndSkipNextEOL(); + qpdf_offset_t findAndSkipNextEOL() override; QPDF_DLL - virtual std::string const& getName() const; + std::string const& getName() const override; QPDF_DLL - virtual qpdf_offset_t tell(); + qpdf_offset_t tell() override; QPDF_DLL - virtual void seek(qpdf_offset_t offset, int whence); + void seek(qpdf_offset_t offset, int whence) override; QPDF_DLL - virtual void rewind(); + void rewind() override; QPDF_DLL - virtual size_t read(char* buffer, size_t length); + size_t read(char* buffer, size_t length) override; QPDF_DLL - virtual void unreadCh(char ch); + void unreadCh(char ch) override; // The file stays open between calls to stayOpen(true) and stayOpen(false). You can use this to // surround multiple operations on a single ClosedFileInputSource to reduce the overhead of a diff --git a/include/qpdf/FileInputSource.hh b/include/qpdf/FileInputSource.hh index 71adad7b..ed9ae6c6 100644 --- a/include/qpdf/FileInputSource.hh +++ b/include/qpdf/FileInputSource.hh @@ -35,21 +35,21 @@ class QPDF_DLL_CLASS FileInputSource: public InputSource QPDF_DLL void setFile(char const* description, FILE* filep, bool close_file); QPDF_DLL - virtual ~FileInputSource(); + ~FileInputSource() override; QPDF_DLL - virtual qpdf_offset_t findAndSkipNextEOL(); + qpdf_offset_t findAndSkipNextEOL() override; QPDF_DLL - virtual std::string const& getName() const; + std::string const& getName() const override; QPDF_DLL - virtual qpdf_offset_t tell(); + qpdf_offset_t tell() override; QPDF_DLL - virtual void seek(qpdf_offset_t offset, int whence); + void seek(qpdf_offset_t offset, int whence) override; QPDF_DLL - virtual void rewind(); + void rewind() override; QPDF_DLL - virtual size_t read(char* buffer, size_t length); + size_t read(char* buffer, size_t length) override; QPDF_DLL - virtual void unreadCh(char ch); + void unreadCh(char ch) override; private: FileInputSource(FileInputSource const&) = delete; diff --git a/include/qpdf/InputSource.hh b/include/qpdf/InputSource.hh index 2bc57c57..c1785a25 100644 --- a/include/qpdf/InputSource.hh +++ b/include/qpdf/InputSource.hh @@ -33,8 +33,7 @@ class QPDF_DLL_CLASS InputSource { public: QPDF_DLL - InputSource() : - last_offset(0) + InputSource() { } QPDF_DLL @@ -86,7 +85,7 @@ class QPDF_DLL_CLASS InputSource inline void loadBuffer(); protected: - qpdf_offset_t last_offset; + qpdf_offset_t last_offset{0}; private: class QPDF_DLL_PRIVATE Members diff --git a/include/qpdf/Pl_Concatenate.hh b/include/qpdf/Pl_Concatenate.hh index 24977de1..bee1bcf3 100644 --- a/include/qpdf/Pl_Concatenate.hh +++ b/include/qpdf/Pl_Concatenate.hh @@ -32,13 +32,13 @@ class QPDF_DLL_CLASS Pl_Concatenate: public Pipeline QPDF_DLL Pl_Concatenate(char const* identifier, Pipeline* next); QPDF_DLL - virtual ~Pl_Concatenate(); + ~Pl_Concatenate() override; QPDF_DLL - virtual void write(unsigned char const* data, size_t len); + void write(unsigned char const* data, size_t len) override; QPDF_DLL - virtual void finish(); + void finish() override; // At the very end, call manualFinish to actually finish the rest of the pipeline. QPDF_DLL diff --git a/include/qpdf/Pl_Count.hh b/include/qpdf/Pl_Count.hh index 51338607..3601f8de 100644 --- a/include/qpdf/Pl_Count.hh +++ b/include/qpdf/Pl_Count.hh @@ -30,11 +30,11 @@ class QPDF_DLL_CLASS Pl_Count: public Pipeline QPDF_DLL Pl_Count(char const* identifier, Pipeline* next); QPDF_DLL - virtual ~Pl_Count(); + ~Pl_Count() override; QPDF_DLL - virtual void write(unsigned char const*, size_t); + void write(unsigned char const*, size_t) override; QPDF_DLL - virtual void finish(); + void finish() override; // Returns the number of bytes written QPDF_DLL qpdf_offset_t getCount() const; diff --git a/include/qpdf/Pl_DCT.hh b/include/qpdf/Pl_DCT.hh index e4f6345f..b7e6b1e3 100644 --- a/include/qpdf/Pl_DCT.hh +++ b/include/qpdf/Pl_DCT.hh @@ -56,12 +56,12 @@ class QPDF_DLL_CLASS Pl_DCT: public Pipeline CompressConfig* config_callback = nullptr); QPDF_DLL - virtual ~Pl_DCT(); + ~Pl_DCT() override; QPDF_DLL - virtual void write(unsigned char const* data, size_t len); + void write(unsigned char const* data, size_t len) override; QPDF_DLL - virtual void finish(); + void finish() override; private: QPDF_DLL_PRIVATE diff --git a/include/qpdf/Pl_Discard.hh b/include/qpdf/Pl_Discard.hh index b2733a66..2eddf13d 100644 --- a/include/qpdf/Pl_Discard.hh +++ b/include/qpdf/Pl_Discard.hh @@ -31,11 +31,11 @@ class QPDF_DLL_CLASS Pl_Discard: public Pipeline QPDF_DLL Pl_Discard(); QPDF_DLL - virtual ~Pl_Discard(); + ~Pl_Discard() override; QPDF_DLL - virtual void write(unsigned char const*, size_t); + void write(unsigned char const*, size_t) override; QPDF_DLL - virtual void finish(); + void finish() override; private: class QPDF_DLL_PRIVATE Members diff --git a/include/qpdf/Pl_Flate.hh b/include/qpdf/Pl_Flate.hh index c31d4a0b..14009b2a 100644 --- a/include/qpdf/Pl_Flate.hh +++ b/include/qpdf/Pl_Flate.hh @@ -40,12 +40,12 @@ class QPDF_DLL_CLASS Pl_Flate: public Pipeline action_e action, unsigned int out_bufsize = def_bufsize); QPDF_DLL - virtual ~Pl_Flate(); + ~Pl_Flate() override; QPDF_DLL - virtual void write(unsigned char const* data, size_t len); + void write(unsigned char const* data, size_t len) override; QPDF_DLL - virtual void finish(); + void finish() override; // Globally set compression level from 1 (fastest, least // compression) to 9 (slowest, most compression). Use -1 to set diff --git a/include/qpdf/Pl_Function.hh b/include/qpdf/Pl_Function.hh index c9d5550d..afd421a3 100644 --- a/include/qpdf/Pl_Function.hh +++ b/include/qpdf/Pl_Function.hh @@ -54,12 +54,12 @@ class QPDF_DLL_CLASS Pl_Function: public Pipeline Pl_Function(char const* identifier, Pipeline* next, writer_c_char_t fn, void* udata); QPDF_DLL - virtual ~Pl_Function(); + ~Pl_Function() override; QPDF_DLL - virtual void write(unsigned char const* buf, size_t len); + void write(unsigned char const* buf, size_t len) override; QPDF_DLL - virtual void finish(); + void finish() override; private: class QPDF_DLL_PRIVATE Members diff --git a/include/qpdf/Pl_OStream.hh b/include/qpdf/Pl_OStream.hh index 3ea21c93..9aeaac4d 100644 --- a/include/qpdf/Pl_OStream.hh +++ b/include/qpdf/Pl_OStream.hh @@ -36,12 +36,12 @@ class QPDF_DLL_CLASS Pl_OStream: public Pipeline QPDF_DLL Pl_OStream(char const* identifier, std::ostream& os); QPDF_DLL - virtual ~Pl_OStream(); + ~Pl_OStream() override; QPDF_DLL - virtual void write(unsigned char const* buf, size_t len); + void write(unsigned char const* buf, size_t len) override; QPDF_DLL - virtual void finish(); + void finish() override; private: class QPDF_DLL_PRIVATE Members diff --git a/include/qpdf/Pl_QPDFTokenizer.hh b/include/qpdf/Pl_QPDFTokenizer.hh index 5bc6cb87..79cbda7b 100644 --- a/include/qpdf/Pl_QPDFTokenizer.hh +++ b/include/qpdf/Pl_QPDFTokenizer.hh @@ -45,11 +45,11 @@ class QPDF_DLL_CLASS Pl_QPDFTokenizer: public Pipeline Pl_QPDFTokenizer( char const* identifier, QPDFObjectHandle::TokenFilter* filter, Pipeline* next = nullptr); QPDF_DLL - virtual ~Pl_QPDFTokenizer(); + ~Pl_QPDFTokenizer() override; QPDF_DLL - virtual void write(unsigned char const* buf, size_t len); + void write(unsigned char const* buf, size_t len) override; QPDF_DLL - virtual void finish(); + void finish() override; private: class QPDF_DLL_PRIVATE Members diff --git a/include/qpdf/Pl_RunLength.hh b/include/qpdf/Pl_RunLength.hh index 86782535..e04bce2d 100644 --- a/include/qpdf/Pl_RunLength.hh +++ b/include/qpdf/Pl_RunLength.hh @@ -29,12 +29,12 @@ class QPDF_DLL_CLASS Pl_RunLength: public Pipeline QPDF_DLL Pl_RunLength(char const* identifier, Pipeline* next, action_e action); QPDF_DLL - virtual ~Pl_RunLength(); + ~Pl_RunLength() override; QPDF_DLL - virtual void write(unsigned char const* data, size_t len); + void write(unsigned char const* data, size_t len) override; QPDF_DLL - virtual void finish(); + void finish() override; private: QPDF_DLL_PRIVATE diff --git a/include/qpdf/Pl_StdioFile.hh b/include/qpdf/Pl_StdioFile.hh index 90190d2b..fb994459 100644 --- a/include/qpdf/Pl_StdioFile.hh +++ b/include/qpdf/Pl_StdioFile.hh @@ -36,12 +36,12 @@ class QPDF_DLL_CLASS Pl_StdioFile: public Pipeline QPDF_DLL Pl_StdioFile(char const* identifier, FILE* f); QPDF_DLL - virtual ~Pl_StdioFile(); + ~Pl_StdioFile() override; QPDF_DLL - virtual void write(unsigned char const* buf, size_t len); + void write(unsigned char const* buf, size_t len) override; QPDF_DLL - virtual void finish(); + void finish() override; private: class QPDF_DLL_PRIVATE Members diff --git a/include/qpdf/Pl_String.hh b/include/qpdf/Pl_String.hh index 8f712fbf..dc720c90 100644 --- a/include/qpdf/Pl_String.hh +++ b/include/qpdf/Pl_String.hh @@ -41,12 +41,12 @@ class QPDF_DLL_CLASS Pl_String: public Pipeline QPDF_DLL Pl_String(char const* identifier, Pipeline* next, std::string& s); QPDF_DLL - virtual ~Pl_String(); + ~Pl_String() override; QPDF_DLL - virtual void write(unsigned char const* buf, size_t len); + void write(unsigned char const* buf, size_t len) override; QPDF_DLL - virtual void finish(); + void finish() override; private: class QPDF_DLL_PRIVATE Members diff --git a/include/qpdf/QPDF.hh b/include/qpdf/QPDF.hh index 152421ad..e54947d9 100644 --- a/include/qpdf/QPDF.hh +++ b/include/qpdf/QPDF.hh @@ -942,8 +942,8 @@ class QPDF { public: CopiedStreamDataProvider(QPDF& destination_qpdf); - virtual ~CopiedStreamDataProvider() = default; - virtual bool provideStreamData( + ~CopiedStreamDataProvider() override = default; + bool provideStreamData( QPDFObjGen const& og, Pipeline* pipeline, bool suppress_warnings, @@ -963,8 +963,8 @@ class QPDF public: StringDecrypter(QPDF* qpdf, QPDFObjGen const& og); - virtual ~StringDecrypter() = default; - virtual void decryptString(std::string& val); + ~StringDecrypter() override = default; + void decryptString(std::string& val) override; private: QPDF* qpdf; @@ -1150,58 +1150,32 @@ class QPDF // PDF 1.4: Table F.4 struct HPageOffsetEntry { - HPageOffsetEntry() : - delta_nobjects(0), - delta_page_length(0), - nshared_objects(0), - delta_content_offset(0), - delta_content_length(0) - { - } - - int delta_nobjects; // 1 - qpdf_offset_t delta_page_length; // 2 - int nshared_objects; // 3 + int delta_nobjects{0}; // 1 + qpdf_offset_t delta_page_length{0}; // 2 // vectors' sizes = nshared_objects - std::vector<int> shared_identifiers; // 4 - std::vector<int> shared_numerators; // 5 - qpdf_offset_t delta_content_offset; // 6 - qpdf_offset_t delta_content_length; // 7 + int nshared_objects{0}; // 3 + std::vector<int> shared_identifiers; // 4 + std::vector<int> shared_numerators; // 5 + qpdf_offset_t delta_content_offset{0}; // 6 + qpdf_offset_t delta_content_length{0}; // 7 }; // PDF 1.4: Table F.3 struct HPageOffset { - HPageOffset() : - min_nobjects(0), - first_page_offset(0), - nbits_delta_nobjects(0), - min_page_length(0), - nbits_delta_page_length(0), - min_content_offset(0), - nbits_delta_content_offset(0), - min_content_length(0), - nbits_delta_content_length(0), - nbits_nshared_objects(0), - nbits_shared_identifier(0), - nbits_shared_numerator(0), - shared_denominator(0) - { - } - - int min_nobjects; // 1 - qpdf_offset_t first_page_offset; // 2 - int nbits_delta_nobjects; // 3 - int min_page_length; // 4 - int nbits_delta_page_length; // 5 - int min_content_offset; // 6 - int nbits_delta_content_offset; // 7 - int min_content_length; // 8 - int nbits_delta_content_length; // 9 - int nbits_nshared_objects; // 10 - int nbits_shared_identifier; // 11 - int nbits_shared_numerator; // 12 - int shared_denominator; // 13 + int min_nobjects{0}; // 1 + qpdf_offset_t first_page_offset{0}; // 2 + int nbits_delta_nobjects{0}; // 3 + int min_page_length{0}; // 4 + int nbits_delta_page_length{0}; // 5 + int min_content_offset{0}; // 6 + int nbits_delta_content_offset{0}; // 7 + int min_content_length{0}; // 8 + int nbits_delta_content_length{0}; // 9 + int nbits_nshared_objects{0}; // 10 + int nbits_shared_identifier{0}; // 11 + int nbits_shared_numerator{0}; // 12 + int shared_denominator{0}; // 13 // vector size is npages std::vector<HPageOffsetEntry> entries; }; @@ -1209,40 +1183,22 @@ class QPDF // PDF 1.4: Table F.6 struct HSharedObjectEntry { - HSharedObjectEntry() : - delta_group_length(0), - signature_present(0), - nobjects_minus_one(0) - { - } - // Item 3 is a 128-bit signature (unsupported by Acrobat) - int delta_group_length; // 1 - int signature_present; // 2 -- always 0 - int nobjects_minus_one; // 4 -- always 0 + int delta_group_length{0}; // 1 + int signature_present{0}; // 2 -- always 0 + int nobjects_minus_one{0}; // 4 -- always 0 }; // PDF 1.4: Table F.5 struct HSharedObject { - HSharedObject() : - first_shared_obj(0), - first_shared_offset(0), - nshared_first_page(0), - nshared_total(0), - nbits_nobjects(0), - min_group_length(0), - nbits_delta_group_length(0) - { - } - - int first_shared_obj; // 1 - qpdf_offset_t first_shared_offset; // 2 - int nshared_first_page; // 3 - int nshared_total; // 4 - int nbits_nobjects; // 5 - int min_group_length; // 6 - int nbits_delta_group_length; // 7 + int first_shared_obj{0}; // 1 + qpdf_offset_t first_shared_offset{0}; // 2 + int nshared_first_page{0}; // 3 + int nshared_total{0}; // 4 + int nbits_nobjects{0}; // 5 + int min_group_length{0}; // 6 + int nbits_delta_group_length{0}; // 7 // vector size is nshared_total std::vector<HSharedObjectEntry> entries; }; @@ -1250,18 +1206,10 @@ class QPDF // PDF 1.4: Table F.9 struct HGeneric { - HGeneric() : - first_object(0), - first_object_offset(0), - nobjects(0), - group_length(0) - { - } - - int first_object; // 1 - qpdf_offset_t first_object_offset; // 2 - int nobjects; // 3 - int group_length; // 4 + int first_object{0}; // 1 + qpdf_offset_t first_object_offset{0}; // 2 + int nobjects{0}; // 3 + int group_length{0}; // 4 }; // Other linearization data structures @@ -1269,26 +1217,14 @@ class QPDF // Initialized from Linearization Parameter dictionary struct LinParameters { - LinParameters() : - file_size(0), - first_page_object(0), - first_page_end(0), - npages(0), - xref_zero_offset(0), - first_page(0), - H_offset(0), - H_length(0) - { - } - - qpdf_offset_t file_size; // /L - int first_page_object; // /O - qpdf_offset_t first_page_end; // /E - int npages; // /N - qpdf_offset_t xref_zero_offset; // /T - int first_page; // /P - qpdf_offset_t H_offset; // offset of primary hint stream - qpdf_offset_t H_length; // length of primary hint stream + qpdf_offset_t file_size{0}; // /L + int first_page_object{0}; // /O + qpdf_offset_t first_page_end{0}; // /E + int npages{0}; // /N + qpdf_offset_t xref_zero_offset{0}; // /T + int first_page{0}; // /P + qpdf_offset_t H_offset{0}; // offset of primary hint stream + qpdf_offset_t H_length{0}; // length of primary hint stream }; // Computed hint table value data structures. These tables contain the computed values on which @@ -1304,14 +1240,8 @@ class QPDF struct CHPageOffsetEntry { - CHPageOffsetEntry() : - nobjects(0), - nshared_objects(0) - { - } - - int nobjects; - int nshared_objects; + int nobjects{0}; + int nshared_objects{0}; // vectors' sizes = nshared_objects std::vector<int> shared_identifiers; }; @@ -1335,16 +1265,9 @@ class QPDF // PDF 1.4: Table F.5 struct CHSharedObject { - CHSharedObject() : - first_shared_obj(0), - nshared_first_page(0), - nshared_total(0) - { - } - - int first_shared_obj; - int nshared_first_page; - int nshared_total; + int first_shared_obj{0}; + int nshared_first_page{0}; + int nshared_total{0}; // vector size is nshared_total std::vector<CHSharedObjectEntry> entries; }; @@ -1385,9 +1308,9 @@ class QPDF checker(checker) { } - virtual ~PatternFinder() = default; - virtual bool - check() + ~PatternFinder() override = default; + bool + check() override { return (this->qpdf.*checker)(); } diff --git a/include/qpdf/QPDFAcroFormDocumentHelper.hh b/include/qpdf/QPDFAcroFormDocumentHelper.hh index a86563fa..8be4d069 100644 --- a/include/qpdf/QPDFAcroFormDocumentHelper.hh +++ b/include/qpdf/QPDFAcroFormDocumentHelper.hh @@ -71,7 +71,7 @@ class QPDFAcroFormDocumentHelper: public QPDFDocumentHelper QPDF_DLL QPDFAcroFormDocumentHelper(QPDF&); QPDF_DLL - virtual ~QPDFAcroFormDocumentHelper() = default; + ~QPDFAcroFormDocumentHelper() override = default; // This class lazily creates an internal cache of the mapping among form fields, annotations, // and pages. Methods within this class preserve the validity of this cache. However, if you diff --git a/include/qpdf/QPDFAnnotationObjectHelper.hh b/include/qpdf/QPDFAnnotationObjectHelper.hh index b93f895f..69ec77b4 100644 --- a/include/qpdf/QPDFAnnotationObjectHelper.hh +++ b/include/qpdf/QPDFAnnotationObjectHelper.hh @@ -30,7 +30,7 @@ class QPDFAnnotationObjectHelper: public QPDFObjectHelper QPDF_DLL QPDFAnnotationObjectHelper(QPDFObjectHandle); QPDF_DLL - virtual ~QPDFAnnotationObjectHelper() = default; + ~QPDFAnnotationObjectHelper() override = default; // This class provides helper methods for annotations. More functionality will likely be added // in the future. diff --git a/include/qpdf/QPDFEFStreamObjectHelper.hh b/include/qpdf/QPDFEFStreamObjectHelper.hh index cdb5c278..2d55cca7 100644 --- a/include/qpdf/QPDFEFStreamObjectHelper.hh +++ b/include/qpdf/QPDFEFStreamObjectHelper.hh @@ -35,7 +35,7 @@ class QPDFEFStreamObjectHelper: public QPDFObjectHelper QPDF_DLL QPDFEFStreamObjectHelper(QPDFObjectHandle); QPDF_DLL - virtual ~QPDFEFStreamObjectHelper() = default; + ~QPDFEFStreamObjectHelper() override = default; // Date parameters are strings that conform to the PDF spec for date/time strings, which is // "D:yyyymmddhhmmss<z>" where <z> is either "Z" for UTC or "-hh'mm'" or "+hh'mm'" for timezone diff --git a/include/qpdf/QPDFEmbeddedFileDocumentHelper.hh b/include/qpdf/QPDFEmbeddedFileDocumentHelper.hh index 4727feef..b4633369 100644 --- a/include/qpdf/QPDFEmbeddedFileDocumentHelper.hh +++ b/include/qpdf/QPDFEmbeddedFileDocumentHelper.hh @@ -39,7 +39,7 @@ class QPDFEmbeddedFileDocumentHelper: public QPDFDocumentHelper QPDF_DLL QPDFEmbeddedFileDocumentHelper(QPDF&); QPDF_DLL - virtual ~QPDFEmbeddedFileDocumentHelper() = default; + ~QPDFEmbeddedFileDocumentHelper() override = default; QPDF_DLL bool hasEmbeddedFiles() const; diff --git a/include/qpdf/QPDFExc.hh b/include/qpdf/QPDFExc.hh index 1a9e16f2..daa52a47 100644 --- a/include/qpdf/QPDFExc.hh +++ b/include/qpdf/QPDFExc.hh @@ -37,7 +37,7 @@ class QPDF_DLL_CLASS QPDFExc: public std::runtime_error qpdf_offset_t offset, std::string const& message); QPDF_DLL - virtual ~QPDFExc() noexcept = default; + ~QPDFExc() noexcept override = default; // To get a complete error string, call what(), provided by std::exception. The accessors below // return the original values used to create the exception. Only the error code and message are diff --git a/include/qpdf/QPDFFileSpecObjectHelper.hh b/include/qpdf/QPDFFileSpecObjectHelper.hh index 9b6474df..6001f09d 100644 --- a/include/qpdf/QPDFFileSpecObjectHelper.hh +++ b/include/qpdf/QPDFFileSpecObjectHelper.hh @@ -35,7 +35,7 @@ class QPDFFileSpecObjectHelper: public QPDFObjectHelper QPDF_DLL QPDFFileSpecObjectHelper(QPDFObjectHandle); QPDF_DLL - virtual ~QPDFFileSpecObjectHelper() = default; + ~QPDFFileSpecObjectHelper() override = default; QPDF_DLL std::string getDescription(); diff --git a/include/qpdf/QPDFFormFieldObjectHelper.hh b/include/qpdf/QPDFFormFieldObjectHelper.hh index fbd5547f..156ccc64 100644 --- a/include/qpdf/QPDFFormFieldObjectHelper.hh +++ b/include/qpdf/QPDFFormFieldObjectHelper.hh @@ -37,7 +37,7 @@ class QPDFFormFieldObjectHelper: public QPDFObjectHelper QPDF_DLL QPDFFormFieldObjectHelper(QPDFObjectHandle); QPDF_DLL - virtual ~QPDFFormFieldObjectHelper() = default; + ~QPDFFormFieldObjectHelper() override = default; QPDF_DLL bool isNull(); diff --git a/include/qpdf/QPDFJob.hh b/include/qpdf/QPDFJob.hh index 37067108..b9c8ba50 100644 --- a/include/qpdf/QPDFJob.hh +++ b/include/qpdf/QPDFJob.hh @@ -145,11 +145,6 @@ class QPDFJob struct AddAttachment { - AddAttachment() : - replace(false) - { - } - std::string path; std::string key; std::string filename; @@ -157,7 +152,7 @@ class QPDFJob std::string moddate; std::string mimetype; std::string description; - bool replace; + bool replace{false}; }; struct PageSpec diff --git a/include/qpdf/QPDFNameTreeObjectHelper.hh b/include/qpdf/QPDFNameTreeObjectHelper.hh index 90cb6856..1d344a6c 100644 --- a/include/qpdf/QPDFNameTreeObjectHelper.hh +++ b/include/qpdf/QPDFNameTreeObjectHelper.hh @@ -50,7 +50,7 @@ class QPDF_DLL_CLASS QPDFNameTreeObjectHelper: public QPDFObjectHelper static QPDFNameTreeObjectHelper newEmpty(QPDF&, bool auto_repair = true); QPDF_DLL - virtual ~QPDFNameTreeObjectHelper(); + ~QPDFNameTreeObjectHelper() override; // Return whether the name tree has an explicit entry for this name. QPDF_DLL diff --git a/include/qpdf/QPDFNumberTreeObjectHelper.hh b/include/qpdf/QPDFNumberTreeObjectHelper.hh index 12603af0..fe55a28f 100644 --- a/include/qpdf/QPDFNumberTreeObjectHelper.hh +++ b/include/qpdf/QPDFNumberTreeObjectHelper.hh @@ -44,7 +44,7 @@ class QPDF_DLL_CLASS QPDFNumberTreeObjectHelper: public QPDFObjectHelper QPDFNumberTreeObjectHelper(QPDFObjectHandle, QPDF&, bool auto_repair = true); QPDF_DLL - virtual ~QPDFNumberTreeObjectHelper(); + ~QPDFNumberTreeObjectHelper() override; // Create an empty number tree QPDF_DLL diff --git a/include/qpdf/QPDFObjGen.hh b/include/qpdf/QPDFObjGen.hh index 0f22b481..60c397e4 100644 --- a/include/qpdf/QPDFObjGen.hh +++ b/include/qpdf/QPDFObjGen.hh @@ -34,9 +34,7 @@ class QPDFObjGen public: // ABI: change to default. QPDF_DLL - QPDFObjGen() : - obj(0), - gen(0) + QPDFObjGen() { } QPDF_DLL diff --git a/include/qpdf/QPDFObjectHandle.hh b/include/qpdf/QPDFObjectHandle.hh index 45ad1079..03262b40 100644 --- a/include/qpdf/QPDFObjectHandle.hh +++ b/include/qpdf/QPDFObjectHandle.hh @@ -290,6 +290,14 @@ class QPDFObjectHandle QPDFObjectHandle(QPDFObjectHandle const&) = default; QPDF_DLL QPDFObjectHandle& operator=(QPDFObjectHandle const&) = default; + +#ifdef QPDF_FUTURE + QPDF_DLL + QPDFObjectHandle(QPDFObjectHandle&&) = default; + QPDF_DLL + QPDFObjectHandle& operator=(QPDFObjectHandle&&) = default; +#endif + QPDF_DLL inline bool isInitialized() const; diff --git a/include/qpdf/QPDFOutlineDocumentHelper.hh b/include/qpdf/QPDFOutlineDocumentHelper.hh index eb5f8f9a..1d249969 100644 --- a/include/qpdf/QPDFOutlineDocumentHelper.hh +++ b/include/qpdf/QPDFOutlineDocumentHelper.hh @@ -41,7 +41,7 @@ class QPDFOutlineDocumentHelper: public QPDFDocumentHelper QPDF_DLL QPDFOutlineDocumentHelper(QPDF&); QPDF_DLL - virtual ~QPDFOutlineDocumentHelper() = default; + ~QPDFOutlineDocumentHelper() override = default; QPDF_DLL bool hasOutlines(); diff --git a/include/qpdf/QPDFOutlineObjectHelper.hh b/include/qpdf/QPDFOutlineObjectHelper.hh index 289941fa..6b42f509 100644 --- a/include/qpdf/QPDFOutlineObjectHelper.hh +++ b/include/qpdf/QPDFOutlineObjectHelper.hh @@ -34,7 +34,7 @@ class QPDFOutlineObjectHelper: public QPDFObjectHelper { public: QPDF_DLL - virtual ~QPDFOutlineObjectHelper() + ~QPDFOutlineObjectHelper() override { // This must be cleared explicitly to avoid circular references that prevent cleanup of // shared pointers. @@ -81,7 +81,7 @@ class QPDFOutlineObjectHelper: public QPDFObjectHelper static QPDFOutlineObjectHelper create(QPDFObjectHandle oh, QPDFOutlineDocumentHelper& dh, int depth) { - return QPDFOutlineObjectHelper(oh, dh, depth); + return {oh, dh, depth}; } }; diff --git a/include/qpdf/QPDFPageDocumentHelper.hh b/include/qpdf/QPDFPageDocumentHelper.hh index a6005a45..b408fdd2 100644 --- a/include/qpdf/QPDFPageDocumentHelper.hh +++ b/include/qpdf/QPDFPageDocumentHelper.hh @@ -37,7 +37,7 @@ class QPDFPageDocumentHelper: public QPDFDocumentHelper QPDF_DLL QPDFPageDocumentHelper(QPDF&); QPDF_DLL - virtual ~QPDFPageDocumentHelper() = default; + ~QPDFPageDocumentHelper() override = default; // Traverse page tree, and return all /Page objects wrapped in QPDFPageObjectHelper objects. // Unlike with QPDF::getAllPages, the vector of pages returned by this call is not affected by diff --git a/include/qpdf/QPDFPageLabelDocumentHelper.hh b/include/qpdf/QPDFPageLabelDocumentHelper.hh index 64e85869..741329cb 100644 --- a/include/qpdf/QPDFPageLabelDocumentHelper.hh +++ b/include/qpdf/QPDFPageLabelDocumentHelper.hh @@ -44,7 +44,7 @@ class QPDFPageLabelDocumentHelper: public QPDFDocumentHelper QPDF_DLL QPDFPageLabelDocumentHelper(QPDF&); QPDF_DLL - virtual ~QPDFPageLabelDocumentHelper() = default; + ~QPDFPageLabelDocumentHelper() override = default; QPDF_DLL bool hasPageLabels(); diff --git a/include/qpdf/QPDFPageObjectHelper.hh b/include/qpdf/QPDFPageObjectHelper.hh index 120df104..a5be1dee 100644 --- a/include/qpdf/QPDFPageObjectHelper.hh +++ b/include/qpdf/QPDFPageObjectHelper.hh @@ -39,7 +39,7 @@ class QPDFPageObjectHelper: public QPDFObjectHelper QPDF_DLL QPDFPageObjectHelper(QPDFObjectHandle); QPDF_DLL - virtual ~QPDFPageObjectHelper() = default; + ~QPDFPageObjectHelper() override = default; // PAGE ATTRIBUTES diff --git a/include/qpdf/QPDFSystemError.hh b/include/qpdf/QPDFSystemError.hh index 7833b070..cdc3e386 100644 --- a/include/qpdf/QPDFSystemError.hh +++ b/include/qpdf/QPDFSystemError.hh @@ -32,7 +32,7 @@ class QPDF_DLL_CLASS QPDFSystemError: public std::runtime_error QPDF_DLL QPDFSystemError(std::string const& description, int system_errno); QPDF_DLL - virtual ~QPDFSystemError() noexcept = default; + ~QPDFSystemError() noexcept override = default; // To get a complete error string, call what(), provided by std::exception. The accessors below // return the original values used to create the exception. diff --git a/include/qpdf/QPDFUsage.hh b/include/qpdf/QPDFUsage.hh index 538392a0..16fbb867 100644 --- a/include/qpdf/QPDFUsage.hh +++ b/include/qpdf/QPDFUsage.hh @@ -30,7 +30,7 @@ class QPDF_DLL_CLASS QPDFUsage: public std::runtime_error QPDF_DLL QPDFUsage(std::string const& msg); QPDF_DLL - virtual ~QPDFUsage() noexcept = default; + ~QPDFUsage() noexcept override = default; }; #endif // QPDFUSAGE_HH diff --git a/include/qpdf/QPDFWriter.hh b/include/qpdf/QPDFWriter.hh index 34720119..be2d6f2e 100644 --- a/include/qpdf/QPDFWriter.hh +++ b/include/qpdf/QPDFWriter.hh @@ -92,7 +92,7 @@ class QPDFWriter QPDF_DLL FunctionProgressReporter(std::function<void(int)>); QPDF_DLL - virtual ~FunctionProgressReporter(); + ~FunctionProgressReporter() override; QPDF_DLL void reportProgress(int) override; diff --git a/lgtm.yml b/lgtm.yml deleted file mode 100644 index 73ccfd6c..00000000 --- a/lgtm.yml +++ /dev/null @@ -1,11 +0,0 @@ -# See https://lgtm.com/help/lgtm/lgtm.yml-configuration-file - -# Suppress alerts for weak cryptographic algorithms. The PDF file -# format used to rely on various weak algorithms. It is no longer -# necessary to use them when creating encrypted PDF files, but qpdf -# must always retain support for those algorithms in order to be able -# to read older files. qpdf issues warnings to try to prevent users -# from creating new files with weak encryption algorithms. - -queries: -- exclude: cpp/weak-cryptographic-algorithm diff --git a/libqpdf/ClosedFileInputSource.cc b/libqpdf/ClosedFileInputSource.cc index 5e607a76..2a6cb897 100644 --- a/libqpdf/ClosedFileInputSource.cc +++ b/libqpdf/ClosedFileInputSource.cc @@ -9,7 +9,7 @@ ClosedFileInputSource::ClosedFileInputSource(char const* filename) : { } -ClosedFileInputSource::~ClosedFileInputSource() +ClosedFileInputSource::~ClosedFileInputSource() // NOLINT (modernize-use-equals-default) { // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer } diff --git a/libqpdf/InputSource.cc b/libqpdf/InputSource.cc index f5dc7706..9389c2f5 100644 --- a/libqpdf/InputSource.cc +++ b/libqpdf/InputSource.cc @@ -37,7 +37,7 @@ InputSource::readLine(size_t max_line_length) if (line_length < max_line_length) { buf[line_length] = '\0'; } - return std::string(buf); + return {buf}; } bool diff --git a/libqpdf/JSON.cc b/libqpdf/JSON.cc index a11d06f2..f6401642 100644 --- a/libqpdf/JSON.cc +++ b/libqpdf/JSON.cc @@ -269,7 +269,7 @@ JSON::encode_string(std::string const& str) JSON JSON::makeDictionary() { - return JSON(std::make_unique<JSON_dictionary>()); + return {std::make_unique<JSON_dictionary>()}; } JSON @@ -299,7 +299,7 @@ JSON::checkDictionaryKeySeen(std::string const& key) JSON JSON::makeArray() { - return JSON(std::make_unique<JSON_array>()); + return {std::make_unique<JSON_array>()}; } JSON @@ -320,43 +320,43 @@ JSON::addArrayElement(JSON const& val) JSON JSON::makeString(std::string const& utf8) { - return JSON(std::make_unique<JSON_string>(utf8)); + return {std::make_unique<JSON_string>(utf8)}; } JSON JSON::makeInt(long long int value) { - return JSON(std::make_unique<JSON_number>(value)); + return {std::make_unique<JSON_number>(value)}; } JSON JSON::makeReal(double value) { - return JSON(std::make_unique<JSON_number>(value)); + return {std::make_unique<JSON_number>(value)}; } JSON JSON::makeNumber(std::string const& encoded) { - return JSON(std::make_unique<JSON_number>(encoded)); + return {std::make_unique<JSON_number>(encoded)}; } JSON JSON::makeBool(bool value) { - return JSON(std::make_unique<JSON_bool>(value)); + return {std::make_unique<JSON_bool>(value)}; } JSON JSON::makeNull() { - return JSON(std::make_unique<JSON_null>()); + return {std::make_unique<JSON_null>()}; } JSON JSON::makeBlob(std::function<void(Pipeline*)> fn) { - return JSON(std::make_unique<JSON_blob>(fn)); + return {std::make_unique<JSON_blob>(fn)}; } bool @@ -588,14 +588,7 @@ namespace JSONParser(InputSource& is, JSON::Reactor* reactor) : is(is), reactor(reactor), - lex_state(ls_top), - bytes(0), - p(buf), - u_count(0), - offset(0), - done(false), - parser_state(ps_top), - dict_key_offset(0) + p(buf) { } @@ -665,20 +658,20 @@ namespace InputSource& is; JSON::Reactor* reactor; - lex_state_e lex_state; + lex_state_e lex_state{ls_top}; char buf[16384]; - size_t bytes; + size_t bytes{0}; char const* p; - qpdf_offset_t u_count; + qpdf_offset_t u_count{0}; unsigned long u_value{0}; - qpdf_offset_t offset; - bool done; + qpdf_offset_t offset{0}; + bool done{false}; std::string token; qpdf_offset_t token_start{0}; - parser_state_e parser_state; + parser_state_e parser_state{ps_top}; std::vector<StackFrame> stack; std::string dict_key; - qpdf_offset_t dict_key_offset; + qpdf_offset_t dict_key_offset{0}; }; } // namespace @@ -1282,7 +1275,7 @@ JSONParser::handleToken() case ps_top: if (!(item.isDictionary() || item.isArray())) { - stack.push_back({ps_done, item}); + stack.emplace_back(ps_done, item); parser_state = ps_done; return; } @@ -1311,7 +1304,7 @@ JSONParser::handleToken() } if (item.isDictionary() || item.isArray()) { - stack.push_back({parser_state, item}); + stack.emplace_back(parser_state, item); // Calling container start method is postponed until after adding the containers to their // parent containers, if any. This makes it much easier to keep track of the current nesting // level. diff --git a/libqpdf/JSONHandler.cc b/libqpdf/JSONHandler.cc index b5c7c35d..4a69fd60 100644 --- a/libqpdf/JSONHandler.cc +++ b/libqpdf/JSONHandler.cc @@ -4,11 +4,48 @@ #include <qpdf/QTC.hh> #include <qpdf/QUtil.hh> +struct Handlers +{ + Handlers() = default; + + JSONHandler::json_handler_t any_handler{nullptr}; + JSONHandler::void_handler_t null_handler{nullptr}; + JSONHandler::string_handler_t string_handler{nullptr}; + JSONHandler::string_handler_t number_handler{nullptr}; + JSONHandler::bool_handler_t bool_handler{nullptr}; + JSONHandler::json_handler_t dict_start_handler{nullptr}; + JSONHandler::void_handler_t dict_end_handler{nullptr}; + JSONHandler::json_handler_t array_start_handler{nullptr}; + JSONHandler::void_handler_t array_end_handler{nullptr}; + JSONHandler::void_handler_t final_handler{nullptr}; + std::map<std::string, std::shared_ptr<JSONHandler>> dict_handlers; + std::shared_ptr<JSONHandler> fallback_dict_handler; + std::shared_ptr<JSONHandler> array_item_handler; +}; + +class JSONHandler::Members +{ + friend class JSONHandler; + + public: + ~Members() = default; + + private: + Members() = default; + Members(Members const&) = delete; + + Handlers h; +}; + JSONHandler::JSONHandler() : m(new Members()) { } +JSONHandler::~JSONHandler() +{ +} + void JSONHandler::usage(std::string const& msg) { @@ -80,24 +117,24 @@ JSONHandler::handle(std::string const& path, JSON j) m->h.any_handler(path, j); return; } - bool handled = false; + bool bvalue = false; std::string s_value; if (m->h.null_handler && j.isNull()) { m->h.null_handler(path); - handled = true; + return; } if (m->h.string_handler && j.getString(s_value)) { m->h.string_handler(path, s_value); - handled = true; + return; } if (m->h.number_handler && j.getNumber(s_value)) { m->h.number_handler(path, s_value); - handled = true; + return; } if (m->h.bool_handler && j.getBool(bvalue)) { m->h.bool_handler(path, bvalue); - handled = true; + return; } if (m->h.dict_start_handler && j.isDictionary()) { m->h.dict_start_handler(path, j); @@ -119,7 +156,7 @@ JSONHandler::handle(std::string const& path, JSON j) } }); m->h.dict_end_handler(path); - handled = true; + return; } if (m->h.array_start_handler && j.isArray()) { m->h.array_start_handler(path, j); @@ -129,15 +166,13 @@ JSONHandler::handle(std::string const& path, JSON j) ++i; }); m->h.array_end_handler(path); - handled = true; + return; } - if (!handled) { - // It would be nice to include information about what type the object was and what types - // were allowed, but we're relying on schema validation to make sure input is properly - // structured before calling the handlers. It would be different if this code were trying to - // be part of a general-purpose JSON package. - QTC::TC("libtests", "JSONHandler unhandled value"); - usage("JSON handler: value at " + path + " is not of expected type"); - } + // It would be nice to include information about what type the object was and what types were + // allowed, but we're relying on schema validation to make sure input is properly structured + // before calling the handlers. It would be different if this code were trying to be part of a + // general-purpose JSON package. + QTC::TC("libtests", "JSONHandler unhandled value"); + usage("JSON handler: value at " + path + " is not of expected type"); } diff --git a/libqpdf/NNTree.cc b/libqpdf/NNTree.cc index a584ff8d..fa054794 100644 --- a/libqpdf/NNTree.cc +++ b/libqpdf/NNTree.cc @@ -319,7 +319,7 @@ NNTreeIterator::split(QPDFObjectHandle to_split, std::list<PathElement>::iterato auto next = this->path.begin(); next->node = first_node; } - this->path.push_front(PathElement(to_split, 0)); + this->path.emplace_front(to_split, 0); parent = this->path.begin(); to_split = first_node; } @@ -578,7 +578,7 @@ NNTreeIterator::setItemNumber(QPDFObjectHandle const& node, int n) void NNTreeIterator::addPathElement(QPDFObjectHandle const& node, int kid_number) { - this->path.push_back(PathElement(node, kid_number)); + this->path.emplace_back(node, kid_number); } bool @@ -591,7 +591,7 @@ NNTreeIterator::deepen(QPDFObjectHandle node, bool first, bool allow_empty) bool failed = false; QPDFObjGen::set seen; - for (auto i: this->path) { + for (auto const& i: this->path) { seen.add(i.node); } while (!failed) { @@ -689,7 +689,7 @@ NNTreeImpl::begin() NNTreeImpl::iterator NNTreeImpl::end() { - return iterator(*this); + return {*this}; } NNTreeImpl::iterator diff --git a/libqpdf/Pl_Buffer.cc b/libqpdf/Pl_Buffer.cc index c3184104..b10cf544 100644 --- a/libqpdf/Pl_Buffer.cc +++ b/libqpdf/Pl_Buffer.cc @@ -11,7 +11,7 @@ Pl_Buffer::Pl_Buffer(char const* identifier, Pipeline* next) : { } -Pl_Buffer::~Pl_Buffer() +Pl_Buffer::~Pl_Buffer() // NOLINT (modernize-use-equals-default) { // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer } diff --git a/libqpdf/Pl_Concatenate.cc b/libqpdf/Pl_Concatenate.cc index 8f974c05..82ec0bd4 100644 --- a/libqpdf/Pl_Concatenate.cc +++ b/libqpdf/Pl_Concatenate.cc @@ -5,7 +5,7 @@ Pl_Concatenate::Pl_Concatenate(char const* identifier, Pipeline* next) : { } -Pl_Concatenate::~Pl_Concatenate() +Pl_Concatenate::~Pl_Concatenate() // NOLINT (modernize-use-equals-default) { // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer } diff --git a/libqpdf/Pl_Count.cc b/libqpdf/Pl_Count.cc index 07bb2654..4a0d6cef 100644 --- a/libqpdf/Pl_Count.cc +++ b/libqpdf/Pl_Count.cc @@ -14,7 +14,7 @@ Pl_Count::Pl_Count(char const* identifier, Pipeline* next) : { } -Pl_Count::~Pl_Count() +Pl_Count::~Pl_Count() // NOLINT (modernize-use-equals-default) { // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer } diff --git a/libqpdf/Pl_DCT.cc b/libqpdf/Pl_DCT.cc index f82fc2aa..042d3977 100644 --- a/libqpdf/Pl_DCT.cc +++ b/libqpdf/Pl_DCT.cc @@ -75,7 +75,7 @@ Pl_DCT::Pl_DCT( { } -Pl_DCT::~Pl_DCT() +Pl_DCT::~Pl_DCT() // NOLINT (modernize-use-equals-default) { // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer } diff --git a/libqpdf/Pl_Discard.cc b/libqpdf/Pl_Discard.cc index d9ddaef3..643d3e4f 100644 --- a/libqpdf/Pl_Discard.cc +++ b/libqpdf/Pl_Discard.cc @@ -7,7 +7,7 @@ Pl_Discard::Pl_Discard() : { } -Pl_Discard::~Pl_Discard() +Pl_Discard::~Pl_Discard() // NOLINT (modernize-use-equals-default) { // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer } diff --git a/libqpdf/Pl_Flate.cc b/libqpdf/Pl_Flate.cc index f43c0b7f..d332e635 100644 --- a/libqpdf/Pl_Flate.cc +++ b/libqpdf/Pl_Flate.cc @@ -58,7 +58,7 @@ Pl_Flate::Pl_Flate( { } -Pl_Flate::~Pl_Flate() +Pl_Flate::~Pl_Flate() // NOLINT (modernize-use-equals-default) { // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer } diff --git a/libqpdf/Pl_Function.cc b/libqpdf/Pl_Function.cc index c75df2a4..00d7f5b0 100644 --- a/libqpdf/Pl_Function.cc +++ b/libqpdf/Pl_Function.cc @@ -39,7 +39,7 @@ Pl_Function::Pl_Function(char const* identifier, Pipeline* next, writer_c_char_t }; } -Pl_Function::~Pl_Function() +Pl_Function::~Pl_Function() // NOLINT (modernize-use-equals-default) { // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer } diff --git a/libqpdf/Pl_OStream.cc b/libqpdf/Pl_OStream.cc index 73fbad21..9b1995a4 100644 --- a/libqpdf/Pl_OStream.cc +++ b/libqpdf/Pl_OStream.cc @@ -13,7 +13,7 @@ Pl_OStream::Pl_OStream(char const* identifier, std::ostream& os) : { } -Pl_OStream::~Pl_OStream() +Pl_OStream::~Pl_OStream() // NOLINT (modernize-use-equals-default) { // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer } diff --git a/libqpdf/Pl_QPDFTokenizer.cc b/libqpdf/Pl_QPDFTokenizer.cc index 576c2bfb..7bb86d5f 100644 --- a/libqpdf/Pl_QPDFTokenizer.cc +++ b/libqpdf/Pl_QPDFTokenizer.cc @@ -21,7 +21,7 @@ Pl_QPDFTokenizer::Pl_QPDFTokenizer( m->tokenizer.includeIgnorable(); } -Pl_QPDFTokenizer::~Pl_QPDFTokenizer() +Pl_QPDFTokenizer::~Pl_QPDFTokenizer() // NOLINT (modernize-use-equals-default) { // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer } diff --git a/libqpdf/Pl_RunLength.cc b/libqpdf/Pl_RunLength.cc index d1a5e318..0d3bba2c 100644 --- a/libqpdf/Pl_RunLength.cc +++ b/libqpdf/Pl_RunLength.cc @@ -16,7 +16,7 @@ Pl_RunLength::Pl_RunLength(char const* identifier, Pipeline* next, action_e acti { } -Pl_RunLength::~Pl_RunLength() +Pl_RunLength::~Pl_RunLength() // NOLINT (modernize-use-equals-default) { // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer } diff --git a/libqpdf/Pl_StdioFile.cc b/libqpdf/Pl_StdioFile.cc index a95d4898..24e11244 100644 --- a/libqpdf/Pl_StdioFile.cc +++ b/libqpdf/Pl_StdioFile.cc @@ -17,7 +17,7 @@ Pl_StdioFile::Pl_StdioFile(char const* identifier, FILE* f) : { } -Pl_StdioFile::~Pl_StdioFile() +Pl_StdioFile::~Pl_StdioFile() // NOLINT (modernize-use-equals-default) { // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer } diff --git a/libqpdf/Pl_String.cc b/libqpdf/Pl_String.cc index 40c4b56f..9009268a 100644 --- a/libqpdf/Pl_String.cc +++ b/libqpdf/Pl_String.cc @@ -13,7 +13,7 @@ Pl_String::Pl_String(char const* identifier, Pipeline* next, std::string& s) : { } -Pl_String::~Pl_String() +Pl_String::~Pl_String() // NOLINT (modernize-use-equals-default) { // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer } diff --git a/libqpdf/QPDF.cc b/libqpdf/QPDF.cc index 6f718742..396dfe8f 100644 --- a/libqpdf/QPDF.cc +++ b/libqpdf/QPDF.cc @@ -840,7 +840,7 @@ QPDF::read_xrefTable(qpdf_offset_t xref_offset) } if (type == 'f') { // Save deleted items until after we've checked the XRefStm, if any. - deleted_items.push_back(QPDFObjGen(toI(i), f2)); + deleted_items.emplace_back(toI(i), f2); } else { insertXrefEntry(toI(i), 1, f1, f2); } @@ -1343,21 +1343,16 @@ QPDF::readObject( size_t length = 0; try { - std::map<std::string, QPDFObjectHandle> dict = object.getDictAsMap(); + auto length_obj = object.getKey("/Length"); - if (dict.count("/Length") == 0) { - QTC::TC("qpdf", "QPDF stream without length"); - throw damagedPDF(input, offset, "stream dictionary lacks /Length key"); - } - - QPDFObjectHandle length_obj = dict["/Length"]; if (!length_obj.isInteger()) { + if (length_obj.isNull()) { + QTC::TC("qpdf", "QPDF stream without length"); + throw damagedPDF(input, offset, "stream dictionary lacks /Length key"); + } QTC::TC("qpdf", "QPDF stream length not integer"); throw damagedPDF( - input, - offset, - "/Length key in stream dictionary is not " - "an integer"); + input, offset, "/Length key in stream dictionary is not an integer"); } length = toS(length_obj.getUIntValue()); @@ -1487,7 +1482,8 @@ QPDF::readObjectAtOffset( // Special case: if offset is 0, just return null. Some PDF writers, in particular // "Mac OS X 10.7.5 Quartz PDFContext", may store deleted objects in the xref table as - // "0000000000 00000 n", which is not correct, but it won't hurt anything for to ignore these. + // "0000000000 00000 n", which is not correct, but it won't hurt anything for us to ignore + // these. if (offset == 0) { QTC::TC("qpdf", "QPDF bogus 0 offset", 0); warn(damagedPDF(0, "object has offset 0")); @@ -2212,7 +2208,7 @@ QPDF::getVersionAsPDFVersion() minor = QUtil::string_to_int(match[2].str().c_str()); } - return PDFVersion(major, minor, extension_level); + return {major, minor, extension_level}; } std::string @@ -2483,7 +2479,7 @@ QPDF::damagedPDF( qpdf_offset_t offset, std::string const& message) { - return QPDFExc(qpdf_e_damaged_pdf, input->getName(), object, offset, message); + return {qpdf_e_damaged_pdf, input->getName(), object, offset, message}; } // Return an exception of type qpdf_e_damaged_pdf. The object is taken from @@ -2499,7 +2495,7 @@ QPDF::damagedPDF( QPDFExc QPDF::damagedPDF(std::string const& object, qpdf_offset_t offset, std::string const& message) { - return QPDFExc(qpdf_e_damaged_pdf, m->file->getName(), object, offset, message); + return {qpdf_e_damaged_pdf, m->file->getName(), object, offset, message}; } // Return an exception of type qpdf_e_damaged_pdf. The filename is taken from m->file and the diff --git a/libqpdf/QPDFAcroFormDocumentHelper.cc b/libqpdf/QPDFAcroFormDocumentHelper.cc index aca4bf1f..5a54bf75 100644 --- a/libqpdf/QPDFAcroFormDocumentHelper.cc +++ b/libqpdf/QPDFAcroFormDocumentHelper.cc @@ -70,7 +70,7 @@ QPDFAcroFormDocumentHelper::addAndRenameFormFields(std::vector<QPDFObjectHandle> if (seen.add(obj)) { auto kids = obj.getKey("/Kids"); if (kids.isArray()) { - for (auto kid: kids.aitems()) { + for (auto const& kid: kids.aitems()) { queue.push_back(kid); } } @@ -104,7 +104,7 @@ QPDFAcroFormDocumentHelper::addAndRenameFormFields(std::vector<QPDFObjectHandle> } } - for (auto i: fields) { + for (auto const& i: fields) { addFormField(i); } } @@ -165,7 +165,7 @@ QPDFAcroFormDocumentHelper::getFormFields() analyze(); std::vector<QPDFFormFieldObjectHelper> result; for (auto const& iter: m->field_to_annotations) { - result.push_back(this->qpdf.getObject(iter.first)); + result.emplace_back(this->qpdf.getObject(iter.first)); } return result; } @@ -279,7 +279,7 @@ QPDFAcroFormDocumentHelper::analyze() annot.warnIfPossible("this widget annotation is not" " reachable from /AcroForm in the document catalog"); m->annotation_to_field[og] = QPDFFormFieldObjectHelper(annot); - m->field_to_annotations[og].push_back(QPDFAnnotationObjectHelper(annot)); + m->field_to_annotations[og].emplace_back(annot); } } } @@ -342,7 +342,7 @@ QPDFAcroFormDocumentHelper::traverseField( if (is_annotation) { QPDFObjectHandle our_field = (is_field ? field : parent); - m->field_to_annotations[our_field.getObjGen()].push_back(QPDFAnnotationObjectHelper(field)); + m->field_to_annotations[our_field.getObjGen()].emplace_back(field); m->annotation_to_field[og] = QPDFFormFieldObjectHelper(our_field); } @@ -469,19 +469,18 @@ namespace ResourceReplacer( std::map<std::string, std::map<std::string, std::string>> const& dr_map, std::map<std::string, std::map<std::string, std::set<size_t>>> const& rnames); - virtual ~ResourceReplacer() = default; - virtual void handleToken(QPDFTokenizer::Token const&) override; + ~ResourceReplacer() override = default; + void handleToken(QPDFTokenizer::Token const&) override; private: - size_t offset; + size_t offset{0}; std::map<std::string, std::map<size_t, std::string>> to_replace; }; } // namespace ResourceReplacer::ResourceReplacer( std::map<std::string, std::map<std::string, std::string>> const& dr_map, - std::map<std::string, std::map<std::string, std::set<size_t>>> const& rnames) : - offset(0) + std::map<std::string, std::map<std::string, std::set<size_t>>> const& rnames) { // We have: // * dr_map[resource_type][key] == new_key @@ -1019,7 +1018,7 @@ QPDFAcroFormDocumentHelper::fixCopiedAnnotations( to_page.replaceKey("/Annots", QPDFObjectHandle::newArray(new_annots)); addAndRenameFormFields(new_fields); if (added_fields) { - for (auto f: new_fields) { + for (auto const& f: new_fields) { added_fields->insert(f.getObjGen()); } } diff --git a/libqpdf/QPDFCrypto_openssl.cc b/libqpdf/QPDFCrypto_openssl.cc index f82230be..92125b45 100644 --- a/libqpdf/QPDFCrypto_openssl.cc +++ b/libqpdf/QPDFCrypto_openssl.cc @@ -194,7 +194,7 @@ QPDFCrypto_openssl::MD5_digest(MD5_Digest d) std::string QPDFCrypto_openssl::SHA2_digest() { - return std::string(reinterpret_cast<char*>(md_out), sha2_bits / 8); + return {reinterpret_cast<char*>(md_out), sha2_bits / 8}; } void diff --git a/libqpdf/QPDFDocumentHelper.cc b/libqpdf/QPDFDocumentHelper.cc index cdafc5fb..9bda5b52 100644 --- a/libqpdf/QPDFDocumentHelper.cc +++ b/libqpdf/QPDFDocumentHelper.cc @@ -1,6 +1,6 @@ #include <qpdf/QPDFDocumentHelper.hh> -QPDFDocumentHelper::~QPDFDocumentHelper() +QPDFDocumentHelper::~QPDFDocumentHelper() // NOLINT (modernize-use-equals-default) { // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer } diff --git a/libqpdf/QPDFFormFieldObjectHelper.cc b/libqpdf/QPDFFormFieldObjectHelper.cc index 67975451..4f7ca0e1 100644 --- a/libqpdf/QPDFFormFieldObjectHelper.cc +++ b/libqpdf/QPDFFormFieldObjectHelper.cc @@ -481,8 +481,8 @@ namespace std::vector<std::string> opt; double tf; QPDFObjectHandle::Rectangle bbox; - enum { st_top, st_bmc, st_emc, st_end } state; - bool replaced; + enum { st_top, st_bmc, st_emc, st_end } state{st_top}; + bool replaced{false}; }; } // namespace @@ -496,9 +496,7 @@ ValueSetter::ValueSetter( V(V), opt(opt), tf(tf), - bbox(bbox), - state(st_top), - replaced(false) + bbox(bbox) { } @@ -649,34 +647,24 @@ namespace class TfFinder: public QPDFObjectHandle::TokenFilter { public: - TfFinder(); - ~TfFinder() override - { - } + TfFinder() = default; + ~TfFinder() override = default; void handleToken(QPDFTokenizer::Token const&) override; double getTf(); std::string getFontName(); std::string getDA(); private: - double tf; - int tf_idx; + double tf{11.0}; + int tf_idx{-1}; std::string font_name; - double last_num; - int last_num_idx; + double last_num{0.0}; + int last_num_idx{-1}; std::string last_name; std::vector<std::string> DA; }; } // namespace -TfFinder::TfFinder() : - tf(11.0), - tf_idx(-1), - last_num(0.0), - last_num_idx(-1) -{ -} - void TfFinder::handleToken(QPDFTokenizer::Token const& token) { diff --git a/libqpdf/QPDFJob.cc b/libqpdf/QPDFJob.cc index 4c7fdd04..3f3bcbb1 100644 --- a/libqpdf/QPDFJob.cc +++ b/libqpdf/QPDFJob.cc @@ -428,7 +428,7 @@ QPDFJob::parseNumrange(char const* range, int max) } catch (std::runtime_error& e) { usage(e.what()); } - return std::vector<int>(); + return {}; } std::unique_ptr<QPDF> @@ -894,7 +894,7 @@ QPDFJob::doListAttachments(QPDF& pdf) v << " " << i2.first << " -> " << i2.second << "\n"; } v << " all data streams:\n"; - for (auto i2: efoh->getEmbeddedFileStreams().ditems()) { + for (auto const& i2: efoh->getEmbeddedFileStreams().ditems()) { auto efs = QPDFEFStreamObjectHelper(i2.second); v << " " << i2.first << " -> " << efs.getObjectHandle().getObjGen().unparse(',') << "\n"; @@ -1329,7 +1329,7 @@ QPDFJob::doJSONAttachments(Pipeline* p, bool& first, QPDF& pdf) j_names.addDictionaryMember(i2.first, JSON::makeString(i2.second)); } auto j_streams = j_details.addDictionaryMember("streams", JSON::makeDictionary()); - for (auto i2: fsoh->getEmbeddedFileStreams().ditems()) { + for (auto const& i2: fsoh->getEmbeddedFileStreams().ditems()) { auto efs = QPDFEFStreamObjectHelper(i2.second); auto j_stream = j_streams.addDictionaryMember(i2.first, JSON::makeDictionary()); j_stream.addDictionaryMember( @@ -2376,9 +2376,8 @@ QPDFJob::handlePageSpecs(QPDF& pdf, std::vector<std::unique_ptr<QPDF>>& page_hea // Read original pages from the PDF, and parse the page range associated with this // occurrence of the file. - parsed_specs.push_back( - // line-break - QPDFPageData(page_spec.filename, page_spec_qpdfs[page_spec.filename], page_spec.range)); + parsed_specs.emplace_back( + page_spec.filename, page_spec_qpdfs[page_spec.filename], page_spec.range); } std::map<unsigned long long, bool> remove_unreferenced; @@ -2427,9 +2426,8 @@ QPDFJob::handlePageSpecs(QPDF& pdf, std::vector<std::unique_ptr<QPDF>>& page_hea for (size_t j = 0; j < m->collate; ++j) { if (cur_page + j < page_data.selected_pages.size()) { got_pages = true; - new_parsed_specs.push_back( - // line-break - QPDFPageData(page_data, page_data.selected_pages.at(cur_page + j))); + new_parsed_specs.emplace_back( + page_data, page_data.selected_pages.at(cur_page + j)); } } } diff --git a/libqpdf/QPDFJob_argv.cc b/libqpdf/QPDFJob_argv.cc index 4a9addbd..aade34cd 100644 --- a/libqpdf/QPDFJob_argv.cc +++ b/libqpdf/QPDFJob_argv.cc @@ -40,18 +40,15 @@ namespace std::shared_ptr<QPDFJob::UOConfig> c_uo; std::shared_ptr<QPDFJob::EncConfig> c_enc; std::vector<std::string> accumulated_args; - std::shared_ptr<char> pages_password; - bool gave_input; - bool gave_output; + std::shared_ptr<char> pages_password{nullptr}; + bool gave_input{false}; + bool gave_output{false}; }; } // namespace ArgParser::ArgParser(QPDFArgParser& ap, std::shared_ptr<QPDFJob::Config> c_main) : ap(ap), - c_main(c_main), - pages_password(nullptr), - gave_input(false), - gave_output(false) + c_main(c_main) { initOptionTables(); } diff --git a/libqpdf/QPDFJob_config.cc b/libqpdf/QPDFJob_config.cc index e847bcd4..834de9ab 100644 --- a/libqpdf/QPDFJob_config.cc +++ b/libqpdf/QPDFJob_config.cc @@ -942,7 +942,7 @@ QPDFJob::PagesConfig* QPDFJob::PagesConfig::pageSpec( std::string const& filename, std::string const& range, char const* password) { - this->config->o.m->page_specs.push_back(QPDFJob::PageSpec(filename, password, range)); + this->config->o.m->page_specs.emplace_back(filename, password, range); return this; } diff --git a/libqpdf/QPDFJob_json.cc b/libqpdf/QPDFJob_json.cc index 92488df1..95622f36 100644 --- a/libqpdf/QPDFJob_json.cc +++ b/libqpdf/QPDFJob_json.cc @@ -59,7 +59,7 @@ namespace std::list<std::shared_ptr<JSONHandler>> json_handlers; bool partial; - JSONHandler* jh; // points to last of json_handlers + JSONHandler* jh{nullptr}; // points to last of json_handlers std::shared_ptr<QPDFJob::Config> c_main; std::shared_ptr<QPDFJob::CopyAttConfig> c_copy_att; std::shared_ptr<QPDFJob::AttConfig> c_att; @@ -71,7 +71,6 @@ namespace Handlers::Handlers(bool partial, std::shared_ptr<QPDFJob::Config> c_main) : partial(partial), - jh(nullptr), c_main(c_main) { initHandlers(); diff --git a/libqpdf/QPDFLogger.cc b/libqpdf/QPDFLogger.cc index 76c3c70c..a704ea75 100644 --- a/libqpdf/QPDFLogger.cc +++ b/libqpdf/QPDFLogger.cc @@ -12,8 +12,7 @@ namespace { public: Pl_Track(char const* identifier, Pipeline* next) : - Pipeline(identifier, next), - used(false) + Pipeline(identifier, next) { } @@ -37,7 +36,7 @@ namespace } private: - bool used; + bool used{false}; }; }; // namespace diff --git a/libqpdf/QPDFMatrix.cc b/libqpdf/QPDFMatrix.cc index a54b4370..f38d7644 100644 --- a/libqpdf/QPDFMatrix.cc +++ b/libqpdf/QPDFMatrix.cc @@ -57,7 +57,7 @@ QPDFMatrix::unparse() const QPDFObjectHandle::Matrix QPDFMatrix::getAsMatrix() const { - return QPDFObjectHandle::Matrix(a, b, c, d, e, f); + return {a, b, c, d, e, f}; } void @@ -124,11 +124,11 @@ QPDFMatrix::transformRectangle(QPDFObjectHandle::Rectangle r) const transform(r.llx, r.ury, tx.at(1), ty.at(1)); transform(r.urx, r.lly, tx.at(2), ty.at(2)); transform(r.urx, r.ury, tx.at(3), ty.at(3)); - return QPDFObjectHandle::Rectangle( + return { *std::min_element(tx.begin(), tx.end()), *std::min_element(ty.begin(), ty.end()), *std::max_element(tx.begin(), tx.end()), - *std::max_element(ty.begin(), ty.end())); + *std::max_element(ty.begin(), ty.end())}; } bool diff --git a/libqpdf/QPDFNameTreeObjectHelper.cc b/libqpdf/QPDFNameTreeObjectHelper.cc index 5a9992fb..9a2a6284 100644 --- a/libqpdf/QPDFNameTreeObjectHelper.cc +++ b/libqpdf/QPDFNameTreeObjectHelper.cc @@ -34,7 +34,7 @@ namespace static NameTreeDetails name_tree_details; -QPDFNameTreeObjectHelper::~QPDFNameTreeObjectHelper() +QPDFNameTreeObjectHelper::~QPDFNameTreeObjectHelper() // NOLINT (modernize-use-equals-default) { // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer. For this specific // class, see github issue #745. @@ -54,8 +54,7 @@ QPDFNameTreeObjectHelper::QPDFNameTreeObjectHelper(QPDFObjectHandle oh, QPDF& q, QPDFNameTreeObjectHelper QPDFNameTreeObjectHelper::newEmpty(QPDF& qpdf, bool auto_repair) { - return QPDFNameTreeObjectHelper( - qpdf.makeIndirectObject("<< /Names [] >>"_qpdf), qpdf, auto_repair); + return {qpdf.makeIndirectObject("<< /Names [] >>"_qpdf), qpdf, auto_repair}; } QPDFNameTreeObjectHelper::iterator::iterator(std::shared_ptr<NNTreeIterator> const& i) : @@ -135,33 +134,33 @@ QPDFNameTreeObjectHelper::iterator::remove() QPDFNameTreeObjectHelper::iterator QPDFNameTreeObjectHelper::begin() const { - return iterator(std::make_shared<NNTreeIterator>(m->impl->begin())); + return {std::make_shared<NNTreeIterator>(m->impl->begin())}; } QPDFNameTreeObjectHelper::iterator QPDFNameTreeObjectHelper::end() const { - return iterator(std::make_shared<NNTreeIterator>(m->impl->end())); + return {std::make_shared<NNTreeIterator>(m->impl->end())}; } QPDFNameTreeObjectHelper::iterator QPDFNameTreeObjectHelper::last() const { - return iterator(std::make_shared<NNTreeIterator>(m->impl->last())); + return {std::make_shared<NNTreeIterator>(m->impl->last())}; } QPDFNameTreeObjectHelper::iterator QPDFNameTreeObjectHelper::find(std::string const& key, bool return_prev_if_not_found) { auto i = m->impl->find(QPDFObjectHandle::newUnicodeString(key), return_prev_if_not_found); - return iterator(std::make_shared<NNTreeIterator>(i)); + return {std::make_shared<NNTreeIterator>(i)}; } QPDFNameTreeObjectHelper::iterator QPDFNameTreeObjectHelper::insert(std::string const& key, QPDFObjectHandle value) { auto i = m->impl->insert(QPDFObjectHandle::newUnicodeString(key), value); - return iterator(std::make_shared<NNTreeIterator>(i)); + return {std::make_shared<NNTreeIterator>(i)}; } bool diff --git a/libqpdf/QPDFNumberTreeObjectHelper.cc b/libqpdf/QPDFNumberTreeObjectHelper.cc index 95cee9c8..478a1884 100644 --- a/libqpdf/QPDFNumberTreeObjectHelper.cc +++ b/libqpdf/QPDFNumberTreeObjectHelper.cc @@ -35,7 +35,7 @@ namespace static NumberTreeDetails number_tree_details; -QPDFNumberTreeObjectHelper::~QPDFNumberTreeObjectHelper() +QPDFNumberTreeObjectHelper::~QPDFNumberTreeObjectHelper() // NOLINT (modernize-use-equals-default) { // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer. For this specific // class, see github issue #745. @@ -56,8 +56,7 @@ QPDFNumberTreeObjectHelper::QPDFNumberTreeObjectHelper( QPDFNumberTreeObjectHelper QPDFNumberTreeObjectHelper::newEmpty(QPDF& qpdf, bool auto_repair) { - return QPDFNumberTreeObjectHelper( - qpdf.makeIndirectObject("<< /Nums [] >>"_qpdf), qpdf, auto_repair); + return {qpdf.makeIndirectObject("<< /Nums [] >>"_qpdf), qpdf, auto_repair}; } QPDFNumberTreeObjectHelper::iterator::iterator(std::shared_ptr<NNTreeIterator> const& i) : @@ -137,33 +136,33 @@ QPDFNumberTreeObjectHelper::iterator::remove() QPDFNumberTreeObjectHelper::iterator QPDFNumberTreeObjectHelper::begin() const { - return iterator(std::make_shared<NNTreeIterator>(m->impl->begin())); + return {std::make_shared<NNTreeIterator>(m->impl->begin())}; } QPDFNumberTreeObjectHelper::iterator QPDFNumberTreeObjectHelper::end() const { - return iterator(std::make_shared<NNTreeIterator>(m->impl->end())); + return {std::make_shared<NNTreeIterator>(m->impl->end())}; } QPDFNumberTreeObjectHelper::iterator QPDFNumberTreeObjectHelper::last() const { - return iterator(std::make_shared<NNTreeIterator>(m->impl->last())); + return {std::make_shared<NNTreeIterator>(m->impl->last())}; } QPDFNumberTreeObjectHelper::iterator QPDFNumberTreeObjectHelper::find(numtree_number key, bool return_prev_if_not_found) { auto i = m->impl->find(QPDFObjectHandle::newInteger(key), return_prev_if_not_found); - return iterator(std::make_shared<NNTreeIterator>(i)); + return {std::make_shared<NNTreeIterator>(i)}; } QPDFNumberTreeObjectHelper::iterator QPDFNumberTreeObjectHelper::insert(numtree_number key, QPDFObjectHandle value) { auto i = m->impl->insert(QPDFObjectHandle::newInteger(key), value); - return iterator(std::make_shared<NNTreeIterator>(i)); + return {std::make_shared<NNTreeIterator>(i)}; } bool diff --git a/libqpdf/QPDFObjectHandle.cc b/libqpdf/QPDFObjectHandle.cc index 3797ad12..3ce748b0 100644 --- a/libqpdf/QPDFObjectHandle.cc +++ b/libqpdf/QPDFObjectHandle.cc @@ -49,7 +49,7 @@ QPDFObjectHandle::StreamDataProvider::StreamDataProvider(bool supports_retry) : { } -QPDFObjectHandle::StreamDataProvider::~StreamDataProvider() +QPDFObjectHandle::StreamDataProvider::~StreamDataProvider() // NOLINT (modernize-use-equals-default) { // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer } @@ -189,13 +189,12 @@ namespace unsigned char getLastChar(); private: - unsigned char last_char; + unsigned char last_char{0}; }; } // namespace LastChar::LastChar(Pipeline* next) : - Pipeline("lastchar", next), - last_char(0) + Pipeline("lastchar", next) { } @@ -752,7 +751,7 @@ QPDFObjectHandle::getValueAsInlineImage(std::string& value) QPDFObjectHandle::QPDFArrayItems QPDFObjectHandle::aitems() { - return QPDFArrayItems(*this); + return *this; } int @@ -826,11 +825,11 @@ QPDFObjectHandle::getArrayAsRectangle() return {}; } } - return Rectangle( + return { std::min(items[0], items[2]), std::min(items[1], items[3]), std::max(items[0], items[2]), - std::max(items[1], items[3])); + std::max(items[1], items[3])}; } return {}; } @@ -848,7 +847,7 @@ QPDFObjectHandle::getArrayAsMatrix() return {}; } } - return Matrix(items[0], items[1], items[2], items[3], items[4], items[5]); + return {items[0], items[1], items[2], items[3], items[4], items[5]}; } return {}; } @@ -959,7 +958,7 @@ QPDFObjectHandle::eraseItemAndGetOld(int at) QPDFObjectHandle::QPDFDictItems QPDFObjectHandle::ditems() { - return QPDFDictItems(*this); + return {*this}; } bool @@ -1049,7 +1048,7 @@ QPDFObjectHandle::makeResourcesIndirect(QPDF& owning_qpdf) if (!sub.isDictionary()) { continue; } - for (auto i2: sub.ditems()) { + for (auto const& i2: sub.ditems()) { std::string const& key = i2.first; QPDFObjectHandle val = i2.second; if (!val.isIndirect()) { @@ -1070,7 +1069,7 @@ QPDFObjectHandle::mergeResources( auto make_og_to_name = [](QPDFObjectHandle& dict, std::map<QPDFObjGen, std::string>& og_to_name) { - for (auto i: dict.ditems()) { + for (auto const& i: dict.ditems()) { if (i.second.isIndirect()) { og_to_name[i.second.getObjGen()] = i.first; } @@ -1079,7 +1078,7 @@ QPDFObjectHandle::mergeResources( // This algorithm is described in comments in QPDFObjectHandle.hh // above the declaration of mergeResources. - for (auto o_top: other.ditems()) { + for (auto const& o_top: other.ditems()) { std::string const& rtype = o_top.first; QPDFObjectHandle other_val = o_top.second; if (hasKey(rtype)) { @@ -1096,7 +1095,7 @@ QPDFObjectHandle::mergeResources( std::set<std::string> rnames; int min_suffix = 1; bool initialized_maps = false; - for (auto ov_iter: other_val.ditems()) { + for (auto const& ov_iter: other_val.ditems()) { std::string const& key = ov_iter.first; QPDFObjectHandle rval = ov_iter.second; if (!this_val.hasKey(key)) { @@ -1862,61 +1861,61 @@ QPDFObjectHandle::getParsedOffset() QPDFObjectHandle QPDFObjectHandle::newBool(bool value) { - return QPDFObjectHandle(QPDF_Bool::create(value)); + return {QPDF_Bool::create(value)}; } QPDFObjectHandle QPDFObjectHandle::newNull() { - return QPDFObjectHandle(QPDF_Null::create()); + return {QPDF_Null::create()}; } QPDFObjectHandle QPDFObjectHandle::newInteger(long long value) { - return QPDFObjectHandle(QPDF_Integer::create(value)); + return {QPDF_Integer::create(value)}; } QPDFObjectHandle QPDFObjectHandle::newReal(std::string const& value) { - return QPDFObjectHandle(QPDF_Real::create(value)); + return {QPDF_Real::create(value)}; } QPDFObjectHandle QPDFObjectHandle::newReal(double value, int decimal_places, bool trim_trailing_zeroes) { - return QPDFObjectHandle(QPDF_Real::create(value, decimal_places, trim_trailing_zeroes)); + return {QPDF_Real::create(value, decimal_places, trim_trailing_zeroes)}; } QPDFObjectHandle QPDFObjectHandle::newName(std::string const& name) { - return QPDFObjectHandle(QPDF_Name::create(name)); + return {QPDF_Name::create(name)}; } QPDFObjectHandle QPDFObjectHandle::newString(std::string const& str) { - return QPDFObjectHandle(QPDF_String::create(str)); + return {QPDF_String::create(str)}; } QPDFObjectHandle QPDFObjectHandle::newUnicodeString(std::string const& utf8_str) { - return QPDFObjectHandle(QPDF_String::create_utf16(utf8_str)); + return {QPDF_String::create_utf16(utf8_str)}; } QPDFObjectHandle QPDFObjectHandle::newOperator(std::string const& value) { - return QPDFObjectHandle(QPDF_Operator::create(value)); + return {QPDF_Operator::create(value)}; } QPDFObjectHandle QPDFObjectHandle::newInlineImage(std::string const& value) { - return QPDFObjectHandle(QPDF_InlineImage::create(value)); + return {QPDF_InlineImage::create(value)}; } QPDFObjectHandle @@ -1928,44 +1927,37 @@ QPDFObjectHandle::newArray() QPDFObjectHandle QPDFObjectHandle::newArray(std::vector<QPDFObjectHandle> const& items) { - return QPDFObjectHandle(QPDF_Array::create(items)); + return {QPDF_Array::create(items)}; } QPDFObjectHandle QPDFObjectHandle::newArray(Rectangle const& rect) { - std::vector<QPDFObjectHandle> items; - items.push_back(newReal(rect.llx)); - items.push_back(newReal(rect.lly)); - items.push_back(newReal(rect.urx)); - items.push_back(newReal(rect.ury)); - return newArray(items); + return newArray({newReal(rect.llx), newReal(rect.lly), newReal(rect.urx), newReal(rect.ury)}); } QPDFObjectHandle QPDFObjectHandle::newArray(Matrix const& matrix) { - std::vector<QPDFObjectHandle> items; - items.push_back(newReal(matrix.a)); - items.push_back(newReal(matrix.b)); - items.push_back(newReal(matrix.c)); - items.push_back(newReal(matrix.d)); - items.push_back(newReal(matrix.e)); - items.push_back(newReal(matrix.f)); - return newArray(items); + return newArray( + {newReal(matrix.a), + newReal(matrix.b), + newReal(matrix.c), + newReal(matrix.d), + newReal(matrix.e), + newReal(matrix.f)}); } QPDFObjectHandle QPDFObjectHandle::newArray(QPDFMatrix const& matrix) { - std::vector<QPDFObjectHandle> items; - items.push_back(newReal(matrix.a)); - items.push_back(newReal(matrix.b)); - items.push_back(newReal(matrix.c)); - items.push_back(newReal(matrix.d)); - items.push_back(newReal(matrix.e)); - items.push_back(newReal(matrix.f)); - return newArray(items); + return newArray( + {newReal(matrix.a), + newReal(matrix.b), + newReal(matrix.c), + newReal(matrix.d), + newReal(matrix.e), + newReal(matrix.f)}); } QPDFObjectHandle @@ -1995,7 +1987,7 @@ QPDFObjectHandle::newDictionary() QPDFObjectHandle QPDFObjectHandle::newDictionary(std::map<std::string, QPDFObjectHandle> const& items) { - return QPDFObjectHandle(QPDF_Dictionary::create(items)); + return {QPDF_Dictionary::create(items)}; } QPDFObjectHandle @@ -2060,7 +2052,7 @@ QPDFObjectHandle::shallowCopy() if (!dereference()) { throw std::logic_error("operation attempted on uninitialized QPDFObjectHandle"); } - return QPDFObjectHandle(obj->copy()); + return {obj->copy()}; } QPDFObjectHandle @@ -2069,7 +2061,7 @@ QPDFObjectHandle::unsafeShallowCopy() if (!dereference()) { throw std::logic_error("operation attempted on uninitialized QPDFObjectHandle"); } - return QPDFObjectHandle(obj->copy(true)); + return {obj->copy(true)}; } void @@ -2471,13 +2463,13 @@ QPDFObjectHandle::QPDFDictItems::iterator::Members::Members(QPDFObjectHandle& oh QPDFObjectHandle::QPDFDictItems::iterator QPDFObjectHandle::QPDFDictItems::begin() { - return iterator(oh, true); + return {oh, true}; } QPDFObjectHandle::QPDFDictItems::iterator QPDFObjectHandle::QPDFDictItems::end() { - return iterator(oh, false); + return {oh, false}; } QPDFObjectHandle::QPDFArrayItems::QPDFArrayItems(QPDFObjectHandle const& oh) : @@ -2551,13 +2543,13 @@ QPDFObjectHandle::QPDFArrayItems::iterator::Members::Members(QPDFObjectHandle& o QPDFObjectHandle::QPDFArrayItems::iterator QPDFObjectHandle::QPDFArrayItems::begin() { - return iterator(oh, true); + return {oh, true}; } QPDFObjectHandle::QPDFArrayItems::iterator QPDFObjectHandle::QPDFArrayItems::end() { - return iterator(oh, false); + return {oh, false}; } QPDFObjGen diff --git a/libqpdf/QPDFObjectHelper.cc b/libqpdf/QPDFObjectHelper.cc index eb7de06e..cbd54f3d 100644 --- a/libqpdf/QPDFObjectHelper.cc +++ b/libqpdf/QPDFObjectHelper.cc @@ -1,6 +1,6 @@ #include <qpdf/QPDFObjectHelper.hh> -QPDFObjectHelper::~QPDFObjectHelper() +QPDFObjectHelper::~QPDFObjectHelper() // NOLINT (modernize-use-equals-default) { // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer } diff --git a/libqpdf/QPDFPageDocumentHelper.cc b/libqpdf/QPDFPageDocumentHelper.cc index 3811d7dd..c9c2cf52 100644 --- a/libqpdf/QPDFPageDocumentHelper.cc +++ b/libqpdf/QPDFPageDocumentHelper.cc @@ -14,7 +14,7 @@ QPDFPageDocumentHelper::getAllPages() { std::vector<QPDFPageObjectHelper> pages; for (auto const& iter: this->qpdf.getAllPages()) { - pages.push_back(QPDFPageObjectHelper(iter)); + pages.emplace_back(iter); } return pages; } diff --git a/libqpdf/QPDFPageObjectHelper.cc b/libqpdf/QPDFPageObjectHelper.cc index 608254e4..fd6e5215 100644 --- a/libqpdf/QPDFPageObjectHelper.cc +++ b/libqpdf/QPDFPageObjectHelper.cc @@ -20,8 +20,8 @@ namespace from_page(from_page) { } - virtual ~ContentProvider() = default; - virtual void provideStreamData(QPDFObjGen const&, Pipeline* pipeline); + ~ContentProvider() override = default; + void provideStreamData(QPDFObjGen const&, Pipeline* pipeline) override; private: QPDFObjectHandle from_page; @@ -44,8 +44,8 @@ namespace { public: InlineImageTracker(QPDF*, size_t min_size, QPDFObjectHandle resources); - virtual ~InlineImageTracker() = default; - virtual void handleToken(QPDFTokenizer::Token const&); + ~InlineImageTracker() override = default; + void handleToken(QPDFTokenizer::Token const&) override; QPDFObjectHandle convertIIDict(QPDFObjectHandle odict); QPDF* qpdf; @@ -53,19 +53,16 @@ namespace QPDFObjectHandle resources; std::string dict_str; std::string bi_str; - int min_suffix; - bool any_images; - enum { st_top, st_bi } state; + int min_suffix{1}; + bool any_images{false}; + enum { st_top, st_bi } state{st_top}; }; } // namespace InlineImageTracker::InlineImageTracker(QPDF* qpdf, size_t min_size, QPDFObjectHandle resources) : qpdf(qpdf), min_size(min_size), - resources(resources), - min_suffix(1), - any_images(false), - state(st_top) + resources(resources) { } @@ -451,7 +448,7 @@ QPDFPageObjectHelper::getAnnotations(std::string const& only_subtype) for (int i = 0; i < nannots; ++i) { QPDFObjectHandle annot = annots.getArrayItem(i); if (annot.isDictionaryOfType("", only_subtype)) { - result.push_back(QPDFAnnotationObjectHelper(annot)); + result.emplace_back(annot); } } } @@ -662,7 +659,7 @@ QPDFPageObjectHelper::shallowCopyPage() QPDF& qpdf = this->oh.getQPDF("QPDFPageObjectHelper::shallowCopyPage called with a direct object"); QPDFObjectHandle new_page = this->oh.shallowCopy(); - return QPDFPageObjectHelper(qpdf.makeIndirectObject(new_page)); + return {qpdf.makeIndirectObject(new_page)}; } QPDFObjectHandle::Matrix @@ -758,7 +755,7 @@ QPDFPageObjectHelper::getMatrixForFormXObjectPlacement( QPDFObjectHandle fdict = fo.getDict(); QPDFObjectHandle bbox_obj = fdict.getKey("/BBox"); if (!bbox_obj.isRectangle()) { - return QPDFMatrix(); + return {}; } QPDFMatrix wmatrix; // work matrix @@ -793,7 +790,7 @@ QPDFPageObjectHelper::getMatrixForFormXObjectPlacement( // Calculate a scale factor, if needed. Shrink or expand if needed and allowed. if ((T.urx == T.llx) || (T.ury == T.lly)) { // avoid division by zero - return QPDFMatrix(); + return {}; } double rect_w = rect.urx - rect.llx; double rect_h = rect.ury - rect.lly; diff --git a/libqpdf/QPDFParser.cc b/libqpdf/QPDFParser.cc index 48227e55..6dcbddb5 100644 --- a/libqpdf/QPDFParser.cc +++ b/libqpdf/QPDFParser.cc @@ -55,7 +55,7 @@ QPDFParser::parse(bool& empty, bool content_stream) bool set_offset = false; std::vector<StackFrame> stack; - stack.push_back(StackFrame(input)); + stack.emplace_back(input); std::vector<parser_state_e> state_stack; state_stack.push_back(st_top); qpdf_offset_t offset; @@ -141,7 +141,7 @@ QPDFParser::parse(bool& empty, bool content_stream) (tokenizer.getType() == QPDFTokenizer::tt_array_open) ? st_array : st_dictionary); b_contents = false; - stack.push_back(StackFrame(input)); + stack.emplace_back(input); } break; diff --git a/libqpdf/QPDFWriter.cc b/libqpdf/QPDFWriter.cc index 50594a09..db3b42e0 100644 --- a/libqpdf/QPDFWriter.cc +++ b/libqpdf/QPDFWriter.cc @@ -26,7 +26,7 @@ #include <cstdlib> #include <stdexcept> -QPDFWriter::ProgressReporter::~ProgressReporter() +QPDFWriter::ProgressReporter::~ProgressReporter() // NOLINT (modernize-use-equals-default) { // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer } @@ -36,7 +36,8 @@ QPDFWriter::FunctionProgressReporter::FunctionProgressReporter(std::function<voi { } -QPDFWriter::FunctionProgressReporter::~FunctionProgressReporter() +QPDFWriter::FunctionProgressReporter::~FunctionProgressReporter() // NOLINT + // (modernize-use-equals-default) { // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer } @@ -2034,29 +2035,25 @@ QPDFWriter::getTrimmedTrailer() return trailer; } +// Make document extension level information direct as required by the spec. void QPDFWriter::prepareFileForWrite() { - // Make document extension level information direct as required by the spec. - m->pdf.fixDanglingReferences(); - QPDFObjectHandle root = m->pdf.getRoot(); - for (auto const& key: root.getKeys()) { - QPDFObjectHandle oh = root.getKey(key); - if ((key == "/Extensions") && (oh.isDictionary())) { - bool extensions_indirect = false; - if (oh.isIndirect()) { - QTC::TC("qpdf", "QPDFWriter make Extensions direct"); - extensions_indirect = true; - oh = root.replaceKeyAndGetNew(key, oh.shallowCopy()); - } - if (oh.hasKey("/ADBE")) { - QPDFObjectHandle adbe = oh.getKey("/ADBE"); - if (adbe.isIndirect()) { - QTC::TC("qpdf", "QPDFWriter make ADBE direct", extensions_indirect ? 0 : 1); - adbe.makeDirect(); - oh.replaceKey("/ADBE", adbe); - } + auto root = m->pdf.getRoot(); + auto oh = root.getKey("/Extensions"); + if (oh.isDictionary()) { + const bool extensions_indirect = oh.isIndirect(); + if (extensions_indirect) { + QTC::TC("qpdf", "QPDFWriter make Extensions direct"); + oh = root.replaceKeyAndGetNew("/Extensions", oh.shallowCopy()); + } + if (oh.hasKey("/ADBE")) { + auto adbe = oh.getKey("/ADBE"); + if (adbe.isIndirect()) { + QTC::TC("qpdf", "QPDFWriter make ADBE direct", extensions_indirect ? 0 : 1); + adbe.makeDirect(); + oh.replaceKey("/ADBE", adbe); } } } diff --git a/libqpdf/QPDFXRefEntry.cc b/libqpdf/QPDFXRefEntry.cc index 7be98b2a..731ad405 100644 --- a/libqpdf/QPDFXRefEntry.cc +++ b/libqpdf/QPDFXRefEntry.cc @@ -3,7 +3,7 @@ #include <qpdf/QIntC.hh> #include <qpdf/QPDFExc.hh> -QPDFXRefEntry::QPDFXRefEntry() +QPDFXRefEntry::QPDFXRefEntry() // NOLINT (modernize-use-equals-default) { } diff --git a/libqpdf/QPDF_Array.cc b/libqpdf/QPDF_Array.cc index 1b78e078..b5b182af 100644 --- a/libqpdf/QPDF_Array.cc +++ b/libqpdf/QPDF_Array.cc @@ -201,7 +201,7 @@ QPDF_Array::getAsVector() const v.reserve(size_t(size())); for (auto const& item: sp_elements) { v.resize(size_t(item.first), null_oh); - v.push_back(item.second); + v.emplace_back(item.second); } v.resize(size_t(size()), null_oh); return v; diff --git a/libqpdf/QPDF_encryption.cc b/libqpdf/QPDF_encryption.cc index 26044500..b5cc44ee 100644 --- a/libqpdf/QPDF_encryption.cc +++ b/libqpdf/QPDF_encryption.cc @@ -164,7 +164,7 @@ pad_or_truncate_password_V4(std::string const& password) { char k1[key_bytes]; pad_or_truncate_password_V4(password, k1); - return std::string(k1, key_bytes); + return {k1, key_bytes}; } static std::string @@ -235,7 +235,7 @@ process_with_aes( } else { outlength = std::min(outlength, bufp->getSize()); } - return std::string(reinterpret_cast<char*>(bufp->getBuffer()), outlength); + return {reinterpret_cast<char*>(bufp->getBuffer()), outlength}; } static std::string @@ -355,7 +355,7 @@ QPDF::compute_data_key( md5.encodeDataIncrementally(result.c_str(), result.length()); MD5::Digest digest; md5.digest(digest); - return std::string(reinterpret_cast<char*>(digest), std::min(result.length(), toS(16))); + return {reinterpret_cast<char*>(digest), std::min(result.length(), toS(16))}; } std::string @@ -401,7 +401,7 @@ QPDF::compute_encryption_key_from_password(std::string const& password, Encrypti MD5::Digest digest; int key_len = std::min(toI(sizeof(digest)), data.getLengthBytes()); iterate_md5_digest(md5, digest, ((data.getR() >= 3) ? 50 : 0), key_len); - return std::string(reinterpret_cast<char*>(digest), toS(key_len)); + return {reinterpret_cast<char*>(digest), toS(key_len)}; } static void @@ -448,7 +448,7 @@ compute_O_value( data.getLengthBytes(), (data.getR() >= 3) ? 20 : 1, false); - return std::string(upass, key_bytes); + return {upass, key_bytes}; } static std::string @@ -467,7 +467,7 @@ compute_U_value_R2(std::string const& user_password, QPDF::EncryptionData const& data.getLengthBytes(), 1, false); - return std::string(udata, key_bytes); + return {udata, key_bytes}; } static std::string @@ -496,7 +496,7 @@ compute_U_value_R3(std::string const& user_password, QPDF::EncryptionData const& for (unsigned int i = sizeof(MD5::Digest); i < key_bytes; ++i) { result[i] = static_cast<char>((i * i) % 0xff); } - return std::string(result, key_bytes); + return {result, key_bytes}; } static std::string diff --git a/libqpdf/QPDF_json.cc b/libqpdf/QPDF_json.cc index c74cf4f7..f8fd689a 100644 --- a/libqpdf/QPDF_json.cc +++ b/libqpdf/QPDF_json.cc @@ -238,7 +238,7 @@ class QPDF::JSONReactor: public JSON::Reactor } } } - virtual ~JSONReactor() = default; + ~JSONReactor() override = default; void dictionaryStart() override; void arrayStart() override; void containerEnd(JSON const& value) override; diff --git a/libqpdf/QPDF_linearization.cc b/libqpdf/QPDF_linearization.cc index faebf5b6..fe25c6d9 100644 --- a/libqpdf/QPDF_linearization.cc +++ b/libqpdf/QPDF_linearization.cc @@ -1367,7 +1367,7 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data) for (auto& oh: m->part6) { int obj = oh.getObjectID(); obj_to_index[obj] = toI(shared.size()); - shared.push_back(CHSharedObjectEntry(obj)); + shared.emplace_back(obj); } QTC::TC("qpdf", "QPDF lin part 8 empty", m->part8.empty() ? 1 : 0); if (!m->part8.empty()) { @@ -1375,7 +1375,7 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data) for (auto& oh: m->part8) { int obj = oh.getObjectID(); obj_to_index[obj] = toI(shared.size()); - shared.push_back(CHSharedObjectEntry(obj)); + shared.emplace_back(obj); } } if (static_cast<size_t>(m->c_shared_object_data.nshared_total) != @@ -1585,7 +1585,7 @@ QPDF::calculateHSharedObject( int length = outputLengthNextN(csoe.at(i).object, 1, lengths, obj_renumber); min_length = std::min(min_length, length); max_length = std::max(max_length, length); - soe.push_back(HSharedObjectEntry()); + soe.emplace_back(); soe.at(i).delta_group_length = length; } if (soe.size() != toS(cso.nshared_total)) { diff --git a/libqpdf/QUtil.cc b/libqpdf/QUtil.cc index 76d6bfd5..0fb03579 100644 --- a/libqpdf/QUtil.cc +++ b/libqpdf/QUtil.cc @@ -903,14 +903,14 @@ QUtil::get_current_qpdf_time() // Don't know how to get timezone on this platform int tzoff = 0; # endif - return QPDFTime( + return { static_cast<int>(ltime.tm_year + 1900), static_cast<int>(ltime.tm_mon + 1), static_cast<int>(ltime.tm_mday), static_cast<int>(ltime.tm_hour), static_cast<int>(ltime.tm_min), static_cast<int>(ltime.tm_sec), - tzoff); + tzoff}; #endif } @@ -1082,13 +1082,12 @@ namespace private: RandomDataProvider* default_provider; - RandomDataProvider* current_provider; + RandomDataProvider* current_provider{nullptr}; }; } // namespace RandomDataProviderProvider::RandomDataProviderProvider() : - default_provider(CryptoRandomDataProvider::getInstance()), - current_provider(nullptr) + default_provider(CryptoRandomDataProvider::getInstance()) { this->current_provider = default_provider; } @@ -1246,7 +1245,7 @@ QUtil::read_lines_from_file( char c; while (next_char(c)) { if (buf == nullptr) { - lines.push_back(""); + lines.emplace_back(""); buf = &(lines.back()); buf->reserve(80); } diff --git a/libqpdf/qpdf-c.cc b/libqpdf/qpdf-c.cc index fe2a608e..1f7b85cb 100644 --- a/libqpdf/qpdf-c.cc +++ b/libqpdf/qpdf-c.cc @@ -813,13 +813,13 @@ trap_oh_errors(qpdf_data qpdf, std::function<RET()> fallback, std::function<RET( if (!qpdf->silence_errors) { QTC::TC("qpdf", "qpdf-c warn about oh error", qpdf->oh_error_occurred ? 0 : 1); if (!qpdf->oh_error_occurred) { - qpdf->warnings.push_back(QPDFExc( + qpdf->warnings.emplace_back( qpdf_e_internal, qpdf->qpdf->getFilename(), "", 0, "C API function caught an exception that it isn't returning; please point the " - "application developer to ERROR HANDLING in qpdf-c.h")); + "application developer to ERROR HANDLING in qpdf-c.h"); qpdf->oh_error_occurred = true; } *QPDFLogger::defaultLogger()->getError() << qpdf->error->what() << "\n"; diff --git a/libqpdf/qpdf/JSONHandler.hh b/libqpdf/qpdf/JSONHandler.hh index 8fdcaee6..653924f6 100644 --- a/libqpdf/qpdf/JSONHandler.hh +++ b/libqpdf/qpdf/JSONHandler.hh @@ -16,7 +16,7 @@ class JSONHandler public: // A QPDFUsage exception is thrown if there are any errors validating the JSON object. JSONHandler(); - ~JSONHandler() = default; + ~JSONHandler(); // Based on the type of handler, expect the object to be of a certain type. QPDFUsage is thrown // otherwise. Multiple handlers may be registered, which allows the object to be of various @@ -53,51 +53,10 @@ class JSONHandler static void usage(std::string const& msg); - struct Handlers - { - Handlers() : - any_handler(nullptr), - null_handler(nullptr), - string_handler(nullptr), - number_handler(nullptr), - bool_handler(nullptr), - dict_start_handler(nullptr), - dict_end_handler(nullptr), - array_start_handler(nullptr), - array_end_handler(nullptr), - final_handler(nullptr) - { - } - - json_handler_t any_handler; - void_handler_t null_handler; - string_handler_t string_handler; - string_handler_t number_handler; - bool_handler_t bool_handler; - json_handler_t dict_start_handler; - void_handler_t dict_end_handler; - json_handler_t array_start_handler; - void_handler_t array_end_handler; - void_handler_t final_handler; - std::map<std::string, std::shared_ptr<JSONHandler>> dict_handlers; - std::shared_ptr<JSONHandler> fallback_dict_handler; - std::shared_ptr<JSONHandler> array_item_handler; - }; - - class Members - { - friend class JSONHandler; - - public: - ~Members() = default; - - private: - Members() = default; - Members(Members const&) = delete; - - Handlers h; - }; - std::shared_ptr<Members> m; + + class Members; + + std::unique_ptr<Members> m; }; #endif // JSONHANDLER_HH diff --git a/libqpdf/qpdf/Pl_LZWDecoder.hh b/libqpdf/qpdf/Pl_LZWDecoder.hh index b2135aa9..792fa8ef 100644 --- a/libqpdf/qpdf/Pl_LZWDecoder.hh +++ b/libqpdf/qpdf/Pl_LZWDecoder.hh @@ -10,9 +10,9 @@ class Pl_LZWDecoder: public Pipeline { public: Pl_LZWDecoder(char const* identifier, Pipeline* next, bool early_code_change); - virtual ~Pl_LZWDecoder() = default; - virtual void write(unsigned char const* buf, size_t len); - virtual void finish(); + ~Pl_LZWDecoder() override = default; + void write(unsigned char const* buf, size_t len) override; + void finish() override; private: void sendNextCode(); diff --git a/libqpdf/qpdf/Pl_MD5.hh b/libqpdf/qpdf/Pl_MD5.hh index 5763d6eb..fb9a2184 100644 --- a/libqpdf/qpdf/Pl_MD5.hh +++ b/libqpdf/qpdf/Pl_MD5.hh @@ -14,9 +14,9 @@ class Pl_MD5: public Pipeline { public: Pl_MD5(char const* identifier, Pipeline* next); - virtual ~Pl_MD5() = default; - virtual void write(unsigned char const*, size_t); - virtual void finish(); + ~Pl_MD5() override = default; + void write(unsigned char const*, size_t) override; + void finish() override; std::string getHexDigest(); // Enable/disable. Disabling the pipeline causes it to become a pass-through. This makes it // possible to stick an MD5 pipeline in a pipeline when it may or may not be required. Disabling diff --git a/libqpdf/qpdf/QPDFArgParser.hh b/libqpdf/qpdf/QPDFArgParser.hh index 3b22a805..ed161d53 100644 --- a/libqpdf/qpdf/QPDFArgParser.hh +++ b/libqpdf/qpdf/QPDFArgParser.hh @@ -145,19 +145,12 @@ class QPDFArgParser private: struct OptionEntry { - OptionEntry() : - parameter_needed(false), - bare_arg_handler(nullptr), - param_arg_handler(nullptr), - invalid_choice_handler(nullptr) - { - } - bool parameter_needed; + bool parameter_needed{false}; std::string parameter_name; std::set<std::string> choices; - bare_arg_handler_t bare_arg_handler; - param_arg_handler_t param_arg_handler; - param_arg_handler_t invalid_choice_handler; + bare_arg_handler_t bare_arg_handler{nullptr}; + param_arg_handler_t param_arg_handler{nullptr}; + param_arg_handler_t invalid_choice_handler{nullptr}; }; typedef std::map<std::string, OptionEntry> option_table_t; diff --git a/libqpdf/qpdf/QPDF_Array.hh b/libqpdf/qpdf/QPDF_Array.hh index 51a366a6..10ac9f8c 100644 --- a/libqpdf/qpdf/QPDF_Array.hh +++ b/libqpdf/qpdf/QPDF_Array.hh @@ -9,14 +9,14 @@ class QPDF_Array: public QPDFValue { public: - virtual ~QPDF_Array() = default; + ~QPDF_Array() override = default; static std::shared_ptr<QPDFObject> create(std::vector<QPDFObjectHandle> const& items); static std::shared_ptr<QPDFObject> create(std::vector<std::shared_ptr<QPDFObject>>&& items, bool sparse); - virtual std::shared_ptr<QPDFObject> copy(bool shallow = false); - virtual std::string unparse(); - virtual JSON getJSON(int json_version); - virtual void disconnect(); + std::shared_ptr<QPDFObject> copy(bool shallow = false) override; + std::string unparse() override; + JSON getJSON(int json_version) override; + void disconnect() override; int size() const noexcept diff --git a/libqpdf/qpdf/QPDF_Bool.hh b/libqpdf/qpdf/QPDF_Bool.hh index 215d359a..0b4a71fd 100644 --- a/libqpdf/qpdf/QPDF_Bool.hh +++ b/libqpdf/qpdf/QPDF_Bool.hh @@ -6,11 +6,11 @@ class QPDF_Bool: public QPDFValue { public: - virtual ~QPDF_Bool() = default; + ~QPDF_Bool() override = default; static std::shared_ptr<QPDFObject> create(bool val); - virtual std::shared_ptr<QPDFObject> copy(bool shallow = false); - virtual std::string unparse(); - virtual JSON getJSON(int json_version); + std::shared_ptr<QPDFObject> copy(bool shallow = false) override; + std::string unparse() override; + JSON getJSON(int json_version) override; bool getVal() const; private: diff --git a/libqpdf/qpdf/QPDF_Destroyed.hh b/libqpdf/qpdf/QPDF_Destroyed.hh index c8e35557..72e9130a 100644 --- a/libqpdf/qpdf/QPDF_Destroyed.hh +++ b/libqpdf/qpdf/QPDF_Destroyed.hh @@ -6,10 +6,10 @@ class QPDF_Destroyed: public QPDFValue { public: - virtual ~QPDF_Destroyed() = default; - virtual std::shared_ptr<QPDFObject> copy(bool shallow = false); - virtual std::string unparse(); - virtual JSON getJSON(int json_version); + ~QPDF_Destroyed() override = default; + std::shared_ptr<QPDFObject> copy(bool shallow = false) override; + std::string unparse() override; + JSON getJSON(int json_version) override; static std::shared_ptr<QPDFValue> getInstance(); private: diff --git a/libqpdf/qpdf/QPDF_Dictionary.hh b/libqpdf/qpdf/QPDF_Dictionary.hh index da38db7a..0fb6636e 100644 --- a/libqpdf/qpdf/QPDF_Dictionary.hh +++ b/libqpdf/qpdf/QPDF_Dictionary.hh @@ -11,13 +11,13 @@ class QPDF_Dictionary: public QPDFValue { public: - virtual ~QPDF_Dictionary() = default; + ~QPDF_Dictionary() override = default; static std::shared_ptr<QPDFObject> create(std::map<std::string, QPDFObjectHandle> const& items); static std::shared_ptr<QPDFObject> create(std::map<std::string, QPDFObjectHandle>&& items); - virtual std::shared_ptr<QPDFObject> copy(bool shallow = false); - virtual std::string unparse(); - virtual JSON getJSON(int json_version); - virtual void disconnect(); + std::shared_ptr<QPDFObject> copy(bool shallow = false) override; + std::string unparse() override; + JSON getJSON(int json_version) override; + void disconnect() override; // hasKey() and getKeys() treat keys with null values as if they aren't there. getKey() returns // null for the value of a non-existent key. This is as per the PDF spec. diff --git a/libqpdf/qpdf/QPDF_InlineImage.hh b/libqpdf/qpdf/QPDF_InlineImage.hh index 553d1d71..bee12354 100644 --- a/libqpdf/qpdf/QPDF_InlineImage.hh +++ b/libqpdf/qpdf/QPDF_InlineImage.hh @@ -6,13 +6,13 @@ class QPDF_InlineImage: public QPDFValue { public: - virtual ~QPDF_InlineImage() = default; + ~QPDF_InlineImage() override = default; static std::shared_ptr<QPDFObject> create(std::string const& val); - virtual std::shared_ptr<QPDFObject> copy(bool shallow = false); - virtual std::string unparse(); - virtual JSON getJSON(int json_version); - virtual std::string - getStringValue() const + std::shared_ptr<QPDFObject> copy(bool shallow = false) override; + std::string unparse() override; + JSON getJSON(int json_version) override; + std::string + getStringValue() const override { return val; } diff --git a/libqpdf/qpdf/QPDF_Integer.hh b/libqpdf/qpdf/QPDF_Integer.hh index 180bb48a..2c2cf2f9 100644 --- a/libqpdf/qpdf/QPDF_Integer.hh +++ b/libqpdf/qpdf/QPDF_Integer.hh @@ -6,11 +6,11 @@ class QPDF_Integer: public QPDFValue { public: - virtual ~QPDF_Integer() = default; + ~QPDF_Integer() override = default; static std::shared_ptr<QPDFObject> create(long long value); - virtual std::shared_ptr<QPDFObject> copy(bool shallow = false); - virtual std::string unparse(); - virtual JSON getJSON(int json_version); + std::shared_ptr<QPDFObject> copy(bool shallow = false) override; + std::string unparse() override; + JSON getJSON(int json_version) override; long long getVal() const; private: diff --git a/libqpdf/qpdf/QPDF_Name.hh b/libqpdf/qpdf/QPDF_Name.hh index 136ad5cb..c14d8659 100644 --- a/libqpdf/qpdf/QPDF_Name.hh +++ b/libqpdf/qpdf/QPDF_Name.hh @@ -6,16 +6,16 @@ class QPDF_Name: public QPDFValue { public: - virtual ~QPDF_Name() = default; + ~QPDF_Name() override = default; static std::shared_ptr<QPDFObject> create(std::string const& name); - virtual std::shared_ptr<QPDFObject> copy(bool shallow = false); - virtual std::string unparse(); - virtual JSON getJSON(int json_version); + std::shared_ptr<QPDFObject> copy(bool shallow = false) override; + std::string unparse() override; + JSON getJSON(int json_version) override; // Put # into strings with characters unsuitable for name token static std::string normalizeName(std::string const& name); - virtual std::string - getStringValue() const + std::string + getStringValue() const override { return name; } diff --git a/libqpdf/qpdf/QPDF_Null.hh b/libqpdf/qpdf/QPDF_Null.hh index 2bbb3db5..a59b7509 100644 --- a/libqpdf/qpdf/QPDF_Null.hh +++ b/libqpdf/qpdf/QPDF_Null.hh @@ -6,7 +6,7 @@ class QPDF_Null: public QPDFValue { public: - virtual ~QPDF_Null() = default; + ~QPDF_Null() override = default; static std::shared_ptr<QPDFObject> create(); static std::shared_ptr<QPDFObject> create( std::shared_ptr<QPDFObject> parent, @@ -16,9 +16,9 @@ class QPDF_Null: public QPDFValue std::shared_ptr<QPDFValue> parent, std::string_view const& static_descr, std::string var_descr); - virtual std::shared_ptr<QPDFObject> copy(bool shallow = false); - virtual std::string unparse(); - virtual JSON getJSON(int json_version); + std::shared_ptr<QPDFObject> copy(bool shallow = false) override; + std::string unparse() override; + JSON getJSON(int json_version) override; private: QPDF_Null(); diff --git a/libqpdf/qpdf/QPDF_Operator.hh b/libqpdf/qpdf/QPDF_Operator.hh index 4fedb808..77aa5a17 100644 --- a/libqpdf/qpdf/QPDF_Operator.hh +++ b/libqpdf/qpdf/QPDF_Operator.hh @@ -6,13 +6,13 @@ class QPDF_Operator: public QPDFValue { public: - virtual ~QPDF_Operator() = default; + ~QPDF_Operator() override = default; static std::shared_ptr<QPDFObject> create(std::string const& val); - virtual std::shared_ptr<QPDFObject> copy(bool shallow = false); - virtual std::string unparse(); - virtual JSON getJSON(int json_version); - virtual std::string - getStringValue() const + std::shared_ptr<QPDFObject> copy(bool shallow = false) override; + std::string unparse() override; + JSON getJSON(int json_version) override; + std::string + getStringValue() const override { return val; } diff --git a/libqpdf/qpdf/QPDF_Real.hh b/libqpdf/qpdf/QPDF_Real.hh index f470e1a6..db5e0940 100644 --- a/libqpdf/qpdf/QPDF_Real.hh +++ b/libqpdf/qpdf/QPDF_Real.hh @@ -6,15 +6,15 @@ class QPDF_Real: public QPDFValue { public: - virtual ~QPDF_Real() = default; + ~QPDF_Real() override = default; static std::shared_ptr<QPDFObject> create(std::string const& val); static std::shared_ptr<QPDFObject> create(double value, int decimal_places, bool trim_trailing_zeroes); - virtual std::shared_ptr<QPDFObject> copy(bool shallow = false); - virtual std::string unparse(); - virtual JSON getJSON(int json_version); - virtual std::string - getStringValue() const + std::shared_ptr<QPDFObject> copy(bool shallow = false) override; + std::string unparse() override; + JSON getJSON(int json_version) override; + std::string + getStringValue() const override { return val; } diff --git a/libqpdf/qpdf/QPDF_Reserved.hh b/libqpdf/qpdf/QPDF_Reserved.hh index 8d6c74f8..9ba855b7 100644 --- a/libqpdf/qpdf/QPDF_Reserved.hh +++ b/libqpdf/qpdf/QPDF_Reserved.hh @@ -6,11 +6,11 @@ class QPDF_Reserved: public QPDFValue { public: - virtual ~QPDF_Reserved() = default; + ~QPDF_Reserved() override = default; static std::shared_ptr<QPDFObject> create(); - virtual std::shared_ptr<QPDFObject> copy(bool shallow = false); - virtual std::string unparse(); - virtual JSON getJSON(int json_version); + std::shared_ptr<QPDFObject> copy(bool shallow = false) override; + std::string unparse() override; + JSON getJSON(int json_version) override; private: QPDF_Reserved(); diff --git a/libqpdf/qpdf/QPDF_Stream.hh b/libqpdf/qpdf/QPDF_Stream.hh index 88331201..8488e157 100644 --- a/libqpdf/qpdf/QPDF_Stream.hh +++ b/libqpdf/qpdf/QPDF_Stream.hh @@ -16,19 +16,19 @@ class QPDF; class QPDF_Stream: public QPDFValue { public: - virtual ~QPDF_Stream() = default; + ~QPDF_Stream() override = default; static std::shared_ptr<QPDFObject> create( QPDF*, QPDFObjGen const& og, QPDFObjectHandle stream_dict, qpdf_offset_t offset, size_t length); - virtual std::shared_ptr<QPDFObject> copy(bool shallow = false); - virtual std::string unparse(); - virtual JSON getJSON(int json_version); - virtual void setDescription( - QPDF*, std::shared_ptr<QPDFValue::Description>& description, qpdf_offset_t offset); - virtual void disconnect(); + std::shared_ptr<QPDFObject> copy(bool shallow = false) override; + std::string unparse() override; + JSON getJSON(int json_version) override; + void setDescription( + QPDF*, std::shared_ptr<QPDFValue::Description>& description, qpdf_offset_t offset) override; + void disconnect() override; QPDFObjectHandle getDict() const; bool isDataModified() const; void setFilterOnWrite(bool); diff --git a/libqpdf/qpdf/QPDF_String.hh b/libqpdf/qpdf/QPDF_String.hh index d4a1bfd4..c34cafef 100644 --- a/libqpdf/qpdf/QPDF_String.hh +++ b/libqpdf/qpdf/QPDF_String.hh @@ -10,16 +10,16 @@ class QPDF_String: public QPDFValue friend class QPDFWriter; public: - virtual ~QPDF_String() = default; + ~QPDF_String() override = default; static std::shared_ptr<QPDFObject> create(std::string const& val); static std::shared_ptr<QPDFObject> create_utf16(std::string const& utf8_val); - virtual std::shared_ptr<QPDFObject> copy(bool shallow = false); - virtual std::string unparse(); + std::shared_ptr<QPDFObject> copy(bool shallow = false) override; + std::string unparse() override; std::string unparse(bool force_binary); - virtual JSON getJSON(int json_version); + JSON getJSON(int json_version) override; std::string getUTF8Val() const; - virtual std::string - getStringValue() const + std::string + getStringValue() const override { return val; } diff --git a/libqpdf/qpdf/QPDF_Unresolved.hh b/libqpdf/qpdf/QPDF_Unresolved.hh index 43d2af31..0a1fa9a5 100644 --- a/libqpdf/qpdf/QPDF_Unresolved.hh +++ b/libqpdf/qpdf/QPDF_Unresolved.hh @@ -6,11 +6,11 @@ class QPDF_Unresolved: public QPDFValue { public: - virtual ~QPDF_Unresolved() = default; + ~QPDF_Unresolved() override = default; static std::shared_ptr<QPDFObject> create(QPDF* qpdf, QPDFObjGen const& og); - virtual std::shared_ptr<QPDFObject> copy(bool shallow = false); - virtual std::string unparse(); - virtual JSON getJSON(int json_version); + std::shared_ptr<QPDFObject> copy(bool shallow = false) override; + std::string unparse() override; + JSON getJSON(int json_version) override; private: QPDF_Unresolved(QPDF* qpdf, QPDFObjGen const& og); diff --git a/libqpdf/qpdf/ResourceFinder.hh b/libqpdf/qpdf/ResourceFinder.hh index d8cb32e6..1c4c59a7 100644 --- a/libqpdf/qpdf/ResourceFinder.hh +++ b/libqpdf/qpdf/ResourceFinder.hh @@ -7,7 +7,7 @@ class ResourceFinder: public QPDFObjectHandle::ParserCallbacks { public: ResourceFinder(); - virtual ~ResourceFinder() = default; + ~ResourceFinder() override = default; void handleObject(QPDFObjectHandle, size_t, size_t) override; void handleEOF() override; std::set<std::string> const& getNames() const; diff --git a/libqpdf/qpdf/SF_ASCII85Decode.hh b/libqpdf/qpdf/SF_ASCII85Decode.hh index 8cf85e66..d474904c 100644 --- a/libqpdf/qpdf/SF_ASCII85Decode.hh +++ b/libqpdf/qpdf/SF_ASCII85Decode.hh @@ -9,7 +9,7 @@ class SF_ASCII85Decode: public QPDFStreamFilter { public: SF_ASCII85Decode() = default; - virtual ~SF_ASCII85Decode() = default; + ~SF_ASCII85Decode() override = default; Pipeline* getDecodePipeline(Pipeline* next) override diff --git a/libqpdf/qpdf/SF_ASCIIHexDecode.hh b/libqpdf/qpdf/SF_ASCIIHexDecode.hh index cd87761e..bb21ede6 100644 --- a/libqpdf/qpdf/SF_ASCIIHexDecode.hh +++ b/libqpdf/qpdf/SF_ASCIIHexDecode.hh @@ -9,7 +9,7 @@ class SF_ASCIIHexDecode: public QPDFStreamFilter { public: SF_ASCIIHexDecode() = default; - virtual ~SF_ASCIIHexDecode() = default; + ~SF_ASCIIHexDecode() override = default; Pipeline* getDecodePipeline(Pipeline* next) override diff --git a/libqpdf/qpdf/SF_DCTDecode.hh b/libqpdf/qpdf/SF_DCTDecode.hh index 997ba89a..619cf9c4 100644 --- a/libqpdf/qpdf/SF_DCTDecode.hh +++ b/libqpdf/qpdf/SF_DCTDecode.hh @@ -9,7 +9,7 @@ class SF_DCTDecode: public QPDFStreamFilter { public: SF_DCTDecode() = default; - virtual ~SF_DCTDecode() = default; + ~SF_DCTDecode() override = default; Pipeline* getDecodePipeline(Pipeline* next) override diff --git a/libqpdf/qpdf/SF_FlateLzwDecode.hh b/libqpdf/qpdf/SF_FlateLzwDecode.hh index 2230ec58..203d893b 100644 --- a/libqpdf/qpdf/SF_FlateLzwDecode.hh +++ b/libqpdf/qpdf/SF_FlateLzwDecode.hh @@ -9,10 +9,10 @@ class SF_FlateLzwDecode: public QPDFStreamFilter { public: SF_FlateLzwDecode(bool lzw); - virtual ~SF_FlateLzwDecode() = default; + ~SF_FlateLzwDecode() override = default; - virtual bool setDecodeParms(QPDFObjectHandle decode_parms); - virtual Pipeline* getDecodePipeline(Pipeline* next); + bool setDecodeParms(QPDFObjectHandle decode_parms) override; + Pipeline* getDecodePipeline(Pipeline* next) override; static std::shared_ptr<QPDFStreamFilter> flate_factory(); static std::shared_ptr<QPDFStreamFilter> lzw_factory(); diff --git a/libqpdf/qpdf/SF_RunLengthDecode.hh b/libqpdf/qpdf/SF_RunLengthDecode.hh index 83c498dc..4a51cf6f 100644 --- a/libqpdf/qpdf/SF_RunLengthDecode.hh +++ b/libqpdf/qpdf/SF_RunLengthDecode.hh @@ -9,7 +9,7 @@ class SF_RunLengthDecode: public QPDFStreamFilter { public: SF_RunLengthDecode() = default; - virtual ~SF_RunLengthDecode() = default; + ~SF_RunLengthDecode() override = default; Pipeline* getDecodePipeline(Pipeline* next) override diff --git a/libqpdf/qpdf/SecureRandomDataProvider.hh b/libqpdf/qpdf/SecureRandomDataProvider.hh index d701a905..f6a29b76 100644 --- a/libqpdf/qpdf/SecureRandomDataProvider.hh +++ b/libqpdf/qpdf/SecureRandomDataProvider.hh @@ -7,8 +7,8 @@ class SecureRandomDataProvider: public RandomDataProvider { public: SecureRandomDataProvider() = default; - virtual ~SecureRandomDataProvider() = default; - virtual void provideRandomData(unsigned char* data, size_t len); + ~SecureRandomDataProvider() override = default; + void provideRandomData(unsigned char* data, size_t len) override; static RandomDataProvider* getInstance(); }; diff --git a/libtests/arg_parser.cc b/libtests/arg_parser.cc index fde00520..ad9d85e9 100644 --- a/libtests/arg_parser.cc +++ b/libtests/arg_parser.cc @@ -28,12 +28,11 @@ class ArgParser void output(std::string const&); QPDFArgParser ap; - int quacks; + int quacks{0}; }; ArgParser::ArgParser(int argc, char* argv[]) : - ap(QPDFArgParser(argc, argv, "TEST_ARG_PARSER")), - quacks(0) + ap(QPDFArgParser(argc, argv, "TEST_ARG_PARSER")) { initOptions(); } diff --git a/libtests/dct_compress.cc b/libtests/dct_compress.cc index 3f7c86a1..8f7e0913 100644 --- a/libtests/dct_compress.cc +++ b/libtests/dct_compress.cc @@ -10,21 +10,17 @@ static void usage() { - std::cerr << "Usage: dct_compress infile outfile width height" - << " {rgb|cmyk|gray}" << std::endl; + std::cerr << "Usage: dct_compress infile outfile width height {rgb|cmyk|gray}" << std::endl; exit(2); } class Callback: public Pl_DCT::CompressConfig { public: - Callback() : - called(false) - { - } + Callback() = default; ~Callback() override = default; void apply(jpeg_compress_struct*) override; - bool called; + bool called{false}; }; void diff --git a/libtests/json_parse.cc b/libtests/json_parse.cc index 35abb68f..757b698b 100644 --- a/libtests/json_parse.cc +++ b/libtests/json_parse.cc @@ -10,7 +10,7 @@ namespace class Reactor: public JSON::Reactor { public: - virtual ~Reactor() = default; + ~Reactor() override = default; void dictionaryStart() override; void arrayStart() override; void containerEnd(JSON const& value) override; diff --git a/libtests/random.cc b/libtests/random.cc index 899c264c..afd2ed6c 100644 --- a/libtests/random.cc +++ b/libtests/random.cc @@ -6,10 +6,10 @@ class BogusRandomDataProvider: public RandomDataProvider { public: - virtual ~BogusRandomDataProvider() = default; + ~BogusRandomDataProvider() override = default; BogusRandomDataProvider() = default; - virtual void - provideRandomData(unsigned char* data, size_t len) + void + provideRandomData(unsigned char* data, size_t len) override { for (size_t i = 0; i < len; ++i) { data[i] = static_cast<unsigned char>(i & 0xff); diff --git a/manual/contributing.rst b/manual/contributing.rst index 0fb376e6..e0565872 100644 --- a/manual/contributing.rst +++ b/manual/contributing.rst @@ -20,11 +20,14 @@ https://github.com/qpdf/qpdf/discussions. Code Formatting --------------- -The qpdf source code is formatting using clang-format ≥ version 15 -with a :file:`.clang-format` file at the top of the source tree. The +.. The minimum clang-format version is also in format-code. There is a + comment there that references this file. + +The qpdf source code is formatted using clang-format with a +:file:`.clang-format` file at the top of the source tree. The :file:`format-code` script reformats all the source code in the -repository. You must have ``clang-format`` in your path, and it must be -at least version 15. +repository. You must have ``clang-format`` in your path, and it must +be at least version 16. For emacs users, the :file:`.dir-locals.el` file configures emacs ``cc-mode`` for an indentation style that is similar to but not diff --git a/manual/installation.rst b/manual/installation.rst index 7b57ef2a..52578dc2 100644 --- a/manual/installation.rst +++ b/manual/installation.rst @@ -277,6 +277,16 @@ BUILD_SHARED_LIBS, BUILD_STATIC_LIBS compiled executables can find the DLL. Updating your path is not necessary if you build with static libraries only. +FUTURE + This option enables changes planned for the next major release to be + included. They are NOT part of the stable API. These changes are ABI + breaking and are subject to change, which means code linked against + a qpdf built with this option may not be binary compatible with + installed qpdf libraries. Set this if you want to test your code + with proposed QPDF API changes and provide feedback prior to the + inclusion of those changes in a release. Packagers should never + distribute backages built with this option. + QTEST_COLOR Turn this on or off to control whether qtest uses color in its output. diff --git a/manual/packaging.rst b/manual/packaging.rst index 1bd89758..ca32554a 100644 --- a/manual/packaging.rst +++ b/manual/packaging.rst @@ -26,6 +26,12 @@ particularly useful to packagers. combined with either ``ctest --verbose`` or ``ctest --output-on-failure``. +- Packagers should never define the ``FUTURE`` build option. API + changes enabled by ``FUTURE`` are not stable and may be + API/ABI-breaking. That option is intended only for people who are + testing their code with a local build of qpdf to provide early + feedback or prepare for possible future changes to the API. + - qpdf's install targets do not install completion files by default since there is no standard location for them. As a packager, it's good if you install them wherever your distribution expects such diff --git a/manual/release-notes.rst b/manual/release-notes.rst index dcb626f2..806c5e6e 100644 --- a/manual/release-notes.rst +++ b/manual/release-notes.rst @@ -6,6 +6,10 @@ Release Notes For a detailed list of changes, please see the file :file:`ChangeLog` in the source distribution. +If you are a developer and want to test your code against future API +changes that are under consideration, you can build qpdf locally and +enable the ``FUTURE`` build option (see :ref:`build-options`). + Planned changes for future 12.x (subject to change): - ``QPDFObjectHandle`` will support move construction/assignment. This change will be invisible to most developers but may break diff --git a/qpdf/fix-qdf.cc b/qpdf/fix-qdf.cc index 60163b4f..5a399b48 100644 --- a/qpdf/fix-qdf.cc +++ b/qpdf/fix-qdf.cc @@ -46,42 +46,29 @@ class QdfFixer st_before_trailer, st_in_trailer, st_done, - } state; + } state{st_top}; - size_t lineno; - qpdf_offset_t offset; - qpdf_offset_t last_offset; - int last_obj; + size_t lineno{0}; + qpdf_offset_t offset{0}; + qpdf_offset_t last_offset{0}; + int last_obj{0}; std::vector<QPDFXRefEntry> xref; - qpdf_offset_t stream_start; - size_t stream_length; - qpdf_offset_t xref_offset; - size_t xref_f1_nbytes; - size_t xref_f2_nbytes; - size_t xref_size; + qpdf_offset_t stream_start{0}; + size_t stream_length{0}; + qpdf_offset_t xref_offset{0}; + size_t xref_f1_nbytes{0}; + size_t xref_f2_nbytes{0}; + size_t xref_size{0}; std::vector<std::string_view> ostream; std::vector<qpdf_offset_t> ostream_offsets; std::vector<std::string_view> ostream_discarded; - size_t ostream_idx; - int ostream_id; + size_t ostream_idx{0}; + int ostream_id{0}; std::string ostream_extends; }; QdfFixer::QdfFixer(std::string const& filename) : - filename(filename), - state(st_top), - lineno(0), - offset(0), - last_offset(0), - last_obj(0), - stream_start(0), - stream_length(0), - xref_offset(0), - xref_f1_nbytes(0), - xref_f2_nbytes(0), - xref_size(0), - ostream_idx(0), - ostream_id(0) + filename(filename) { } diff --git a/qpdf/qtest/qpdf/issue-100.out b/qpdf/qtest/qpdf/issue-100.out index 3676f1aa..81b8a7e0 100644 --- a/qpdf/qtest/qpdf/issue-100.out +++ b/qpdf/qtest/qpdf/issue-100.out @@ -9,7 +9,7 @@ WARNING: issue-100.pdf (object 5 0, offset 297): unknown token while reading obj WARNING: issue-100.pdf (object 5 0, offset 304): unknown token while reading object; treating as string WARNING: issue-100.pdf (object 5 0, offset 304): too many errors; giving up on reading object WARNING: issue-100.pdf (object 5 0, offset 308): expected endobj -WARNING: issue-100.pdf (object 5 0, offset 418): /Length key in stream dictionary is not an integer +WARNING: issue-100.pdf (object 5 0, offset 418): stream dictionary lacks /Length key WARNING: issue-100.pdf (object 5 0, offset 489): attempting to recover stream length WARNING: issue-100.pdf (object 5 0, offset 489): recovered stream length: 12 WARNING: issue-100.pdf (trailer, offset 953): expected dictionary key but found non-name object; inserting key /QPDFFake1 diff --git a/qpdf/qtest/qpdf/issue-117.out b/qpdf/qtest/qpdf/issue-117.out index 540b9c3c..1aa80144 100644 --- a/qpdf/qtest/qpdf/issue-117.out +++ b/qpdf/qtest/qpdf/issue-117.out @@ -2,7 +2,7 @@ WARNING: issue-117.pdf: file is damaged WARNING: issue-117.pdf (offset 3526): xref not found WARNING: issue-117.pdf: Attempting to reconstruct cross-reference table WARNING: issue-117.pdf (offset 66): loop detected resolving object 2 0 -WARNING: issue-117.pdf (object 2 0, offset 22): /Length key in stream dictionary is not an integer +WARNING: issue-117.pdf (object 2 0, offset 22): stream dictionary lacks /Length key WARNING: issue-117.pdf (object 2 0, offset 67): attempting to recover stream length WARNING: issue-117.pdf (object 2 0, offset 67): recovered stream length: 91 WARNING: issue-117.pdf (object 5 0, offset 1559): expected endstream diff --git a/qpdf/qtest/qpdf/issue-335a.out b/qpdf/qtest/qpdf/issue-335a.out index 812fa570..75bfb235 100644 --- a/qpdf/qtest/qpdf/issue-335a.out +++ b/qpdf/qtest/qpdf/issue-335a.out @@ -1019,22 +1019,22 @@ WARNING: issue-335a.pdf (trailer, offset 20748): stream keyword followed by extr WARNING: issue-335a.pdf (trailer, offset 20679): stream dictionary lacks /Length key WARNING: issue-335a.pdf (trailer, offset 20749): attempting to recover stream length WARNING: issue-335a.pdf (trailer, offset 20749): unable to recover stream data; treating stream as empty -WARNING: issue-335a.pdf (trailer, offset 20756): /Length key in stream dictionary is not an integer +WARNING: issue-335a.pdf (trailer, offset 20756): stream dictionary lacks /Length key WARNING: issue-335a.pdf (trailer, offset 20787): attempting to recover stream length WARNING: issue-335a.pdf (trailer, offset 20787): unable to recover stream data; treating stream as empty WARNING: issue-335a.pdf (trailer, offset 20812): unknown token while reading object; treating as string WARNING: issue-335a.pdf (trailer, offset 20803): expected dictionary key but found non-name object; inserting key /QPDFFake1 WARNING: issue-335a.pdf (trailer, offset 20803): dictionary has duplicated key /Length; last occurrence overrides earlier ones WARNING: issue-335a.pdf (trailer, offset 20843): stream keyword followed by extraneous whitespace -WARNING: issue-335a.pdf (trailer, offset 20800): /Length key in stream dictionary is not an integer +WARNING: issue-335a.pdf (trailer, offset 20800): stream dictionary lacks /Length key WARNING: issue-335a.pdf (trailer, offset 20844): attempting to recover stream length WARNING: issue-335a.pdf (trailer, offset 20844): unable to recover stream data; treating stream as empty -WARNING: issue-335a.pdf (trailer, offset 20851): /Length key in stream dictionary is not an integer +WARNING: issue-335a.pdf (trailer, offset 20851): stream dictionary lacks /Length key WARNING: issue-335a.pdf (trailer, offset 20882): attempting to recover stream length WARNING: issue-335a.pdf (trailer, offset 20882): unable to recover stream data; treating stream as empty WARNING: issue-335a.pdf (trailer, offset 20914): unknown token while reading object; treating as string WARNING: issue-335a.pdf (trailer, offset 20898): expected dictionary key but found non-name object; inserting key /QPDFFake1 -WARNING: issue-335a.pdf (trailer, offset 20895): /Length key in stream dictionary is not an integer +WARNING: issue-335a.pdf (trailer, offset 20895): stream dictionary lacks /Length key WARNING: issue-335a.pdf (trailer, offset 20929): attempting to recover stream length WARNING: issue-335a.pdf (trailer, offset 20929): unable to recover stream data; treating stream as empty WARNING: issue-335a.pdf (trailer, offset 20949): unexpected > @@ -1047,7 +1047,7 @@ WARNING: issue-335a.pdf (trailer, offset 20973): unexpected ) WARNING: issue-335a.pdf (trailer, offset 20973): too many errors; giving up on reading object WARNING: issue-335a.pdf (trailer, offset 21042): unknown token while reading object; treating as string WARNING: issue-335a.pdf (trailer, offset 21026): expected dictionary key but found non-name object; inserting key /QPDFFake1 -WARNING: issue-335a.pdf (trailer, offset 21023): /Length key in stream dictionary is not an integer +WARNING: issue-335a.pdf (trailer, offset 21023): stream dictionary lacks /Length key WARNING: issue-335a.pdf (trailer, offset 21057): attempting to recover stream length WARNING: issue-335a.pdf (trailer, offset 21057): unable to recover stream data; treating stream as empty WARNING: issue-335a.pdf (trailer, offset 21077): unexpected > @@ -1116,7 +1116,7 @@ WARNING: issue-335a.pdf (trailer, offset 21444): unknown token while reading obj WARNING: issue-335a.pdf (trailer, offset 21452): invalid character (-) in hexstring WARNING: issue-335a.pdf (trailer, offset 21819): unknown token while reading object; treating as string WARNING: issue-335a.pdf (trailer, offset 21819): too many errors; giving up on reading object -WARNING: issue-335a.pdf (trailer, offset 21407): /Length key in stream dictionary is not an integer +WARNING: issue-335a.pdf (trailer, offset 21407): stream dictionary lacks /Length key WARNING: issue-335a.pdf (trailer, offset 21438): attempting to recover stream length WARNING: issue-335a.pdf (trailer, offset 21438): unable to recover stream data; treating stream as empty WARNING: issue-335a.pdf (trailer, offset 21452): invalid character (-) in hexstring @@ -1171,13 +1171,13 @@ WARNING: issue-335a.pdf (trailer, offset 21936): dictionary has duplicated key / WARNING: issue-335a.pdf (trailer, offset 21936): expected dictionary key but found non-name object; inserting key /QPDFFake7 WARNING: issue-335a.pdf (trailer, offset 21936): expected dictionary key but found non-name object; inserting key /QPDFFake8 WARNING: issue-335a.pdf (trailer, offset 21936): expected dictionary key but found non-name object; inserting key /QPDFFake9 -WARNING: issue-335a.pdf (trailer, offset 21932): /Length key in stream dictionary is not an integer +WARNING: issue-335a.pdf (trailer, offset 21932): stream dictionary lacks /Length key WARNING: issue-335a.pdf (trailer, offset 22052): attempting to recover stream length WARNING: issue-335a.pdf (trailer, offset 22052): unable to recover stream data; treating stream as empty WARNING: issue-335a.pdf (trailer, offset 22000): invalid character (t) in hexstring WARNING: issue-335a.pdf (trailer, offset 22088): unknown token while reading object; treating as string WARNING: issue-335a.pdf (trailer, offset 22087): expected dictionary key but found non-name object; inserting key /QPDFFake1 -WARNING: issue-335a.pdf (trailer, offset 22083): /Length key in stream dictionary is not an integer +WARNING: issue-335a.pdf (trailer, offset 22083): stream dictionary lacks /Length key WARNING: issue-335a.pdf (trailer, offset 22136): attempting to recover stream length WARNING: issue-335a.pdf (trailer, offset 22136): unable to recover stream data; treating stream as empty WARNING: issue-335a.pdf (trailer, offset 22178): unknown token while reading object; treating as string @@ -1194,7 +1194,7 @@ WARNING: issue-335a.pdf (trailer, offset 22177): expected dictionary key but fou WARNING: issue-335a.pdf (trailer, offset 22177): expected dictionary key but found non-name object; inserting key /QPDFFake4 WARNING: issue-335a.pdf (trailer, offset 22177): expected dictionary key but found non-name object; inserting key /QPDFFake5 WARNING: issue-335a.pdf (trailer, offset 22276): stream keyword followed by carriage return only -WARNING: issue-335a.pdf (trailer, offset 22173): /Length key in stream dictionary is not an integer +WARNING: issue-335a.pdf (trailer, offset 22173): stream dictionary lacks /Length key WARNING: issue-335a.pdf (trailer, offset 22276): attempting to recover stream length WARNING: issue-335a.pdf (trailer, offset 22276): unable to recover stream data; treating stream as empty WARNING: issue-335a.pdf (trailer, offset 22202): unknown token while reading object; treating as string @@ -1219,7 +1219,7 @@ WARNING: issue-335a.pdf (trailer, offset 22373): attempting to recover stream le WARNING: issue-335a.pdf (trailer, offset 22373): unable to recover stream data; treating stream as empty WARNING: issue-335a.pdf (trailer, offset 22437): unknown token while reading object; treating as string WARNING: issue-335a.pdf (trailer, offset 22436): expected dictionary key but found non-name object; inserting key /QPDFFake1 -WARNING: issue-335a.pdf (trailer, offset 22432): /Length key in stream dictionary is not an integer +WARNING: issue-335a.pdf (trailer, offset 22432): stream dictionary lacks /Length key WARNING: issue-335a.pdf (trailer, offset 22484): attempting to recover stream length WARNING: issue-335a.pdf (trailer, offset 22484): unable to recover stream data; treating stream as empty WARNING: issue-335a.pdf (trailer, offset 22650): unknown token while reading object; treating as string @@ -1278,7 +1278,7 @@ WARNING: issue-335a.pdf (trailer, offset 22817): attempting to recover stream le WARNING: issue-335a.pdf (trailer, offset 22817): unable to recover stream data; treating stream as empty WARNING: issue-335a.pdf (trailer, offset 22702): unknown token while reading object; treating as string WARNING: issue-335a.pdf (trailer, offset 22701): expected dictionary key but found non-name object; inserting key /QPDFFake1 -WARNING: issue-335a.pdf (trailer, offset 22697): /Length key in stream dictionary is not an integer +WARNING: issue-335a.pdf (trailer, offset 22697): stream dictionary lacks /Length key WARNING: issue-335a.pdf (trailer, offset 22748): attempting to recover stream length WARNING: issue-335a.pdf (trailer, offset 22748): unable to recover stream data; treating stream as empty WARNING: issue-335a.pdf (trailer, offset 22845): unknown token while reading object; treating as string @@ -1308,7 +1308,7 @@ WARNING: issue-335a.pdf (object 5 0, offset 23451): invalid character (ÿ) in hex WARNING: issue-335a.pdf (object 5 0, offset 23458): unknown token while reading object; treating as string WARNING: issue-335a.pdf (object 5 0, offset 23444): expected dictionary key but found non-name object; inserting key /QPDFFake1 WARNING: issue-335a.pdf (object 5 0, offset 23444): expected dictionary key but found non-name object; inserting key /QPDFFake2 -WARNING: issue-335a.pdf (object 5 0, offset 23440): /Length key in stream dictionary is not an integer +WARNING: issue-335a.pdf (object 5 0, offset 23440): stream dictionary lacks /Length key WARNING: issue-335a.pdf (object 5 0, offset 23485): attempting to recover stream length WARNING: issue-335a.pdf (object 5 0, offset 23485): unable to recover stream data; treating stream as empty WARNING: issue-335a.pdf (object 5 0, offset 24974): expected endobj diff --git a/qpdf/qtest/qpdf/issue-51.out b/qpdf/qtest/qpdf/issue-51.out index feffea44..251df570 100644 --- a/qpdf/qtest/qpdf/issue-51.out +++ b/qpdf/qtest/qpdf/issue-51.out @@ -5,7 +5,7 @@ WARNING: issue-51.pdf (object 7 0, offset 553): expected endobj WARNING: issue-51.pdf (object 1 0, offset 236): dictionary has duplicated key /00000000; last occurrence overrides earlier ones WARNING: issue-51.pdf (object 1 0, offset 359): expected endobj WARNING: issue-51.pdf (offset 70): loop detected resolving object 2 0 -WARNING: issue-51.pdf (object 2 0, offset 26): /Length key in stream dictionary is not an integer +WARNING: issue-51.pdf (object 2 0, offset 26): stream dictionary lacks /Length key WARNING: issue-51.pdf (object 2 0, offset 71): attempting to recover stream length WARNING: issue-51.pdf (object 2 0, offset 71): unable to recover stream data; treating stream as empty WARNING: issue-51.pdf (object 2 0, offset 977): expected endobj diff --git a/qpdf/test_driver.cc b/qpdf/test_driver.cc index 655f480b..b2ed825d 100644 --- a/qpdf/test_driver.cc +++ b/qpdf/test_driver.cc @@ -51,7 +51,7 @@ class ExtendNameTree: public QPDFNameTreeObjectHelper { public: ExtendNameTree(QPDFObjectHandle o, QPDF& q); - virtual ~ExtendNameTree(); + ~ExtendNameTree() override; }; ExtendNameTree::ExtendNameTree(QPDFObjectHandle o, QPDF& q) : @@ -68,16 +68,15 @@ class Provider: public QPDFObjectHandle::StreamDataProvider { public: Provider(std::shared_ptr<Buffer> b) : - b(b), - bad_length(false) + b(b) { } - virtual ~Provider() = default; - virtual void - provideStreamData(int objid, int generation, Pipeline* p) + ~Provider() override = default; + void + provideStreamData(int objid, int generation, Pipeline* p) override { - // Don't change signature to use QPDFObjGen const& to detect - // problems forwarding to legacy implementations. + // Don't change signature to use QPDFObjGen const& to detect problems forwarding to legacy + // implementations. p->write(b->getBuffer(), b->getSize()); if (this->bad_length) { unsigned char ch = ' '; @@ -93,16 +92,16 @@ class Provider: public QPDFObjectHandle::StreamDataProvider private: std::shared_ptr<Buffer> b; - bool bad_length; + bool bad_length{false}; }; class ParserCallbacks: public QPDFObjectHandle::ParserCallbacks { public: - virtual ~ParserCallbacks() = default; - virtual void contentSize(size_t size); - virtual void handleObject(QPDFObjectHandle, size_t, size_t); - virtual void handleEOF(); + ~ParserCallbacks() override = default; + void contentSize(size_t size) override; + void handleObject(QPDFObjectHandle, size_t, size_t) override; + void handleEOF() override; }; void @@ -138,9 +137,9 @@ class TokenFilter: public QPDFObjectHandle::TokenFilter { public: TokenFilter() = default; - virtual ~TokenFilter() = default; - virtual void - handleToken(QPDFTokenizer::Token const& t) + ~TokenFilter() override = default; + void + handleToken(QPDFTokenizer::Token const& t) override { if (t == QPDFTokenizer::Token(QPDFTokenizer::tt_string, "Potato")) { // Exercise unparsing of strings by token constructor @@ -149,8 +148,8 @@ class TokenFilter: public QPDFObjectHandle::TokenFilter writeToken(t); } } - virtual void - handleEOF() + void + handleEOF() override { writeToken(QPDFTokenizer::Token(QPDFTokenizer::tt_name, "/bye")); write("\n"); @@ -2577,7 +2576,7 @@ test_76(QPDF& pdf, char const* arg2) assert(efs2.getSubtype() == "text/plain"); assert(QUtil::hex_encode(efs2.getChecksum()) == "2fce9c8228e360ba9b04a1bd1bf63d6b"); - for (auto iter: efdh.getEmbeddedFiles()) { + for (auto const& iter: efdh.getEmbeddedFiles()) { std::cout << iter.first << " -> " << iter.second->getFilename() << std::endl; } assert(efdh.getEmbeddedFile("att1")->getFilename() == "att1.txt"); diff --git a/qpdf/test_large_file.cc b/qpdf/test_large_file.cc index 12a75a84..f273c783 100644 --- a/qpdf/test_large_file.cc +++ b/qpdf/test_large_file.cc @@ -61,21 +61,19 @@ class ImageChecker: public Pipeline { public: ImageChecker(size_t n); - virtual ~ImageChecker() = default; - virtual void write(unsigned char const* data, size_t len); - virtual void finish(); + ~ImageChecker() override = default; + void write(unsigned char const* data, size_t len) override; + void finish() override; private: size_t n; - size_t offset; - bool okay; + size_t offset{0}; + bool okay{true}; }; ImageChecker::ImageChecker(size_t n) : Pipeline("image checker", nullptr), - n(n), - offset(0), - okay(true) + n(n) { } @@ -104,8 +102,8 @@ class ImageProvider: public QPDFObjectHandle::StreamDataProvider { public: ImageProvider(size_t n); - virtual ~ImageProvider() = default; - virtual void provideStreamData(int objid, int generation, Pipeline* pipeline); + ~ImageProvider() override = default; + void provideStreamData(int objid, int generation, Pipeline* pipeline) override; private: size_t n; diff --git a/qpdf/test_tokenizer.cc b/qpdf/test_tokenizer.cc index c0d13054..28aa3069 100644 --- a/qpdf/test_tokenizer.cc +++ b/qpdf/test_tokenizer.cc @@ -28,8 +28,8 @@ class Finder: public InputSource::Finder str(str) { } - virtual ~Finder() = default; - virtual bool check(); + ~Finder() override = default; + bool check() override; private: std::shared_ptr<InputSource> is; |