Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package podofo for openSUSE:Factory checked in at 2025-09-05 21:42:15 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/podofo (Old) and /work/SRC/openSUSE:Factory/.podofo.new.1977 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "podofo" Fri Sep 5 21:42:15 2025 rev:42 rq:1302717 version:1.0.2 Changes: -------- --- /work/SRC/openSUSE:Factory/podofo/podofo.changes 2025-08-12 17:03:59.517803697 +0200 +++ /work/SRC/openSUSE:Factory/.podofo.new.1977/podofo.changes 2025-09-05 21:42:29.498575166 +0200 @@ -1,0 +2,13 @@ +Wed Sep 3 18:52:33 UTC 2025 - Andreas Stieger <andreas.stie...@gmx.de> + +- Update to 1.0.2: + * PdfTokenizer: Fixed free-after-use after failing to parse + content while reading literal tokens (boo#1249105) + * PdfFont: Improved heursitic for word spacing + * PdfDifferenceEncoding: Fixed handling of ligatures in AGL + character names + * PdfXMPPAcket: Make GetDescription() const correct + * PdfMemDocument: Fixed upgrade to PDF2.0 in a incremental update +- drop cmake variables unused in the project + +------------------------------------------------------------------- Old: ---- podofo-1.0.1.tar.gz New: ---- podofo-1.0.2.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ podofo.spec ++++++ --- /var/tmp/diff_new_pack.CdEhvZ/_old 2025-09-05 21:42:30.122601423 +0200 +++ /var/tmp/diff_new_pack.CdEhvZ/_new 2025-09-05 21:42:30.126601591 +0200 @@ -2,6 +2,7 @@ # spec file for package podofo # # Copyright (c) 2025 SUSE LLC +# Copyright (c) 2025 Andreas Stieger <andreas.stie...@gmx.de> # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -18,21 +19,16 @@ %define libver 3 Name: podofo -Version: 1.0.1 +Version: 1.0.2 Release: 0 Summary: PDF parsing and creation library License: GPL-2.0-or-later -URL: http://podofo.sourceforge.net/ +URL: https://podofo.sourceforge.net/ Source0: https://github.com/podofo/podofo/archive/%{version}/%{name}-%{version}.tar.gz BuildRequires: cmake >= 3.23 BuildRequires: dos2unix BuildRequires: doxygen BuildRequires: fdupes -%if 0%{suse_version} > 1600 -BuildRequires: gcc-c++ -%else -BuildRequires: gcc13-c++ -%endif BuildRequires: graphviz BuildRequires: libboost_headers-devel BuildRequires: pkgconfig @@ -46,6 +42,11 @@ BuildRequires: pkgconfig(lua) BuildRequires: pkgconfig(openssl) BuildRequires: pkgconfig(zlib) +%if 0%{?suse_version} > 1600 +BuildRequires: gcc-c++ +%else +BuildRequires: gcc13-c++ +%endif %description A cross platform PDF parsing and creation library. @@ -79,11 +80,7 @@ export CXX=g++ test -x "$(type -p g++-13)" && export CXX=g++-13 %cmake \ - -DWANT_FONTCONFIG=ON \ - -DWANT_BOOST=ON \ -DPODOFO_BUILD_STATIC=OFF \ - -DPODOFO_USE_VISIBILITY=ON \ - -DPODOFO_BUILD_TEST=OFF \ -DPODOFO_BUILD_TEST=OFF \ -DPODOFO_BUILD_UNSUPPORTED_TOOLS=OFF %cmake_build @@ -102,8 +99,7 @@ %fdupes -s %{buildroot} -%post -n libpodofo%{libver} -p /sbin/ldconfig -%postun -n libpodofo%{libver} -p /sbin/ldconfig +%ldconfig_scriptlets -n libpodofo%{libver} %files -n libpodofo%{libver} %license COPYING ++++++ podofo-1.0.1.tar.gz -> podofo-1.0.2.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/podofo-1.0.1/API-MIGRATION.md new/podofo-1.0.2/API-MIGRATION.md --- old/podofo-1.0.1/API-MIGRATION.md 2025-06-21 23:47:21.000000000 +0200 +++ new/podofo-1.0.2/API-MIGRATION.md 2025-08-28 23:08:39.000000000 +0200 @@ -1,3 +1,7 @@ +## 1.0.1 -> 1.0.2 +- `PdfXMPPacket`: make reserved 3rd party interop `GetDescription` non const, as we + generally ensure const correctness in all the API (with limited exceptions) + ## 0.10.1 -> 1.0.0 - `PdfFontConfigWrapper`: Put `GetFcConfig()` and the constructor with `FcConfig*` argument under guard by the `PODOFO_3RDPARTY_INTEROP_ENABLED` macro diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/podofo-1.0.1/CHANGELOG.md new/podofo-1.0.2/CHANGELOG.md --- old/podofo-1.0.1/CHANGELOG.md 2025-06-21 23:47:21.000000000 +0200 +++ new/podofo-1.0.2/CHANGELOG.md 2025-08-28 23:08:39.000000000 +0200 @@ -1,5 +1,13 @@ +## Version 1.0.2 +- Fixed [#275](https://github.com/podofo/podofo/issues/275), [#276](https://github.com/podofo/podofo/issues/276) +- `PdfTokenizer`: Fixed free-after-use after failing to parse content while reading literal tokens +- `PdfFont`: Improved heursitic for word spacing +- `PdfDifferenceEncoding`: Fixed handling of ligatures in AGL character names +- `PdfXMPPAcket`: Make `GetDescription()` const correct +- `PdfMemDocument`: Fixed upgrade to PDF2.0 in a incremental update + ## Version 1.0.1 -- Fixed #265, #256 +- Fixed [#265](https://github.com/podofo/podofo/issues/265), [#264](https://github.com/podofo/podofo/issues/264) - Fixed several issues related to use of `nullable<std::unique_ptr<T>>` - XMP: Fixed removing extension from extension bag - XMP: Fix double inserting pdfuaid schema @@ -53,26 +61,32 @@ - Tons of other bug fixes ## Version 0.10.5 -- Fix #191, #197, #201, #212, #233, #241, #251, #252, #253 -- PdfParser: Fixed stack overflow parsing documents with many XRef stream updates -- PdfFont: Fixed GetBoundingBox() retrival -- PdfFontMetricsObject: Fixed reading /FontBBox -- PdfEncodingFactory: Fixed parsing of limits with /FirstChar equals to /LastChar -- PdfFontMetricsStandard14: Fixed parsing /Widths -- PdfMetadata: Fixed missing init ensure for SetAuthor() -- PdfTokenizer: Fixed character escaping when reading strings -- PdfPageCollection: Fix memory leak in RemovePageAt +- Fix [#191](https://github.com/podofo/podofo/issues/191), [#197](https://github.com/podofo/podofo/issues/197), + [#201](https://github.com/podofo/podofo/issues/201), [#212](https://github.com/podofo/podofo/issues/212), + [#233](https://github.com/podofo/podofo/issues/233), [#241](https://github.com/podofo/podofo/issues/241), + [#251](https://github.com/podofo/podofo/issues/251), [#252](https://github.com/podofo/podofo/issues/252), + [#253](https://github.com/podofo/podofo/issues/253) +- `PdfParser`: Fixed stack overflow parsing documents with many XRef stream updates +- `PdfFont`: Fixed `GetBoundingBox()` retrival +- `PdfFontMetricsObject`: Fixed reading `/FontBBox` +- `PdfEncodingFactory`: Fixed parsing of limits with `/FirstChar` equals to `/LastChar` +- `PdfFontMetricsStandard14`: Fixed parsing /Widths +- `PdfMetadata`: Fixed missing init ensure for SetAuthor() +- `PdfTokenizer`: Fixed character escaping when reading strings +- `PdfPageCollection`: Fix memory leak in `RemovePageAt` - Compilation and linking fixes in various conditions -- PdfFontManager: Fixed GetOrCreateFontFromBuffer stealing memory -- PdfPageCollection: Disable copy/assignment -- PdfPage_TextExtraction: Fix `decodeString` with no font -- Fix eating of non-space chars in SplitTextAsLines +- `PdfFontManager`: Fixed GetOrCreateFontFromBuffer stealing memory +- `PdfPageCollection`: Disable copy/assignment +- `PdfPage_TextExtraction`: Fix `decodeString` with no font +- Fix eating of non-space chars in `SplitTextAsLines` - Fix FreeType segfault race condition -- PdfCheckBox: Fixed IsChecked() -- PdfParser: Uncondtionally try to read XRef stream in all PDFs that doesn't have a cross reference section +- `PdfCheckBox`: Fixed `IsChecked()` +- `PdfParser`: Uncondtionally try to read XRef stream in all PDFs that doesn't have a cross reference section ## Version 0.10.4 -- Fixes #161, #162, #167, #183, merges #157 +- Fixes [#161](https://github.com/podofo/podofo/issues/161), [#162](https://github.com/podofo/podofo/issues/162), +[#167](https://github.com/podofo/podofo/issues/167), [#183](https://github.com/podofo/podofo/issues/183), +merges [#157](https://github.com/podofo/podofo/issues/) - `StandardStreamDevice`: Fixed `seek()` in case of `iostream`/`fstream` - `PdfWriter`: Fixed computing the doc identifier with a wrong buffer - `PdfPainter`: Fix `SetCurrentMatrix()` to really update CTM @@ -81,17 +95,21 @@ - `PdfPainter`: Fixed offset on multiline text if text is not left aligned ## Version 0.10.3 -- Fixed big performance regression introduced in 0.10, see #108 -- Fixed data loss with encrypted documents, see #99 +- Fixed big performance regression introduced in 0.10, see [#108](https://github.com/podofo/podofo/issues/108) +- Fixed data loss with encrypted documents, see [#99](https://github.com/podofo/podofo/issues/99) - Fixed compilation with VS2022 >= 17.8 - Fixed compilation using libxml >= 2.12.0 ## Version 0.10.2 -- Security related bugfixes #76, #89, #96 +- Security related bugfixes [#76](https://github.com/podofo/podofo/issues/76), +[#89](https://github.com/podofo/podofo/issues/89), +[#96](https://github.com/podofo/podofo/issues/96) - Some compilation and test fixes ## Version 0.10.1 -- Security bugfixes, #66, #67, #69, #70, #71, #72 +- Security bugfixes, [#66](https://github.com/podofo/podofo/issues/66), [#67](https://github.com/podofo/podofo/issues/67), +[#69](https://github.com/podofo/podofo/issues/69), [#70](https://github.com/podofo/podofo/issues/70), +[#71](https://github.com/podofo/podofo/issues/71), [#72](https://github.com/podofo/podofo/issues/72) - Rewritten `PdfPageCollection` for performance - `PdfCMapEncoding`: Fix parsing some invalid CMap(s) supported by Acrobat - `PdfXRefStreamParserObject`: Fixed handling of invalid XRef stream entries @@ -141,99 +159,99 @@ - `PdfImage`: Added `DecodeTo(pixelFormat)` ## Version 0.9.22 (pdfmm) -- Fixed serialization of strings with non ASCII PdfDocEncoding +- Fixed serialization of strings with non ASCII `PdfDocEncoding` characters -- Removed PdfLocaleImbue -- PdfEncrypt: Removed PdfReference state. Added PdfStatefulEncrypt -- Removed use of std::ostringstream. Added efficient outstringstream -- Added PdfMath functionalities (matrix transformations and so on) +- Removed `PdfLocaleImbue` +- `PdfEncrypt`: Removed `PdfReference` state. Added `PdfStatefulEncrypt` +- Removed use of `std::ostringstream`. Added efficient `outstringstream` +- Added `PdfMath` functionalities (matrix transformations and so on) ## Version 0.9.21 (pdfmm) - Fixed serialization of UTF-16BE strings -- More lenient PdfDate parsing +- More lenient `PdfDate` parsing ## Version 0.9.20 (pdfmm) - The project is now a C++17 library -- Added move semantics for PdfVariant, PdfObject, PdfArray, PdfDictionary +- Added move semantics for `PdfVariant`, `PdfObject`, `PdfArray`, `PdfDictionary` - Improved XRefStream support, added support in incremental saves - Many fixes in save incremental object/generation number incrementing -- String backed with UTF-8 storage -- PdfName backed with UTF-8 storage -- Brand new PdfEncoding class with support for both /Encoding and /ToUnicode, +- `PdfString` backed with UTF-8 storage +- `PdfName` backed with UTF-8 storage +- Brand new P`dfEncoding` class with support for both `/Encoding` and `/ToUnicode`, more complete Unicode support -- Added a PdfDynamicEncoding class that creates a custom CID encoding +- Added a `PdfDynamicEncoding` class that creates a custom CID encoding based on actual used glyphs used -- Automatic creation of CIDMap and /ToUnicode -- Added PdfSigner class and SignDocument() -- Added PdfFontType1Encoding, which support Type1 implicit encoding +- Automatic creation of CIDMap and `/ToUnicode` +- Added `PdfSigner` class and `SignDocument()` +- Added `PdfFontType1Encoding`, which support Type1 implicit encoding - Added support for PDF 2.0 UTF-8 strings (untested) -- Added indirect iteration for PdfArray/PdfDictionary (see GetIndirectIterator methods) -- Added PdfDocument::GetPdfALevel() +- Added indirect iteration for `PdfArray`/`PdfDictionary` (see `GetIndirectIterator` methods) +- Added `PdfDocument::GetPdfALevel()` - Added PDFA preserving writing -- Refactored/Reviewed PdfInputDevice: versions that take buffer - do not copy it (use istringviewstream) -- Added font replacement facility PdfFont::TryCreateFontSubstitute() +- Refactored/Reviewed `PdfInputDevice`: versions that take buffer + do not copy it (use `istringviewstream`) +- Added font replacement facility `PdfFont::TryCreateFontSubstitute()` - Added standard14 fonts embedding, with font programs from PDFium -- Reviewed PdfXObject hierarchy, added PdfXObjectForm, PdfXObjectPostScript -- Added PdfTextState and use it to compute string widths in PdfFont -- Improved PdfDocEncoding to expose conversion utf8 conversion facilities -- PdfParser: Support also files with whitespace offset before magic start -- PdfObject auto ownership -- PdfContents: create on demand /Contents. First create a single stream, after array -- Improved IsDirty handling: less dirty bit sets -- Added PdfPostScriptTokenizer that as better general support for PostScript -- PdfDictionary: Review/convert GetKey -> FindKey -- PdfDictionary: Review GetKeyAs methods +- Reviewed `PdfXObject` hierarchy, added `PdfXObjectForm`, `PdfXObjectPostScript` +- Added `PdfTextState` and use it to compute string widths in `PdfFont` +- Improved `PdfDocEncoding` to expose conversion utf8 conversion facilities +- `PdfParser`: Support also files with whitespace offset before magic start +- `PdfObject` auto ownership +- `PdfContents`: create on demand /Contents. First create a single stream, after array +- Improved `IsDirty` handling: less dirty bit sets +- Added `PdfPostScriptTokenizer` that as better general support for PostScript +- `PdfDictionary`: Reviewed/convert `GetKey` -> `FindKey` +- `PdfDictionary`: Reviewed `GetKeyAs` methods - Fixed hundreds of warnings. No warnings left in tested builds -- FontConfigManager: better handling with custom configurations -- Removed PdfMutex. Used std::mutex where necessary -- Datatypte: remove PdfDataType::HexString +- `FontConfigManager`: better handling with custom configurations +- Removed `PdfMutex`. Used `std::mutex` where necessary +- Datatypte: removed `PdfDataType::HexString` - Removed support for old compilers (MSVC6, hpux, borland, turbo...) - Added better endian swap functions -- Removed auto_ptr usage -- Removed pdf_int/pdf_uint types -- Removed use of pdf_long/long types -- Removed use of ptrdiff_t +- Removed `auto_ptr` usage +- Removed `pdf_int`/`pdf_uint` types +- Removed use of `pdf_long`/`long` types +- Removed use of `ptrdiff_t` - Removed unistring and ugly string conversion code. Moved to utfcpp -- Reviewed PdfObject::GetNumber/PdfObject::GetReal (strict/lenient) -- Remove PdfObject inheritance on PdfVariant -- Reviewed PdfVariant/PdfObject/PdfArray/PdfDictionary equality/disequality operators +- Reviewed `PdfObject::GetNumber`/`PdfObject::GetReal` (strict/lenient) +- Remove `PdfObject` inheritance on `PdfVariant` +- Reviewed `PdfVariant`/`PdfObject`/`PdfArray`/`PdfDictionary` equality/disequality operators - Simplified copyright headers - Object copy constructor must copy also stream -- PdfElement: GetDocument(), GetObject() refs -- PdfVecObjects: GetParentDocument() -> GetDocument() -- Remove PdfSignOutputDevice::SetSignatureSize(size) +- `PdfElement`: `GetDocument()`, `GetObject()` refs +- `PdfIndirectObjectList`: `GetParentDocument()` -> `GetDocument()` +- Remove `PdfSignOutputDevice::SetSignatureSize(size)` - Moved inline code to .cpp - Remove comments on overrides - Cleaned CMakeFiles (removed custom Find<>.cmake) -- NULL -> nullptr -- Use shared_ptr in PdfFontMetrics, PdfEncoding in PdfFont -- Cleaned PdfFontCache (renamed PdfFontManager), removed font functions from PdfDocument -- PdfArray::FindAt() return ref +- `NULL` -> `nullptr` +- Use `std::shared_ptr` in `PdfFontMetrics`, `PdfEncoding` in `PdfFont` +- Cleaned `PdfFontCache` (renamed `PdfFontManager`), removed font functions from `PdfDocument` +- `PdfArray::FindAt()` return ref - Simplified license headers -- Reviewed PdfPageTree and PdfPageTreeCache API +- Reviewed `PdfPageTree` and `PdfPageTreeCache` API - Reviewed most int vs unsigned indexing - Remove all hungarian notation - Sanitize code style - Removed all const char* and passed to string/string_view -- Renamed PdfFontCache -> PdfFontManager -- Renamed PdfVecObjects -> PdfIndirectObjectList -- Renamed PdfNamesTree -> PdfNameTree -- Renamed PdfPagesTree -> PdfPageTree -- Renamed PdfPagesTreeCache -> PdfPageTreeCache +- Renamed `PdfFontCache` -> `PdfFontManager` +- Renamed `PdfVecObjects` -> `PdfIndirectObjectList` +- Renamed `PdfNamesTree` -> `PdfNameTree` +- Renamed `PdfPagesTree` -> `PdfPageTree` +- Renamed `PdfPagesTreeCache` -> `PdfPageTreeCache` - PdfObject: removed GetIndirectObject(), MustGetIndirectKey (must use PdfDictionary now) -- Remove PdfMemoryManagement.cpp, Removed podofo_new, podofo_free +- Remove `PdfMemoryManagement.cpp`, Removed `podofo_new`, `podofo_free` - Add chars type for char array storage/buffering which inerits string - Review pointer vs ref parameters/return types -- Remove PdfRefCountedBuffer, PdfRefCountedInputDevice, PdfRefCountedOutputDevice -- Removed PdfMemoryManagement and all C style malloc/free usage -- Refactored PdfOutputDevice (PdfMemoryOutputDevice/PdfFileOutputDevice/etc.) -- Clean PdfError, remove wchar_t -- Remove printf, snprintf -- Renamed PdfElement-> {PdfDictionaryElement|PdfArrayElement} that - respectively have GetDictionary(), GetArray() -- Reviwed PdfWriteFlags, added PdfSaveOptions +- Removed `PdfRefCountedBuffer`, `PdfRefCountedInputDevice`, `PdfRefCountedOutputDevice` +- Removed `PdfMemoryManagement` and all C style malloc/free usage +- Refactored `PdfOutputDevice` (`PdfMemoryOutputDevice`/`PdfFileOutputDevice`/etc.) +- Clean `PdfError`, remove `wchar_t` +- Remove `printf`, `snprintf` +- Renamed `PdfElement`-> {`PdfDictionaryElement`|`PdfArrayElement`} that + respectively have `GetDictionary()`, `GetArray()` +- Reviewed `PdfWriteFlags`, added `PdfSaveOptions` ## Old PoDoFo ChangeLog diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/podofo-1.0.1/CMakeLists.txt new/podofo-1.0.2/CMakeLists.txt --- old/podofo-1.0.1/CMakeLists.txt 2025-06-21 23:47:21.000000000 +0200 +++ new/podofo-1.0.2/CMakeLists.txt 2025-08-28 23:08:39.000000000 +0200 @@ -20,7 +20,7 @@ set(PODOFO_VERSION_MAJOR "1" CACHE STRING "Major part of podofo version number") set(PODOFO_VERSION_MINOR "0" CACHE STRING "Minor part of podofo version number") -set(PODOFO_VERSION_PATCH "1" CACHE STRING "Patchlevel part of podofo version number") +set(PODOFO_VERSION_PATCH "2" CACHE STRING "Patchlevel part of podofo version number") set(PODOFO_VERSION "${PODOFO_VERSION_MAJOR}.${PODOFO_VERSION_MINOR}.${PODOFO_VERSION_PATCH}") set(PODOFO_SOVERSION "3") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/podofo-1.0.1/playground/CMakeLists.txt new/podofo-1.0.2/playground/CMakeLists.txt --- old/podofo-1.0.1/playground/CMakeLists.txt 2025-06-21 23:47:21.000000000 +0200 +++ new/podofo-1.0.2/playground/CMakeLists.txt 2025-08-28 23:08:39.000000000 +0200 @@ -76,6 +76,12 @@ # Set use libxml2 static for fontconfig add_compile_definitions(LIBXML_STATIC) +# Don't search dependencies in sysroot. This avoid +# potential mismatches +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE NEVER) + if(WIN32) if ("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") set(LIB_SUFFIX "d") @@ -95,12 +101,6 @@ # Fontconfig set(Fontconfig_LIBRARY "${DEPS_PATH}/fontconfig/lib/${ARCH}/fontconfig${LIB_SUFFIX}.lib" CACHE FILEPATH "" FORCE) else() - # Freetype - set(FREETYPE_INCLUDE_DIR_ft2build "${DEPS_PATH}/freetype/include/freetype2" CACHE PATH "" FORCE) - set(FREETYPE_INCLUDE_DIR_freetype2 "${DEPS_PATH}/freetype/include" CACHE PATH "" FORCE) - set(FREETYPE_LIBRARY_RELEASE "${DEPS_PATH}/freetype/lib/${ARCH}/libfreetype.a" CACHE FILEPATH "" FORCE) - # Fontconfig - set(Fontconfig_LIBRARY "${DEPS_PATH}/fontconfig/lib/${ARCH}/libfontconfig.a" CACHE FILEPATH "" FORCE) set(PLATFORM_SYSTEM_LIBRARIES "${DEPS_PATH}/bzip2/lib/${ARCH}/libbz2.a" "${DEPS_PATH}/libuuid/lib/${ARCH}/libuuid.a") endif() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/podofo-1.0.1/src/podofo/CMakeLists.txt new/podofo-1.0.2/src/podofo/CMakeLists.txt --- old/podofo-1.0.1/src/podofo/CMakeLists.txt 2025-06-21 23:47:21.000000000 +0200 +++ new/podofo-1.0.2/src/podofo/CMakeLists.txt 2025-08-28 23:08:39.000000000 +0200 @@ -77,7 +77,7 @@ set(PODOFO_TARGET podofo_static) set(PODOFO_LIBRARIES podofo_static podofo_private podofo_3rdparty CACHE INTERNAL "Which podofo library variant to depend on") - set(PODOFO_PACKAGE_CONFIG_LIBS "-lpodofo_private -lpodofo_3rdparty") + set(PODOFO_PKGCONFIG_LIBS_PRIVATE "-lpodofo_private -lpodofo_3rdparty") endif() if(PODOFO_BUILD_SHARED) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/podofo-1.0.1/src/podofo/libpodofo.pc.in new/podofo-1.0.2/src/podofo/libpodofo.pc.in --- old/podofo-1.0.1/src/podofo/libpodofo.pc.in 2025-06-21 23:47:21.000000000 +0200 +++ new/podofo-1.0.2/src/podofo/libpodofo.pc.in 2025-08-28 23:08:39.000000000 +0200 @@ -8,5 +8,5 @@ Version: @PODOFO_VERSION@ Requires.private: @PODOFO_PKGCONFIG_REQUIRES_PRIVATE@ Libs: -L${libdir} -lpodofo -Libs.private: @PODOFO_PACKAGE_CONFIG_LIBS@ +Libs.private: @PODOFO_PKGCONFIG_LIBS_PRIVATE@ Cflags: -I${includedir} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/podofo-1.0.1/src/podofo/main/PdfDeclarations.h new/podofo-1.0.2/src/podofo/main/PdfDeclarations.h --- old/podofo-1.0.1/src/podofo/main/PdfDeclarations.h 2025-06-21 23:47:21.000000000 +0200 +++ new/podofo-1.0.2/src/podofo/main/PdfDeclarations.h 2025-08-28 23:08:39.000000000 +0200 @@ -251,7 +251,7 @@ enum class PdfFontDescriptorFlags : uint32_t { None = 0, - FixedPitch = 1 << 0, + FixedPitch = 1 << 0, ///< Also known as monospaced Serif = 1 << 1, Symbolic = 1 << 2, ///< Font contains glyphs outside the Standard Latin character set. It does **not** mean the font is a symbol like font Script = 1 << 3, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/podofo-1.0.1/src/podofo/main/PdfDifferenceEncoding.cpp new/podofo-1.0.2/src/podofo/main/PdfDifferenceEncoding.cpp --- old/podofo-1.0.1/src/podofo/main/PdfDifferenceEncoding.cpp 2025-06-21 23:47:21.000000000 +0200 +++ new/podofo-1.0.2/src/podofo/main/PdfDifferenceEncoding.cpp 2025-08-28 23:08:39.000000000 +0200 @@ -110,14 +110,14 @@ // dictionary, therefore they have no meaning CodePointSpan codepoints; const PdfName* actualName; - if (!PdfDifferenceEncoding::TryGetCodePointsFromCharName(name, codepoints, actualName)) + if (PdfDifferenceEncoding::TryGetCodePointsFromCharName(name, codepoints, actualName)) { - char32_t cp = code; - addDifference(code, codepointview(&cp, 1), name); + addDifference(code, codepoints, actualName == nullptr ? PdfName(name) : *actualName); } else { - addDifference(code, codepoints, actualName == nullptr ? PdfName(name) : *actualName); + char32_t cp = code; + addDifference(code, codepointview(&cp, 1), name); } } @@ -427,7 +427,7 @@ string_view component; CodePointSpan temp; const PdfName* discard; - do + while (true) { component = charName.substr(0, componentDelim); if (!tryFetchCodePoints(component, temp, discard)) @@ -437,8 +437,13 @@ return false; } + ret.push_back(*temp); + if (componentDelim == string_view::npos) + break; + charName = charName.substr(componentDelim + 1); - } while ((componentDelim = charName.find('_')) != string_view::npos); + componentDelim = charName.find('_'); + } codepoints = CodePointSpan(ret); return true; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/podofo-1.0.1/src/podofo/main/PdfFont.cpp new/podofo-1.0.2/src/podofo/main/PdfFont.cpp --- old/podofo-1.0.1/src/podofo/main/PdfFont.cpp 2025-06-21 23:47:21.000000000 +0200 +++ new/podofo-1.0.2/src/podofo/main/PdfFont.cpp 2025-08-28 23:08:39.000000000 +0200 @@ -33,6 +33,7 @@ static double getGlyphLength(double glyphLength, const PdfTextState& state, bool ignoreCharSpacing); static string_view toString(PdfFontStretch stretch); +static double getGlyphMedianWidth(const PdfFontMetrics& metrics, unsigned maxGlyphCount); PdfFont::PdfFont(PdfDocument& doc, PdfFontType type, PdfFontMetricsConstPtr&& metrics, const PdfEncoding& encoding) : @@ -354,13 +355,21 @@ double PdfFont::GetWordSpacingLength(const PdfTextState& state) const { - const_cast<PdfFont&>(*this).initSpaceDescriptors(); - return getGlyphLength(m_WordSpacingLengthRaw, state, false); + const_cast<PdfFont&>(*this).initSpacingDescriptors(); + constexpr double WORD_SPACING_FRACTIONAL_FACTOR = 5.5; + return getGlyphLength(m_WordSpacingLengthRaw / WORD_SPACING_FRACTIONAL_FACTOR, state, false); +} + +double PdfFont::GetHardSpacingLength(const PdfTextState& state) const +{ + const_cast<PdfFont&>(*this).initSpacingDescriptors(); + constexpr double HARD_SPACING_FACTOR = 6; + return getGlyphLength(m_WordSpacingLengthRaw * HARD_SPACING_FACTOR, state, false); } double PdfFont::GetSpaceCharLength(const PdfTextState& state) const { - const_cast<PdfFont&>(*this).initSpaceDescriptors(); + const_cast<PdfFont&>(*this).initSpaceCharLength(); return getGlyphLength(m_SpaceCharLengthRaw, state, false); } @@ -601,43 +610,37 @@ contents.GetOrCreateStream().SetData(data); } -void PdfFont::initSpaceDescriptors() +void PdfFont::initSpacingDescriptors() { if (m_WordSpacingLengthRaw >= 0) return; - // TODO: Maybe try looking up other characters if U' ' is missing? - // https://docs.microsoft.com/it-it/dotnet/api/system.char.iswhitespace + // We arbitrarily take a fraction of the median of few glyphs. The + // factor proved to work well with a consistent tests corpus + // NOTE: This is very different from what Adobe Acrobat does, + // but there's no reference heuristic to look at, every + // implementation does something different + // https://github.com/pdf-association/pdf-issues/issues/564 + constexpr unsigned GLYPH_MEDIAN_MAX_COUNT = 10; + m_WordSpacingLengthRaw = getGlyphMedianWidth(*m_Metrics, GLYPH_MEDIAN_MAX_COUNT); +} + +void PdfFont::initSpaceCharLength() +{ + if (m_SpaceCharLengthRaw >= 0) + return; + unsigned gid; if (!TryGetGID(U' ', PdfGlyphAccess::ReadMetrics, gid) || !m_Metrics->TryGetGlyphWidth(gid, m_SpaceCharLengthRaw) || m_SpaceCharLengthRaw <= 0) { - double lengthsum = 0; - unsigned nonZeroCount = 0; - for (unsigned i = 0, count = m_Metrics->GetGlyphCount(PdfGlyphAccess::ReadMetrics); i < count; i++) - { - double length; - m_Metrics->TryGetGlyphWidth(i, length); - if (length > 0) - { - lengthsum += length; - nonZeroCount++; - } - } - - m_SpaceCharLengthRaw = lengthsum / nonZeroCount; + constexpr unsigned GLYPH_MEDIAN_MAX_COUNT = 10; + m_SpaceCharLengthRaw = getGlyphMedianWidth(*m_Metrics, GLYPH_MEDIAN_MAX_COUNT); + constexpr double CHAR_SPACE_FRACTIONAL_FACTOR = 3; + if ((m_Metrics->GetFlags() & PdfFontDescriptorFlags::FixedPitch) == PdfFontDescriptorFlags::None) + m_SpaceCharLengthRaw /= CHAR_SPACE_FRACTIONAL_FACTOR; } - - // We arbitrarily take a fraction of the read or inferred - // char space to determine the word spacing length. The - // factor proved to work well with a consistent tests corpus - // NOTE: This is very different from what Adobe Acrobat does, - // but there's no reference heuristic to look at, every - // implementation does something different - // https://github.com/pdf-association/pdf-issues/issues/564 - constexpr double WORD_SPACING_FRACTIONAL_FACTOR = 5.3; - m_WordSpacingLengthRaw = m_SpaceCharLengthRaw / WORD_SPACING_FRACTIONAL_FACTOR; } void PdfFont::pushSubsetInfo(unsigned cid, const PdfGID& gid, const PdfCharCode& code) @@ -1188,3 +1191,33 @@ PODOFO_RAISE_ERROR(PdfErrorCode::InvalidEnumValue); } } + +double getGlyphMedianWidth(const PdfFontMetrics& metrics, unsigned maxGlyphCount) +{ + vector<double> glyphWidths; + double length; + unsigned i = 0, count = metrics.GetGlyphCount(PdfGlyphAccess::ReadMetrics); + while (true) + { + if (i >= count) + break; + + // Skip some small glyph lengths + constexpr double GLYPH_WIDTH_THRESHOLD = 0.25; + if (metrics.TryGetGlyphWidth(i, length) && length > GLYPH_WIDTH_THRESHOLD) + { + glyphWidths.push_back(length); + if (glyphWidths.size() == maxGlyphCount) + break; + } + + i++; + } + + if (glyphWidths.size() == 0) + return 0; + + size_t n = glyphWidths.size() / 2; + std::nth_element(glyphWidths.begin(), glyphWidths.begin() + n, glyphWidths.end()); + return glyphWidths[n]; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/podofo-1.0.1/src/podofo/main/PdfFont.h new/podofo-1.0.2/src/podofo/main/PdfFont.h --- old/podofo-1.0.1/src/podofo/main/PdfFont.h 2025-06-21 23:47:21.000000000 +0200 +++ new/podofo-1.0.2/src/podofo/main/PdfFont.h 2025-08-28 23:08:39.000000000 +0200 @@ -186,6 +186,14 @@ double GetWordSpacingLength(const PdfTextState& state) const; /** + * \returns The hard spacing length + * \remarks This differs from GetWordSpacingLength() as this will + * unconditionally split same line entries even when extracting lines + * as opposed to words + */ + double GetHardSpacingLength(const PdfTextState& state) const; + + /** * \returns The space char length * \remarks This differs from GetWordSpacingLength() as this will * be used to visually represent a space, while word spacing length @@ -447,7 +455,9 @@ static std::unique_ptr<PdfFont> createFontForType(PdfDocument& doc, PdfFontMetricsConstPtr&& metrics, const PdfEncoding& encoding, bool preferNonCID); - void initSpaceDescriptors(); + void initSpacingDescriptors(); + + void initSpaceCharLength(); void pushSubsetInfo(unsigned cid, const PdfGID& gid, const PdfCharCode& code); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/podofo-1.0.1/src/podofo/main/PdfFontConfigWrapper.cpp new/podofo-1.0.2/src/podofo/main/PdfFontConfigWrapper.cpp --- old/podofo-1.0.1/src/podofo/main/PdfFontConfigWrapper.cpp 2025-06-21 23:47:21.000000000 +0200 +++ new/podofo-1.0.2/src/podofo/main/PdfFontConfigWrapper.cpp 2025-08-28 23:08:39.000000000 +0200 @@ -22,7 +22,6 @@ PdfFontConfigWrapper::PdfFontConfigWrapper(const string_view& configStr) : m_FcConfig(FcConfigCreate()) { - m_FcConfig = FcConfigCreate(); if (m_FcConfig == nullptr) PODOFO_RAISE_ERROR_INFO(PdfErrorCode::InvalidHandle, "Could not allocate font config"); @@ -34,6 +33,9 @@ PODOFO_RAISE_ERROR_INFO(PdfErrorCode::InvalidFontData, "Could not parse font config"); } +PdfFontConfigWrapper::PdfFontConfigWrapper() + : PdfFontConfigWrapper((FcConfig*)nullptr) { } + PdfFontConfigWrapper::PdfFontConfigWrapper(FcConfig* fcConfig) : m_FcConfig(fcConfig) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/podofo-1.0.1/src/podofo/main/PdfFontConfigWrapper.h new/podofo-1.0.2/src/podofo/main/PdfFontConfigWrapper.h --- old/podofo-1.0.1/src/podofo/main/PdfFontConfigWrapper.h 2025-06-21 23:47:21.000000000 +0200 +++ new/podofo-1.0.2/src/podofo/main/PdfFontConfigWrapper.h 2025-08-28 23:08:39.000000000 +0200 @@ -47,11 +47,13 @@ */ PdfFontConfigWrapper(const std::string_view& configStr); -#if PODOFO_3RDPARTY_INTEROP_ENABLED + PdfFontConfigWrapper(); + +#ifdef PODOFO_3RDPARTY_INTEROP_ENABLED /** * Create a new FontConfigWrapper and initialize the fontconfig library. */ - PdfFontConfigWrapper(FcConfig* fcConfig = nullptr); + PdfFontConfigWrapper(FcConfig* fcConfig); FcConfig* GetFcConfig(); #endif // PODOFO_3RDPARTY_INTEROP_ENABLED diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/podofo-1.0.1/src/podofo/main/PdfImage.cpp new/podofo-1.0.2/src/podofo/main/PdfImage.cpp --- old/podofo-1.0.1/src/podofo/main/PdfImage.cpp 2025-06-21 23:47:21.000000000 +0200 +++ new/podofo-1.0.2/src/podofo/main/PdfImage.cpp 2025-08-28 23:08:39.000000000 +0200 @@ -1159,48 +1159,6 @@ png_destroy_read_struct(&png, &pnginfo, (png_infopp)nullptr); } -unique_ptr<PdfXObjectForm> PdfImage::getTransformation(PdfImageOrientation orientation) -{ - Matrix transformation; - switch (orientation) - { - case PdfImageOrientation::TopRight: - transformation = Matrix(-1, 0, 0, 1, m_Width, 0); - break; - case PdfImageOrientation::BottomRight: - transformation = Matrix(-1, 0, 0, -1, m_Width, m_Height); - break; - case PdfImageOrientation::BottomLeft: - transformation = Matrix(1, 0, 0, -1, 0, m_Height); - break; - case PdfImageOrientation::LeftTop: - transformation = Matrix(0, 1, -1, 0, m_Height, 0); - break; - case PdfImageOrientation::RightTop: - transformation = Matrix(0, 1, 1, 0, 0, 0); - break; - case PdfImageOrientation::RightBottom: - transformation = Matrix(0, -1, 1, 0, 0, m_Width); - break; - case PdfImageOrientation::LeftBottom: - transformation = Matrix(0, -1, -1, 0, m_Height, m_Width); - break; - case PdfImageOrientation::TopLeft: - // This would be the identity matrix, so it requires no transformation - return nullptr; - default: - PODOFO_RAISE_ERROR_INFO(PdfErrorCode::InvalidEnumValue, "Invalid orientation"); - } - - auto actualXobj = GetDocument().CreateXObjectForm(GetRect()); - static_cast<PdfResourceOperations&>(actualXobj->GetOrCreateResources()).AddResource(PdfResourceType::XObject, "XOb1"_n, GetObject()); - PdfStringStream sstream; - PoDoFo::WriteOperator_Do(sstream, "XOb1"); - actualXobj->GetObject().GetOrCreateStream().SetData(sstream.GetString()); - - return actualXobj; -} - void PdfImage::loadFromPngContent(png_structp png, png_infop pnginfo, charbuff& buffer, PdfImageInfo& info) { png_set_sig_bytes(png, 8); @@ -1395,6 +1353,48 @@ #endif // PODOFO_HAVE_PNG_LIB +unique_ptr<PdfXObjectForm> PdfImage::getTransformation(PdfImageOrientation orientation) +{ + Matrix transformation; + switch (orientation) + { + case PdfImageOrientation::TopRight: + transformation = Matrix(-1, 0, 0, 1, m_Width, 0); + break; + case PdfImageOrientation::BottomRight: + transformation = Matrix(-1, 0, 0, -1, m_Width, m_Height); + break; + case PdfImageOrientation::BottomLeft: + transformation = Matrix(1, 0, 0, -1, 0, m_Height); + break; + case PdfImageOrientation::LeftTop: + transformation = Matrix(0, 1, -1, 0, m_Height, 0); + break; + case PdfImageOrientation::RightTop: + transformation = Matrix(0, 1, 1, 0, 0, 0); + break; + case PdfImageOrientation::RightBottom: + transformation = Matrix(0, -1, 1, 0, 0, m_Width); + break; + case PdfImageOrientation::LeftBottom: + transformation = Matrix(0, -1, -1, 0, m_Height, m_Width); + break; + case PdfImageOrientation::TopLeft: + // This would be the identity matrix, so it requires no transformation + return nullptr; + default: + PODOFO_RAISE_ERROR_INFO(PdfErrorCode::InvalidEnumValue, "Invalid orientation"); + } + + auto actualXobj = GetDocument().CreateXObjectForm(GetRect()); + static_cast<PdfResourceOperations&>(actualXobj->GetOrCreateResources()).AddResource(PdfResourceType::XObject, "XOb1"_n, GetObject()); + PdfStringStream sstream; + PoDoFo::WriteOperator_Do(sstream, "XOb1"); + actualXobj->GetObject().GetOrCreateStream().SetData(sstream.GetString()); + + return actualXobj; +} + void PdfImage::SetChromaKeyMask(int64_t r, int64_t g, int64_t b, int64_t threshold) { PdfArray array; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/podofo-1.0.1/src/podofo/main/PdfMemDocument.cpp new/podofo-1.0.2/src/podofo/main/PdfMemDocument.cpp --- old/podofo-1.0.1/src/podofo/main/PdfMemDocument.cpp 2025-06-21 23:47:21.000000000 +0200 +++ new/podofo-1.0.2/src/podofo/main/PdfMemDocument.cpp 2025-08-28 23:08:39.000000000 +0200 @@ -178,7 +178,7 @@ if (m_InitialVersion < this->GetPdfVersion()) { - if (this->GetPdfVersion() < PdfVersion::V1_0 || this->GetPdfVersion() > PdfVersion::V1_7) + if (this->GetPdfVersion() < PdfVersion::V1_0 || this->GetPdfVersion() > PdfVersion::V2_0) PODOFO_RAISE_ERROR(PdfErrorCode::ValueOutOfRange); GetCatalog().GetDictionary().AddKey("Version"_n, PoDoFo::GetPdfVersionName(GetPdfVersion())); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/podofo-1.0.1/src/podofo/main/PdfPage_TextExtraction.cpp new/podofo-1.0.2/src/podofo/main/PdfPage_TextExtraction.cpp --- old/podofo-1.0.1/src/podofo/main/PdfPage_TextExtraction.cpp 2025-06-21 23:47:21.000000000 +0200 +++ new/podofo-1.0.2/src/podofo/main/PdfPage_TextExtraction.cpp 2025-08-28 23:08:39.000000000 +0200 @@ -28,8 +28,6 @@ constexpr double SAME_LINE_THRESHOLD = 0.01; constexpr double SEPARATION_EPSILON = 0.0000001; -// Inferred empirically on Adobe Acrobat Pro -constexpr unsigned HARD_SEPARATION_SPACING_MULTIPLIER = 6; #define ASSERT(condition, message, ...) if (!condition)\ PoDoFo::LogMessage(PdfLogSeverity::Warning, message, ##__VA_ARGS__); @@ -52,13 +50,14 @@ double T_l = 0; // Leading text Tl PdfTextState PdfState; Vector2 WordSpacingVectorRaw; - Vector2 SpaceCharVectorRaw; + Vector2 HardSpacingVectorRaw; double WordSpacingLength = 0; - double CharSpaceLength = 0; + double HardSpacingLength = 0; void ComputeDependentState(); void ComputeSpaceDescriptors(); void ComputeT_rm(); double GetWordSpacingLength() const; + double GetHardSpacingLength() const; double GetSpaceCharLength() const; void ScanString(const PdfString& encodedStr, string& decoded, vector<double>& lengths, vector<unsigned>& positions); }; @@ -900,8 +899,8 @@ void ExtractionContext::Tf_Operator(const PdfName &fontname, double fontsize) { auto resources = getActualCanvas().GetResources(); - double spacingLengthRaw = 0; - double spaceCharLengthRaw = 0; + double wordSpacingLengthRaw = 0; + double hardSpacingLengthRaw = 0; States.Current->PdfState.FontSize = fontsize; if (resources == nullptr || (States.Current->PdfState.Font = resources->GetFont(fontname)) == nullptr) { @@ -909,22 +908,22 @@ } else { - spacingLengthRaw = States.Current->GetWordSpacingLength(); - spaceCharLengthRaw = States.Current->GetSpaceCharLength(); + wordSpacingLengthRaw = States.Current->GetWordSpacingLength(); + hardSpacingLengthRaw = States.Current->GetHardSpacingLength(); } - States.Current->WordSpacingVectorRaw = Vector2(spacingLengthRaw, 0); - if (spacingLengthRaw == 0) + States.Current->WordSpacingVectorRaw = Vector2(wordSpacingLengthRaw, 0); + if (wordSpacingLengthRaw == 0) { PoDoFo::LogMessage(PdfLogSeverity::Warning, "Unable to provide a word spacing length, setting default font size"); States.Current->WordSpacingVectorRaw = Vector2(fontsize, 0); } - States.Current->SpaceCharVectorRaw = Vector2(spaceCharLengthRaw, 0); - if (spaceCharLengthRaw == 0) + States.Current->HardSpacingVectorRaw = Vector2(hardSpacingLengthRaw, 0); + if (hardSpacingLengthRaw == 0) { - PoDoFo::LogMessage(PdfLogSeverity::Warning, "Unable to provide a space char length, setting default font size"); - States.Current->SpaceCharVectorRaw = Vector2(fontsize, 0); + PoDoFo::LogMessage(PdfLogSeverity::Warning, "Unable to provide a hard spacing length, setting default font size"); + States.Current->HardSpacingVectorRaw = Vector2(fontsize, 0); } States.Current->ComputeSpaceDescriptors(); @@ -1050,7 +1049,7 @@ { if (Options.TokenizeWords || distance + SEPARATION_EPSILON > - States.Current->CharSpaceLength * HARD_SEPARATION_SPACING_MULTIPLIER) + States.Current->HardSpacingLength) { // Current entry is space separated and either we // tokenize words, or it's an hard entry separation @@ -1255,7 +1254,7 @@ void TextState::ComputeSpaceDescriptors() { WordSpacingLength = (WordSpacingVectorRaw * T_m.GetScalingRotation()).GetLength(); - CharSpaceLength = (SpaceCharVectorRaw * T_m.GetScalingRotation()).GetLength(); + HardSpacingLength = (HardSpacingVectorRaw * T_m.GetScalingRotation()).GetLength(); } void TextState::ComputeT_rm() @@ -1268,6 +1267,11 @@ return PdfState.Font->GetWordSpacingLength(PdfState); } +double TextState::GetHardSpacingLength() const +{ + return PdfState.Font->GetHardSpacingLength(PdfState); +} + double TextState::GetSpaceCharLength() const { return PdfState.Font->GetSpaceCharLength(PdfState); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/podofo-1.0.1/src/podofo/main/PdfTokenizer.cpp new/podofo-1.0.2/src/podofo/main/PdfTokenizer.cpp --- old/podofo-1.0.1/src/podofo/main/PdfTokenizer.cpp 2025-06-21 23:47:21.000000000 +0200 +++ new/podofo-1.0.2/src/podofo/main/PdfTokenizer.cpp 2025-08-28 23:08:39.000000000 +0200 @@ -304,7 +304,7 @@ // Don't consume the token this->EnqueueToken(token, tokenType); PoDoFo::LogMessage(PdfLogSeverity::Warning, "Invalid real while parsing content"); - return PdfLiteralDataType::Unknown; + goto Recovery; } new(&variant.m_Real)PdfVariant::PrimitiveMember(val); @@ -318,7 +318,7 @@ // Don't consume the token this->EnqueueToken(token, tokenType); PoDoFo::LogMessage(PdfLogSeverity::Warning, "Invalid number while parsing content"); - return PdfLiteralDataType::Unknown; + goto Recovery; } if (!m_options.ReadReferences) @@ -382,6 +382,7 @@ } else { + Recovery: new(&variant.m_Null)PdfVariant::NullMember(); return PdfLiteralDataType::Unknown; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/podofo-1.0.1/src/podofo/main/PdfXMPPacket.cpp new/podofo-1.0.2/src/podofo/main/PdfXMPPacket.cpp --- old/podofo-1.0.1/src/podofo/main/PdfXMPPacket.cpp 2025-06-21 23:47:21.000000000 +0200 +++ new/podofo-1.0.2/src/podofo/main/PdfXMPPacket.cpp 2025-08-28 23:08:39.000000000 +0200 @@ -113,6 +113,7 @@ void PdfXMPPacket::ToString(string& str) const { + str.clear(); serializeXMPMetadataTo(str, m_Doc); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/podofo-1.0.1/src/podofo/main/PdfXMPPacket.h new/podofo-1.0.2/src/podofo/main/PdfXMPPacket.h --- old/podofo-1.0.1/src/podofo/main/PdfXMPPacket.h 2025-06-21 23:47:21.000000000 +0200 +++ new/podofo-1.0.2/src/podofo/main/PdfXMPPacket.h 2025-08-28 23:08:39.000000000 +0200 @@ -38,7 +38,7 @@ #if PODOFO_3RDPARTY_INTEROP_ENABLED xmlDocPtr GetDoc() { return m_Doc; } xmlNodePtr GetOrCreateDescription(); - xmlNodePtr GetDescription() const { return m_Description; } + xmlNodePtr GetDescription() { return m_Description; } #endif // PODOFO_3RDPARTY_INTEROP_ENABLED public: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/podofo-1.0.1/src/podofo/private/PdfParser.cpp new/podofo-1.0.2/src/podofo/private/PdfParser.cpp --- old/podofo-1.0.1/src/podofo/private/PdfParser.cpp 2025-06-21 23:47:21.000000000 +0200 +++ new/podofo-1.0.2/src/podofo/private/PdfParser.cpp 2025-08-28 23:08:39.000000000 +0200 @@ -78,12 +78,6 @@ } catch (PdfError& e) { - if (e.GetCode() == PdfErrorCode::InvalidPassword) - { - // Do not clean up, expect user to call ParseFile again - throw; - } - // If this is being called from a constructor then the // destructor will not be called. // Clean up here @@ -768,8 +762,8 @@ // in a second pass, or (if demand loading is enabled) defer it for later. for (auto objToLoad : *m_Objects) { - auto obj = dynamic_cast<PdfParserObject*>(objToLoad); - obj->ParseStream(); + auto parserObj = dynamic_cast<PdfParserObject*>(objToLoad); + parserObj->ParseStream(); } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/podofo-1.0.1/src/podofo/private/charconv_compat.h new/podofo-1.0.2/src/podofo/private/charconv_compat.h --- old/podofo-1.0.1/src/podofo/private/charconv_compat.h 2025-06-21 23:47:21.000000000 +0200 +++ new/podofo-1.0.2/src/podofo/private/charconv_compat.h 2025-08-28 23:08:39.000000000 +0200 @@ -7,7 +7,7 @@ #if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 10 #define WANT_CHARS_FORMAT #endif -#if (defined(__GNUC__) && !defined(__clang__) && !defined(__MINGW32__) && __GNUC__ < 11) || (defined(__MINGW32__) && __GNUC__ < 12) || defined(__clang__) +#if (defined(__GNUC__) && !defined(__clang__) && !defined(__MINGW32__) && __GNUC__ < 11) || (defined(__MINGW32__) && __GNUC__ < 12) || (defined(__clang__) && defined(_LIBCPP_VERSION) && (_LIBCPP_VERSION < 200000)) #define WANT_FROM_CHARS #endif #if (defined(__GNUC__) && !defined(__clang__) && !defined(__MINGW32__) && __GNUC__ < 11) || (defined(__MINGW32__) && __GNUC__ < 12) || (defined(__clang__) && ((defined(__apple_build_version__) && __apple_build_version__ < 15000000) || __clang_major__ < 14)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/podofo-1.0.1/test/unit/CMakeLists.txt new/podofo-1.0.2/test/unit/CMakeLists.txt --- old/podofo-1.0.1/test/unit/CMakeLists.txt 2025-06-21 23:47:21.000000000 +0200 +++ new/podofo-1.0.2/test/unit/CMakeLists.txt 2025-08-28 23:08:39.000000000 +0200 @@ -11,10 +11,10 @@ add_executable(podofo-unit ${SOURCE_FILES}) target_link_libraries(podofo-unit podofo_test + OpenSSL::Crypto ${PODOFO_LIBRARIES} podofo_private podofo_3rdparty - ${PODOFO_LIB_DEPENDS} ) add_compile_options(${PODOFO_CFLAGS}) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/podofo-1.0.1/test/unit/main.cpp new/podofo-1.0.2/test/unit/main.cpp --- old/podofo-1.0.1/test/unit/main.cpp 2025-06-21 23:47:21.000000000 +0200 +++ new/podofo-1.0.2/test/unit/main.cpp 2025-08-28 23:08:39.000000000 +0200 @@ -16,17 +16,23 @@ int main(int argc, char* argv[]) { - PdfCommon::SetMaxLoggingSeverity(PdfLogSeverity::Warning); - - // Add a fonts directory for more consistents run - auto fontPath = TestUtils::GetTestInputPath() / "Fonts"; - if (!fs::exists(fontPath)) + // Avoid performing test initialization on Catch2 query for tests, + // which it does with switches "--list-test-names-only" and "--list-reporters" + if (argc <= 1 || string_view(argv[1]).find("--list") == string_view::npos) { - throw runtime_error("Missing Fonts directory. Ensure you have correctly " - "fetched \"extern/resources\" git submodule"); + PdfCommon::SetMaxLoggingSeverity(PdfLogSeverity::Warning); + + // Add a fonts directory for more consistents run + auto fontPath = TestUtils::GetTestInputPath() / "Fonts"; + if (!fs::exists(fontPath)) + { + throw runtime_error("Missing Fonts directory. Ensure you have correctly " + "fetched \"extern/resources\" git submodule"); + } + + PdfCommon::AddFontDirectory(fontPath.u8string()); + PdfCommon::SetMaxLoggingSeverity(PdfLogSeverity::Warning); } - PdfCommon::AddFontDirectory(fontPath.u8string()); - PdfCommon::SetMaxLoggingSeverity(PdfLogSeverity::Warning); return Catch::Session().run(argc, argv); }