5 Commits

Author SHA1 Message Date
Michael R Sweet
932f237c3f Prep for 1.6.1 release. 2025-12-26 12:09:56 -05:00
Michael R Sweet
09198056a5 Fix the pkg-config file generation. 2025-12-21 20:24:09 -05:00
Michael R Sweet
1c9e675cf6 Bump version. 2025-12-21 19:17:27 -05:00
Michael R Sweet
f16f0c10ed Bump version. 2025-12-21 19:15:29 -05:00
Michael R Sweet
019f0e8003 Support Encrypt dictionaries as well as indirect references (Issue #139) 2025-12-21 19:03:34 -05:00
10 changed files with 100 additions and 64 deletions

View File

@@ -2,15 +2,17 @@ Changes in PDFio
================
v1.6.1 - YYYY-MM-DD
v1.6.1 - 2025-12-26
-------------------
- Added missing input checking to `pdfioFileCreateFontObjFromBase` function.
- Updated support for UTF-16 strings (Issue #141)
- Updated Xcode project to use installed PNG library.
- Fixed decryption of PDF files using an Encrypt dictionary instead of an
indirect reference (Issue #139)
- Fixed character range checking in a TTF support function.
- Fixed some clang warnings.
- Fixed the generated pkg-config file.
v1.6.0 - 2025-10-06

49
configure vendored
View File

@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.71 for pdfio 1.6.0.
# Generated by GNU Autoconf 2.71 for pdfio 1.6.1.
#
# Report bugs to <https://github.com/michaelrsweet/pdfio/issues>.
#
@@ -610,8 +610,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='pdfio'
PACKAGE_TARNAME='pdfio'
PACKAGE_VERSION='1.6.0'
PACKAGE_STRING='pdfio 1.6.0'
PACKAGE_VERSION='1.6.1'
PACKAGE_STRING='pdfio 1.6.1'
PACKAGE_BUGREPORT='https://github.com/michaelrsweet/pdfio/issues'
PACKAGE_URL='https://www.msweet.org/pdfio'
@@ -653,7 +653,7 @@ WARNINGS
CSFLAGS
LIBPDFIO_STATIC
LIBPDFIO
PKGCONFIG_LIBPNG
PKGCONFIG_REQUIRES_PRIVATE
PKGCONFIG_REQUIRES
PKGCONFIG_LIBS_PRIVATE
PKGCONFIG_LIBS
@@ -1295,7 +1295,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
\`configure' configures pdfio 1.6.0 to adapt to many kinds of systems.
\`configure' configures pdfio 1.6.1 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1361,7 +1361,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of pdfio 1.6.0:";;
short | recursive ) echo "Configuration of pdfio 1.6.1:";;
esac
cat <<\_ACEOF
@@ -1460,7 +1460,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
pdfio configure 1.6.0
pdfio configure 1.6.1
generated by GNU Autoconf 2.71
Copyright (C) 2021 Free Software Foundation, Inc.
@@ -1678,7 +1678,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
It was created by pdfio $as_me 1.6.0, which was
It was created by pdfio $as_me 1.6.1, which was
generated by GNU Autoconf 2.71. Invocation command line was
$ $0$ac_configure_args_raw
@@ -2434,9 +2434,9 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
PDFIO_VERSION="1.6.0"
PDFIO_VERSION_MAJOR="`echo 1.6.0 | awk -F. '{print $1}'`"
PDFIO_VERSION_MINOR="`echo 1.6.0 | awk -F. '{printf("%d\n",$2);}'`"
PDFIO_VERSION="1.6.1"
PDFIO_VERSION_MAJOR="`echo 1.6.1 | awk -F. '{print $1}'`"
PDFIO_VERSION_MINOR="`echo 1.6.1 | awk -F. '{printf("%d\n",$2);}'`"
@@ -4138,7 +4138,9 @@ fi
PKGCONFIG_CFLAGS="-I\${includedir}"
PKGCONFIG_LIBS="-L\${libdir} -lpdfio"
PKGCONFIG_LIBS_PRIVATE="-lm"
PKGCONFIG_REQUIRES="zlib"
PKBCONFIG_REQUIRES=""
PKGCONFIG_REQUIRES_PRIVATE=""
@@ -4154,6 +4156,7 @@ then :
printf "%s\n" "yes" >&6; }
CPPFLAGS="$($PKGCONFIG --cflags zlib) $CPPFLAGS"
LIBS="$($PKGCONFIG --libs zlib) $LIBS"
PKGCONFIG_REQUIRES_PRIVATE="zlib"
else $as_nop
@@ -4216,7 +4219,6 @@ then :
fi
PKGCONFIG_REQUIRES=""
PKGCONFIG_LIBS_PRIVATE="-lz $PKGCONFIG_LIBS_PRIVATE"
fi
@@ -4228,9 +4230,6 @@ then :
fi
PKGCONFIG_LIBPNG=""
if test "x$PKGCONFIG" != x -a x$enable_libpng != xno
then :
@@ -4246,8 +4245,16 @@ printf "%s\n" "#define HAVE_LIBPNG 1" >>confdefs.h
CPPFLAGS="$($PKGCONFIG --cflags libpng16) -DHAVE_LIBPNG=1 $CPPFLAGS"
LIBS="$($PKGCONFIG --libs libpng16) -lz $LIBS"
PKGCONFIG_LIBS_PRIVATE="$($PKGCONFIG --libs libpng16) $PKGCONFIG_LIBS_PRIVATE"
PKGCONFIG_REQUIRES="libpng >= 1.6,$PKGCONFIG_REQUIRES"
if test "x$PKGCONFIG_REQUIRES_PRIVATE" = x
then :
PKGCONFIG_REQUIRES_PRIVATE="libpng >= 1.6"
else $as_nop
PKGCONFIG_REQUIRES_PRIVATE="libpng >= 1.6, $PKGCONFIG_REQUIRES_PRIVATE"
fi
else $as_nop
@@ -4314,6 +4321,8 @@ else $as_nop
LIBPDFIO_STATIC=""
PKGCONFIG_LIBS="$PKGCONFIG_LIBS $PKGCONFIG_LIBS_PRIVATE"
PKGCONFIG_LIBS_PRIVATE=""
PKGCONFIG_REQUIRES="$PKGCONFIG_REQUIRES_PRIVATE"
PKGCONFIG_REQUIRES_PRIVATE=""
fi
@@ -5106,7 +5115,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by pdfio $as_me 1.6.0, which was
This file was extended by pdfio $as_me 1.6.1, which was
generated by GNU Autoconf 2.71. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -5162,7 +5171,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config='$ac_cs_config_escaped'
ac_cs_version="\\
pdfio config.status 1.6.0
pdfio config.status 1.6.1
configured by $0, generated by GNU Autoconf 2.71,
with options \\"\$ac_cs_config\\"

View File

@@ -21,7 +21,7 @@ AC_PREREQ([2.70])
dnl Package name and version...
AC_INIT([pdfio], [1.6.0], [https://github.com/michaelrsweet/pdfio/issues], [pdfio], [https://www.msweet.org/pdfio])
AC_INIT([pdfio], [1.6.1], [https://github.com/michaelrsweet/pdfio/issues], [pdfio], [https://www.msweet.org/pdfio])
PDFIO_VERSION="AC_PACKAGE_VERSION"
PDFIO_VERSION_MAJOR="`echo AC_PACKAGE_VERSION | awk -F. '{print $1}'`"
@@ -119,11 +119,13 @@ AC_PATH_TOOL([PKGCONFIG], [pkg-config])
PKGCONFIG_CFLAGS="-I\${includedir}"
PKGCONFIG_LIBS="-L\${libdir} -lpdfio"
PKGCONFIG_LIBS_PRIVATE="-lm"
PKGCONFIG_REQUIRES="zlib"
PKBCONFIG_REQUIRES=""
PKGCONFIG_REQUIRES_PRIVATE=""
AC_SUBST([PKGCONFIG_CFLAGS])
AC_SUBST([PKGCONFIG_LIBS])
AC_SUBST([PKGCONFIG_LIBS_PRIVATE])
AC_SUBST([PKGCONFIG_REQUIRES])
AC_SUBST([PKGCONFIG_REQUIRES_PRIVATE])
dnl ZLIB
@@ -132,6 +134,7 @@ AS_IF([$PKGCONFIG --exists zlib], [
AC_MSG_RESULT([yes])
CPPFLAGS="$($PKGCONFIG --cflags zlib) $CPPFLAGS"
LIBS="$($PKGCONFIG --libs zlib) $LIBS"
PKGCONFIG_REQUIRES_PRIVATE="zlib"
],[
AC_MSG_RESULT([no])
AC_CHECK_HEADER([zlib.h])
@@ -141,16 +144,12 @@ AS_IF([$PKGCONFIG --exists zlib], [
AC_MSG_ERROR([Sorry, this software requires zlib 1.1 or higher.])
])
PKGCONFIG_REQUIRES=""
PKGCONFIG_LIBS_PRIVATE="-lz $PKGCONFIG_LIBS_PRIVATE"
])
dnl libpng...
AC_ARG_ENABLE([libpng], AS_HELP_STRING([--enable-libpng], [use libpng for pdfioFileCreateImageObjFromFile, default=auto]))
PKGCONFIG_LIBPNG=""
AC_SUBST([PKGCONFIG_LIBPNG])
AS_IF([test "x$PKGCONFIG" != x -a x$enable_libpng != xno], [
AC_MSG_CHECKING([for libpng-1.6.x])
AS_IF([$PKGCONFIG --exists libpng16], [
@@ -158,8 +157,11 @@ AS_IF([test "x$PKGCONFIG" != x -a x$enable_libpng != xno], [
AC_DEFINE([HAVE_LIBPNG], 1, [Have PNG library?])
CPPFLAGS="$($PKGCONFIG --cflags libpng16) -DHAVE_LIBPNG=1 $CPPFLAGS"
LIBS="$($PKGCONFIG --libs libpng16) -lz $LIBS"
PKGCONFIG_LIBS_PRIVATE="$($PKGCONFIG --libs libpng16) $PKGCONFIG_LIBS_PRIVATE"
PKGCONFIG_REQUIRES="libpng >= 1.6,$PKGCONFIG_REQUIRES"
AS_IF([test "x$PKGCONFIG_REQUIRES_PRIVATE" = x], [
PKGCONFIG_REQUIRES_PRIVATE="libpng >= 1.6"
], [
PKGCONFIG_REQUIRES_PRIVATE="libpng >= 1.6, $PKGCONFIG_REQUIRES_PRIVATE"
])
], [
AC_MSG_RESULT([no]);
AS_IF([test x$enable_libpng = xyes], [
@@ -192,6 +194,8 @@ AS_IF([test x$enable_shared = xyes], [
LIBPDFIO_STATIC=""
PKGCONFIG_LIBS="$PKGCONFIG_LIBS $PKGCONFIG_LIBS_PRIVATE"
PKGCONFIG_LIBS_PRIVATE=""
PKGCONFIG_REQUIRES="$PKGCONFIG_REQUIRES_PRIVATE"
PKGCONFIG_REQUIRES_PRIVATE=""
])
AC_SUBST([LIBPDFIO])

View File

@@ -214,8 +214,9 @@ _pdfioCryptoLock(
pdfioObjClose(pdf->encrypt_obj);
pdf->encryption = encryption;
pdf->permissions = permissions;
pdf->encrypt_dict = dict;
pdf->encryption = encryption;
pdf->permissions = permissions;
return (true);
}
@@ -570,7 +571,6 @@ _pdfioCryptoUnlock(
{
int tries; // Number of tries
const char *password = NULL; // Password to try
pdfio_dict_t *encrypt_dict; // Encrypt objection dictionary
int version, // Version value
revision, // Revision value
length; // Key length value
@@ -590,20 +590,14 @@ _pdfioCryptoUnlock(
_pdfio_value_t *value; // Encrypt dictionary value, if any
// See if we support the type of encryption specified by the Encrypt object
// See if we support the type of encryption specified by the Encrypt
// dictionary...
if ((encrypt_dict = pdfioObjGetDict(pdf->encrypt_obj)) == NULL)
{
_pdfioFileError(pdf, "Unable to get encryption dictionary.");
return (false);
}
handler = pdfioDictGetName(pdf->encrypt_dict, "Filter");
version = (int)pdfioDictGetNumber(pdf->encrypt_dict, "V");
revision = (int)pdfioDictGetNumber(pdf->encrypt_dict, "R");
length = (int)pdfioDictGetNumber(pdf->encrypt_dict, "Length");
handler = pdfioDictGetName(encrypt_dict, "Filter");
version = (int)pdfioDictGetNumber(encrypt_dict, "V");
revision = (int)pdfioDictGetNumber(encrypt_dict, "R");
length = (int)pdfioDictGetNumber(encrypt_dict, "Length");
if ((value = _pdfioDictGetValue(encrypt_dict, "EncryptMetadata")) != NULL && value->type == PDFIO_VALTYPE_BOOLEAN)
if ((value = _pdfioDictGetValue(pdf->encrypt_dict, "EncryptMetadata")) != NULL && value->type == PDFIO_VALTYPE_BOOLEAN)
pdf->encrypt_metadata = value->value.boolean;
else
pdf->encrypt_metadata = true;
@@ -622,9 +616,9 @@ _pdfioCryptoUnlock(
pdfio_dict_t *filter; // Crypt Filter
const char *cfm; // Crypt filter method
stream_filter = pdfioDictGetName(encrypt_dict, "StmF");
string_filter = pdfioDictGetName(encrypt_dict, "StrF");
cf_dict = pdfioDictGetDict(encrypt_dict, "CF");
stream_filter = pdfioDictGetName(pdf->encrypt_dict, "StmF");
string_filter = pdfioDictGetName(pdf->encrypt_dict, "StrF");
cf_dict = pdfioDictGetDict(pdf->encrypt_dict, "CF");
if (!cf_dict)
{
@@ -701,7 +695,7 @@ _pdfioCryptoUnlock(
// Grab the remaining values we need to unlock the PDF...
pdf->file_keylen = (size_t)(length / 8);
p = pdfioDictGetNumber(encrypt_dict, "P");
p = pdfioDictGetNumber(pdf->encrypt_dict, "P");
PDFIO_DEBUG("_pdfioCryptoUnlock: P=%.0f\n", p);
if (p < 0x7fffffff) // Handle integers > 2^31-1
pdf->permissions = (pdfio_permission_t)p;
@@ -709,8 +703,8 @@ _pdfioCryptoUnlock(
pdf->permissions = (pdfio_permission_t)(p - 4294967296.0);
PDFIO_DEBUG("_pdfioCryptoUnlock: permissions=%d\n", pdf->permissions);
owner_key = pdfioDictGetBinary(encrypt_dict, "O", &owner_keylen);
user_key = pdfioDictGetBinary(encrypt_dict, "U", &user_keylen);
owner_key = pdfioDictGetBinary(pdf->encrypt_dict, "O", &owner_keylen);
user_key = pdfioDictGetBinary(pdf->encrypt_dict, "U", &user_keylen);
if (!owner_key)
{

View File

@@ -2283,12 +2283,18 @@ load_xref(
{
// Save the trailer dictionary and grab the root (catalog) and info
// objects...
pdfio_obj_t *encrypt_obj; // Encryption object
pdf->trailer_dict = trailer.value.dict;
pdf->encrypt_obj = pdfioDictGetObj(pdf->trailer_dict, "Encrypt");
pdf->id_array = pdfioDictGetArray(pdf->trailer_dict, "ID");
if ((encrypt_obj = pdfioDictGetObj(pdf->trailer_dict, "Encrypt")) != NULL)
pdf->encrypt_dict = pdfioObjGetDict(encrypt_obj);
else
pdf->encrypt_dict = pdfioDictGetDict(pdf->trailer_dict, "Encrypt");
// If the trailer contains an Encrypt key, try unlocking the file...
if (pdf->encrypt_obj && !_pdfioCryptoUnlock(pdf, password_cb, password_data))
if (pdf->encrypt_dict && !_pdfioCryptoUnlock(pdf, password_cb, password_data))
return (false);
}
@@ -2434,12 +2440,18 @@ load_xref(
{
// Save the trailer dictionary and grab the root (catalog) and info
// objects...
pdfio_obj_t *encrypt_obj; // Encryption object
pdf->trailer_dict = trailer.value.dict;
pdf->encrypt_obj = pdfioDictGetObj(pdf->trailer_dict, "Encrypt");
pdf->id_array = pdfioDictGetArray(pdf->trailer_dict, "ID");
if ((encrypt_obj = pdfioDictGetObj(pdf->trailer_dict, "Encrypt")) != NULL)
pdf->encrypt_dict = pdfioObjGetDict(encrypt_obj);
else
pdf->encrypt_dict = pdfioDictGetDict(pdf->trailer_dict, "Encrypt");
// If the trailer contains an Encrypt key, try unlocking the file...
if (pdf->encrypt_obj && !_pdfioCryptoUnlock(pdf, password_cb, password_data))
if (pdf->encrypt_dict && !_pdfioCryptoUnlock(pdf, password_cb, password_data))
return (false);
}
}
@@ -2529,7 +2541,7 @@ repair_xref(
pdf->root_obj = NULL;
pdf->info_obj = NULL;
pdf->pages_obj = NULL;
pdf->encrypt_obj = NULL;
pdf->encrypt_dict = NULL;
// Read from the beginning of the file, looking for objects...
if ((line_offset = _pdfioFileSeek(pdf, 0, SEEK_SET)) < 0)
@@ -2603,10 +2615,17 @@ repair_xref(
if (!strcmp(type, "XRef") && !pdf->trailer_dict)
{
// Save the trailer dictionary...
pdfio_obj_t *encrypt_obj;
// Encryption object
PDFIO_DEBUG("repair_xref: XRef stream...\n");
pdf->trailer_dict = pdfioObjGetDict(obj);
pdf->encrypt_obj = pdfioDictGetObj(pdf->trailer_dict, "Encrypt");
pdf->id_array = pdfioDictGetArray(pdf->trailer_dict, "ID");
if ((encrypt_obj = pdfioDictGetObj(pdf->trailer_dict, "Encrypt")) != NULL)
pdf->encrypt_dict = pdfioObjGetDict(encrypt_obj);
else
pdf->encrypt_dict = pdfioDictGetDict(pdf->trailer_dict, "Encrypt");
}
}
else if (type && !strcmp(line, "endobj"))
@@ -2660,11 +2679,17 @@ repair_xref(
{
// Save the trailer dictionary and grab the root (catalog) and info
// objects...
pdfio_obj_t *encrypt_obj; // Encryption object
PDFIO_DEBUG("repair_xref: Using this trailer dictionary.\n");
pdf->trailer_dict = trailer.value.dict;
pdf->encrypt_obj = pdfioDictGetObj(pdf->trailer_dict, "Encrypt");
pdf->id_array = pdfioDictGetArray(pdf->trailer_dict, "ID");
if ((encrypt_obj = pdfioDictGetObj(pdf->trailer_dict, "Encrypt")) != NULL)
pdf->encrypt_dict = pdfioObjGetDict(encrypt_obj);
else
pdf->encrypt_dict = pdfioDictGetDict(pdf->trailer_dict, "Encrypt");
}
}
@@ -2678,7 +2703,7 @@ repair_xref(
pdf->trailer_dict = backup_trailer;
// If the trailer contains an Encrypt key, try unlocking the file...
if (pdf->encrypt_obj && !_pdfioCryptoUnlock(pdf, password_cb, password_data))
if (pdf->encrypt_dict && !_pdfioCryptoUnlock(pdf, password_cb, password_data))
return (false);
// Load any stream objects...

View File

@@ -283,7 +283,8 @@ struct _pdfio_file_s // PDF file structure
pdfio_obj_t *root_obj; // Root object/dictionary
pdfio_obj_t *info_obj; // Information object
pdfio_obj_t *pages_obj; // Root pages object
pdfio_obj_t *encrypt_obj; // De/Encryption object/dictionary
pdfio_obj_t *encrypt_obj; // Encryption object (not used for reading)
pdfio_dict_t *encrypt_dict; // De/Encryption dictionary
pdfio_obj_t *cgats001_obj, // CGATS001 ICC profile object
*cp1252_obj, // CP1252 font encoding object
*unicode_obj; // Unicode font encoding object

View File

@@ -23,7 +23,7 @@ extern "C" {
// Version numbers...
//
# define PDFIO_VERSION "1.6.0"
# define PDFIO_VERSION "1.6.1"
# define PDFIO_VERSION_MAJOR 1
# define PDFIO_VERSION_MINOR 6

View File

@@ -11,3 +11,4 @@ Cflags: @PKGCONFIG_CFLAGS@
Libs: @PKGCONFIG_LIBS@
Libs.private: @PKGCONFIG_LIBS_PRIVATE@
Requires: @PKGCONFIG_REQUIRES@
Requires.private: @PKGCONFIG_REQUIRES_PRIVATE@

View File

@@ -3,7 +3,7 @@
<metadata>
<id>pdfio_native</id>
<title>PDFio Library for VS2019+</title>
<version>1.6.0</version>
<version>1.6.1</version>
<authors>Michael R Sweet</authors>
<owners>michaelrsweet</owners>
<projectUrl>https://github.com/michaelrsweet/pappl</projectUrl>
@@ -16,7 +16,7 @@
<copyright>Copyright © 2019-2025 by Michael R Sweet</copyright>
<tags>pdf file native</tags>
<dependencies>
<dependency id="pdfio_native.redist" version="1.6.0" />
<dependency id="pdfio_native.redist" version="1.6.1" />
<dependency id="libpng_native.redist" version="1.6.30" />
<dependency id="zlib_native.redist" version="1.2.11" />
</dependencies>

View File

@@ -3,7 +3,7 @@
<metadata>
<id>pdfio_native.redist</id>
<title>PDFio Library for VS2019+</title>
<version>1.6.0</version>
<version>1.6.1</version>
<authors>Michael R Sweet</authors>
<owners>michaelrsweet</owners>
<projectUrl>https://github.com/michaelrsweet/pappl</projectUrl>