6 Commits

Author SHA1 Message Date
Michael R Sweet
dc584c0868 PDFio 1.5.4. 2025-08-26 12:33:30 -04:00
Michael R Sweet
4b7e9691b3 PDFio 1.5.4. 2025-08-26 12:32:50 -04:00
Michael R Sweet
795daba88e Fix typos. 2025-08-06 11:26:10 -04:00
Michael R Sweet
ca4f20e84c Clarify token too large errors (Issue #131) 2025-07-28 19:11:17 +01:00
Michael R Sweet
a54e2886a6 Fix copy_jpeg with invalid/corrupt JPEG data (Issue #132) 2025-07-28 19:04:17 +01:00
Michael R Sweet
d3a5fa9e0b Limit generation numbers to 0 to 65535. 2025-07-28 12:51:17 +01:00
10 changed files with 135 additions and 125 deletions

View File

@@ -2,6 +2,15 @@ Changes in PDFio
================
v1.5.4 - 2025-08-26
-------------------
- Updated indirect reference reading code to limit the range of generation
numbers.
- Updated error messages for too large tokens (Issue #131)
- Fixed a JPEG copy bug (Issue #132)
v1.5.3 - 2025-05-03
-------------------

24
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.5.3.
# Generated by GNU Autoconf 2.71 for pdfio 1.5.4.
#
# 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.5.3'
PACKAGE_STRING='pdfio 1.5.3'
PACKAGE_VERSION='1.5.4'
PACKAGE_STRING='pdfio 1.5.4'
PACKAGE_BUGREPORT='https://github.com/michaelrsweet/pdfio/issues'
PACKAGE_URL='https://www.msweet.org/pdfio'
@@ -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.5.3 to adapt to many kinds of systems.
\`configure' configures pdfio 1.5.4 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.5.3:";;
short | recursive ) echo "Configuration of pdfio 1.5.4:";;
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.5.3
pdfio configure 1.5.4
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.5.3, which was
It was created by pdfio $as_me 1.5.4, 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.5.3"
PDFIO_VERSION_MAJOR="`echo 1.5.3 | awk -F. '{print $1}'`"
PDFIO_VERSION_MINOR="`echo 1.5.3 | awk -F. '{printf("%d\n",$2);}'`"
PDFIO_VERSION="1.5.4"
PDFIO_VERSION_MAJOR="`echo 1.5.4 | awk -F. '{print $1}'`"
PDFIO_VERSION_MINOR="`echo 1.5.4 | awk -F. '{printf("%d\n",$2);}'`"
@@ -5099,7 +5099,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.5.3, which was
This file was extended by pdfio $as_me 1.5.4, which was
generated by GNU Autoconf 2.71. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -5155,7 +5155,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.5.3
pdfio config.status 1.5.4
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.5.3], [https://github.com/michaelrsweet/pdfio/issues], [pdfio], [https://www.msweet.org/pdfio])
AC_INIT([pdfio], [1.5.4], [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}'`"

View File

@@ -1,7 +1,7 @@
//
// Simple markdown to PDF converter example for PDFio.
//
// Copyright © 2024 by Michael R Sweet.
// Copyright © 2024-2025 by Michael R Sweet.
//
// Licensed under Apache License v2.0. See the file "LICENSE" for more
// information.
@@ -289,8 +289,8 @@ main(int argc, // I - Number of command-line arguments
// Get the markdown file from the command-line...
if (argc < 2 || argc > 3)
{
fputs("Usage: md2pdf FILENANE.md [FILENAME.pdf]\n", stderr);
fputs(" md2pdf FILENANE.md >FILENAME.pdf\n", stderr);
fputs("Usage: md2pdf FILENAME.md [FILENAME.pdf]\n", stderr);
fputs(" md2pdf FILENAME.md >FILENAME.pdf\n", stderr);
return (1);
}

View File

@@ -2527,110 +2527,69 @@ copy_jpeg(pdfio_dict_t *dict, // I - Dictionary
bufend += bytes;
}
if (*bufptr == _PDFIO_JPEG_MARKER)
if (*bufptr != _PDFIO_JPEG_MARKER)
{
// Start of a marker in the file...
bufptr ++;
_pdfioFileError(dict->pdf, "Invalid JPEG data: <%02X>", *bufptr);
goto finish;
}
marker = *bufptr;
length = (size_t)((bufptr[1] << 8) | bufptr[2]);
bufptr += 3;
// Start of a marker in the file...
bufptr ++;
if (marker == _PDFIO_JPEG_MARKER)
continue;
else if (marker == _PDFIO_JPEG_EOI || marker == _PDFIO_JPEG_SOS || length < 2)
break;
marker = *bufptr;
length = (size_t)((bufptr[1] << 8) | bufptr[2]);
bufptr += 3;
PDFIO_DEBUG("copy_jpeg: JPEG X'FF%02X' (length %u)\n", marker, (unsigned)length);
PDFIO_DEBUG("copy_jpeg: JPEG X'FF%02X' (length %u)\n", marker, (unsigned)length);
length -= 2;
if (marker == _PDFIO_JPEG_EOI || marker == _PDFIO_JPEG_SOS || length < 2)
break;
if ((marker >= _PDFIO_JPEG_SOF0 && marker <= _PDFIO_JPEG_SOF3) || (marker >= _PDFIO_JPEG_SOF5 && marker <= _PDFIO_JPEG_SOF7) || (marker >= _PDFIO_JPEG_SOF9 && marker <= _PDFIO_JPEG_SOF11) || (marker >= _PDFIO_JPEG_SOF13 && marker <= _PDFIO_JPEG_SOF15))
length -= 2;
if ((marker >= _PDFIO_JPEG_SOF0 && marker <= _PDFIO_JPEG_SOF3) || (marker >= _PDFIO_JPEG_SOF5 && marker <= _PDFIO_JPEG_SOF7) || (marker >= _PDFIO_JPEG_SOF9 && marker <= _PDFIO_JPEG_SOF11) || (marker >= _PDFIO_JPEG_SOF13 && marker <= _PDFIO_JPEG_SOF15))
{
// SOFn marker, look for dimensions...
//
// Byte(s) Description
// ------- -------------------
// 0 Bits per component
// 1-2 Height
// 3-4 Width
// 5 Number of colors
if (bufptr[0] != 8)
{
// SOFn marker, look for dimensions...
//
// Byte(s) Description
// ------- -------------------
// 0 Bits per component
// 1-2 Height
// 3-4 Width
// 5 Number of colors
if (bufptr[0] != 8)
{
_pdfioFileError(dict->pdf, "Unable to load %d-bit JPEG image.", bufptr[0]);
goto finish;
}
width = (unsigned)((bufptr[3] << 8) | bufptr[4]);
height = (unsigned)((bufptr[1] << 8) | bufptr[2]);
num_colors = bufptr[5];
}
else if (marker == _PDFIO_JPEG_APP2 && length > 14 && memcmp(bufptr, "ICC_PROFILE", 12))
{
// Portion of ICC profile
int n = bufptr[12], // Chunk number in profile (1-based)
count = bufptr[13]; // Number of chunks
unsigned char *icc_temp; // New ICC buffer
// Discard "ICC_PROFILE\0" and chunk number/count...
bufptr += 14;
length -= 14;
// Expand our ICC buffer...
if ((icc_temp = realloc(icc_data, icc_datalen + length)) == NULL)
return (NULL);
else
icc_data = icc_temp;
// Read the chunk into the ICC buffer...
do
{
if (bufptr >= bufend)
{
// Read more of the marker...
if ((bytes = read(fd, buffer, sizeof(buffer))) <= 0)
{
_pdfioFileError(dict->pdf, "Unable to read JPEG data - %s", strerror(errno));
goto finish;
}
bufptr = buffer;
bufend = buffer + bytes;
}
// Copy from the file buffer to the ICC buffer
if ((bytes = bufend - bufptr) > (ssize_t)length)
bytes = (ssize_t)length;
memcpy(icc_data + icc_datalen, bufptr, bytes);
icc_datalen += (size_t)bytes;
bufptr += bytes;
length -= (size_t)bytes;
}
while (length > 0);
if (n == count && width > 0 && height > 0 && num_colors > 0)
{
// Have everything we need...
break;
}
else
{
// Continue reading...
continue;
}
_pdfioFileError(dict->pdf, "Unable to load %d-bit JPEG image.", bufptr[0]);
goto finish;
}
// Skip past this marker...
while (length > 0)
width = (unsigned)((bufptr[3] << 8) | bufptr[4]);
height = (unsigned)((bufptr[1] << 8) | bufptr[2]);
num_colors = bufptr[5];
}
else if (marker == _PDFIO_JPEG_APP2 && length > 14 && memcmp(bufptr, "ICC_PROFILE", 12))
{
// Portion of ICC profile
int n = bufptr[12], // Chunk number in profile (1-based)
count = bufptr[13]; // Number of chunks
unsigned char *icc_temp; // New ICC buffer
// Discard "ICC_PROFILE\0" and chunk number/count...
bufptr += 14;
length -= 14;
// Expand our ICC buffer...
if ((icc_temp = realloc(icc_data, icc_datalen + length)) == NULL)
return (NULL);
else
icc_data = icc_temp;
// Read the chunk into the ICC buffer...
do
{
bytes = bufend - bufptr;
if (length > (size_t)bytes)
{
// Consume everything we have and grab more...
length -= (size_t)bytes;
if (bufptr >= bufend)
{
// Read more of the marker...
if ((bytes = read(fd, buffer, sizeof(buffer))) <= 0)
{
_pdfioFileError(dict->pdf, "Unable to read JPEG data - %s", strerror(errno));
@@ -2640,12 +2599,54 @@ copy_jpeg(pdfio_dict_t *dict, // I - Dictionary
bufptr = buffer;
bufend = buffer + bytes;
}
else
// Copy from the file buffer to the ICC buffer
if ((bytes = bufend - bufptr) > (ssize_t)length)
bytes = (ssize_t)length;
memcpy(icc_data + icc_datalen, bufptr, bytes);
icc_datalen += (size_t)bytes;
bufptr += bytes;
length -= (size_t)bytes;
}
while (length > 0);
if (n == count && width > 0 && height > 0 && num_colors > 0)
{
// Have everything we need...
break;
}
else
{
// Continue reading...
continue;
}
}
// Skip past this marker...
while (length > 0)
{
bytes = bufend - bufptr;
if (length > (size_t)bytes)
{
// Consume everything we have and grab more...
length -= (size_t)bytes;
if ((bytes = read(fd, buffer, sizeof(buffer))) <= 0)
{
// Enough at the end of the buffer...
bufptr += length;
length = 0;
_pdfioFileError(dict->pdf, "Unable to read JPEG data - %s", strerror(errno));
goto finish;
}
bufptr = buffer;
bufend = buffer + bytes;
}
else
{
// Enough at the end of the buffer...
bufptr += length;
length = 0;
}
}
}

View File

@@ -380,7 +380,7 @@ _pdfioTokenRead(_pdfio_token_t *tb, // I - Token buffer/stack
else
{
// Out of space
_pdfioFileError(tb->pdf, "Token too large.");
_pdfioFileError(tb->pdf, "String token too large.");
*bufptr = '\0';
return (false);
}
@@ -408,7 +408,7 @@ _pdfioTokenRead(_pdfio_token_t *tb, // I - Token buffer/stack
if ((2 * (bytes + 1)) > bufsize)
{
// Out of space...
_pdfioFileError(tb->pdf, "Token too large.");
_pdfioFileError(tb->pdf, "Binary string token too large.");
*bufptr = '\0';
return (false);
}
@@ -442,7 +442,7 @@ _pdfioTokenRead(_pdfio_token_t *tb, // I - Token buffer/stack
else
{
// Out of space...
_pdfioFileError(tb->pdf, "Token too large.");
_pdfioFileError(tb->pdf, "Keyword token too large.");
*bufptr = '\0';
return (false);
}
@@ -474,7 +474,7 @@ _pdfioTokenRead(_pdfio_token_t *tb, // I - Token buffer/stack
else
{
// Out of space...
_pdfioFileError(tb->pdf, "Token too large.");
_pdfioFileError(tb->pdf, "Number token too large.");
*bufptr = '\0';
return (false);
}
@@ -523,7 +523,7 @@ _pdfioTokenRead(_pdfio_token_t *tb, // I - Token buffer/stack
else
{
// Out of space
_pdfioFileError(tb->pdf, "Token too large.");
_pdfioFileError(tb->pdf, "Name token too large.");
*bufptr = '\0';
return (false);
}
@@ -566,7 +566,7 @@ _pdfioTokenRead(_pdfio_token_t *tb, // I - Token buffer/stack
else
{
// Too large
_pdfioFileError(tb->pdf, "Token too large.");
_pdfioFileError(tb->pdf, "Hex string token too large.");
*bufptr = '\0';
return (false);
}

View File

@@ -515,7 +515,7 @@ _pdfioValueRead(pdfio_file_t *pdf, // I - PDF file
// Integer...
long generation = 0; // Generation number
while (tempptr < tb->bufend && isdigit(*tempptr & 255))
while (tempptr < tb->bufend && generation < 65536 && isdigit(*tempptr & 255))
{
generation = generation * 10 + *tempptr - '0';
tempptr ++;

View File

@@ -23,7 +23,7 @@ extern "C" {
// Version numbers...
//
# define PDFIO_VERSION "1.5.3"
# define PDFIO_VERSION "1.5.4"
# define PDFIO_VERSION_MAJOR 1
# define PDFIO_VERSION_MINOR 5

View File

@@ -3,7 +3,7 @@
<metadata>
<id>pdfio_native</id>
<title>PDFio Library for VS2019+</title>
<version>1.5.3</version>
<version>1.5.4</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.5.3" />
<dependency id="pdfio_native.redist" version="1.5.4" />
<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.5.3</version>
<version>1.5.4</version>
<authors>Michael R Sweet</authors>
<owners>michaelrsweet</owners>
<projectUrl>https://github.com/michaelrsweet/pappl</projectUrl>