8 Commits

Author SHA1 Message Date
41ac7a0b4b Changelog. 2025-01-18 09:45:29 -05:00
5fc571b711 Merge pull request #89 from vlasovsoft1979/master
Fix undefined behavior in _pdfioFileSeek
2025-01-18 09:42:58 -05:00
acf27d29c6 Fix undefined behavior 2025-01-18 13:56:25 +03:00
026f653e07 Fix loading of last 1024 bytes for small PDF files (Issue #87) 2025-01-17 16:58:33 -05:00
3bc041e6d3 Delay loading of the Info object and clean up the pdfioinfo example (Issue #87) 2025-01-17 16:50:30 -05:00
fbd61d1fe9 Bump copyright and version, changelog for example makefile fix. 2025-01-10 14:54:11 -05:00
ee2794199c Merge pull request #86 from tlaronde/master
examples/Makefile: libm is not added by default by all
2025-01-10 14:50:44 -05:00
31c3400f23 examples/Makefile: libm is not added by default by all
-lm has to be added for system/compilers that don't add the lib by
default (the case on NetBSD).
2025-01-10 20:18:06 +01:00
15 changed files with 117 additions and 57 deletions

View File

@ -2,7 +2,16 @@ Changes in PDFio
================
v1.4.0 - YYYY-MM-DD
v1.4.1 - YYYY-MM-DD
-------------------
- Fixed the link libraries for the example source code (Issue #86)
- Fixed handling of the Info object (Issue #87)
- Fixed opening of PDF files less than 1024 bytes in length (Issue #87)
- Fixed potential `NULL` dereference when reading (Issue #89)
v1.4.0 - 2024-12-26
-------------------
- Added new `pdfioDictGetKey` and `pdfioDictGetNumPairs` APIs (Issue #63)

View File

@ -1,7 +1,7 @@
#
# Makefile for PDFio.
#
# Copyright © 2021-2024 by Michael R Sweet.
# Copyright © 2021-2025 by Michael R Sweet.
#
# Licensed under Apache License v2.0. See the file "LICENSE" for more
# information.
@ -246,7 +246,7 @@ ttf.o: ttf.h
# Make documentation using Codedoc <https://www.msweet.org/codedoc>
DOCFLAGS = \
--author "Michael R Sweet" \
--copyright "Copyright (c) 2021-2024 by Michael R Sweet" \
--copyright "Copyright (c) 2021-2025 by Michael R Sweet" \
--docversion $(PDFIO_VERSION)
.PHONY: doc

2
NOTICE
View File

@ -1,6 +1,6 @@
PDFio - PDF Read/Write Library
Copyright © 2021-2024 by Michael R Sweet.
Copyright © 2021-2025 by Michael R Sweet.
(Optional) Exceptions to the Apache 2.0 License:
================================================

View File

@ -89,7 +89,7 @@ generates a static library that will be installed under "/usr/local" with:
Legal Stuff
-----------
PDFio is Copyright © 2021-2024 by Michael R Sweet.
PDFio is Copyright © 2021-2025 by Michael R Sweet.
This software is licensed under the Apache License Version 2.0 with an
(optional) exception to allow linking against GPL2/LGPL2 software. See the

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.4.0.
# Generated by GNU Autoconf 2.71 for pdfio 1.4.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.4.0'
PACKAGE_STRING='pdfio 1.4.0'
PACKAGE_VERSION='1.4.1'
PACKAGE_STRING='pdfio 1.4.1'
PACKAGE_BUGREPORT='https://github.com/michaelrsweet/pdfio/issues'
PACKAGE_URL='https://www.msweet.org/pdfio'
@ -1293,7 +1293,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.4.0 to adapt to many kinds of systems.
\`configure' configures pdfio 1.4.1 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@ -1359,7 +1359,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of pdfio 1.4.0:";;
short | recursive ) echo "Configuration of pdfio 1.4.1:";;
esac
cat <<\_ACEOF
@ -1456,7 +1456,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
pdfio configure 1.4.0
pdfio configure 1.4.1
generated by GNU Autoconf 2.71
Copyright (C) 2021 Free Software Foundation, Inc.
@ -1612,7 +1612,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.4.0, which was
It was created by pdfio $as_me 1.4.1, which was
generated by GNU Autoconf 2.71. Invocation command line was
$ $0$ac_configure_args_raw
@ -2368,9 +2368,9 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
PDFIO_VERSION="1.4.0"
PDFIO_VERSION_MAJOR="`echo 1.4.0 | awk -F. '{print $1}'`"
PDFIO_VERSION_MINOR="`echo 1.4.0 | awk -F. '{printf("%d\n",$2);}'`"
PDFIO_VERSION="1.4.1"
PDFIO_VERSION_MAJOR="`echo 1.4.1 | awk -F. '{print $1}'`"
PDFIO_VERSION_MINOR="`echo 1.4.1 | awk -F. '{printf("%d\n",$2);}'`"
@ -4935,7 +4935,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.4.0, which was
This file was extended by pdfio $as_me 1.4.1, which was
generated by GNU Autoconf 2.71. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@ -4991,7 +4991,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.4.0
pdfio config.status 1.4.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.4.0], [https://github.com/michaelrsweet/pdfio/issues], [pdfio], [https://www.msweet.org/pdfio])
AC_INIT([pdfio], [1.4.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}'`"

View File

@ -1,4 +1,4 @@
.TH pdfio 3 "pdf read/write library" "2024-12-26" "pdf read/write library"
.TH pdfio 3 "pdf read/write library" "2025-01-17" "pdf read/write library"
.SH NAME
pdfio \- pdf read/write library
.SH Introduction
@ -1045,9 +1045,11 @@ The pdfioinfo.c example program opens a PDF file and prints the title, author, c
{
const char *filename; // PDF filename
pdfio_file_t *pdf; // PDF file
const char *author; // Author name
time_t creation_date; // Creation date
struct tm *creation_tm; // Creation date/time information
char creation_text[256]; // Creation date/time as a string
const char *title; // Title
// Get the filename from the command\-line...
@ -1065,15 +1067,25 @@ The pdfioinfo.c example program opens a PDF file and prints the title, author, c
if (pdf == NULL)
return (1);
// Get the title and author...
author = pdfioFileGetAuthor(pdf);
title = pdfioFileGetTitle(pdf);
// Get the creation date and convert to a string...
creation_date = pdfioFileGetCreationDate(pdf);
creation_tm = localtime(&creation_date);
strftime(creation_text, sizeof(creation_text), "%c", creation_tm);
if ((creation_date = pdfioFileGetCreationDate(pdf)) > 0)
{
creation_tm = localtime(&creation_date);
strftime(creation_text, sizeof(creation_text), "%c", creation_tm);
}
else
{
snprintf(creation_text, sizeof(creation_text), "\-\- not set \-\-");
}
// Print file information to stdout...
printf("%s:\\n", filename);
printf(" Title: %s\\n", pdfioFileGetTitle(pdf));
printf(" Author: %s\\n", pdfioFileGetAuthor(pdf));
printf(" Title: %s\\n", title ? title : "\-\- not set \-\-");
printf(" Author: %s\\n", author ? author : "\-\- not set \-\-");
printf(" Created On: %s\\n", creation_text);
printf(" Number Pages: %u\\n", (unsigned)pdfioFileGetNumPages(pdf));
@ -2062,7 +2074,7 @@ The render_line function adds content from the linefrag_t array to a PDF page. I
}
.fi
.PP
We then loops through the fragments for the current line, drawing checkboxes, images, and text as needed. When a hyperlink is present, we add the link to the links array in the docdata_t structure, mapping "@" and "@@" to an internal link corresponding to the linked text:
We then loops through the fragments for the current line, drawing checkboxes, images, and text as needed. Whan a hyperlink is present, we add the link to the links array in the docdata_t structure, mapping "@" and "@@" to an internal link corresponding to the linked text:
.nf
if (frag\->url && dd\->num_links < DOCLINK_MAX)
@ -2070,7 +2082,7 @@ We then loops through the fragments for the current line, drawing checkboxes, im
doclink_t *l = dd\->links + dd\->num_links;
// Pointer to this link record
if (!strcmp(frag\->url, "@"))
if (!strcmp(frag\->url, "@"))
{
// Use mapped text as link target...
char targetlink[129]; // Targeted link

View File

@ -1161,9 +1161,11 @@ main(<span class="reserved">int</span> argc, <span clas
{
<span class="reserved">const</span> <span class="reserved">char</span> *filename; <span class="comment">// PDF filename</span>
pdfio_file_t *pdf; <span class="comment">// PDF file</span>
<span class="reserved">const</span> <span class="reserved">char</span> *author; <span class="comment">// Author name</span>
time_t creation_date; <span class="comment">// Creation date</span>
<span class="reserved">struct</span> tm *creation_tm; <span class="comment">// Creation date/time information</span>
<span class="reserved">char</span> creation_text[<span class="number">256</span>]; <span class="comment">// Creation date/time as a string</span>
<span class="reserved">const</span> <span class="reserved">char</span> *title; <span class="comment">// Title</span>
<span class="comment">// Get the filename from the command-line...</span>
@ -1181,15 +1183,25 @@ main(<span class="reserved">int</span> argc, <span clas
<span class="reserved">if</span> (pdf == NULL)
<span class="reserved">return</span> (<span class="number">1</span>);
<span class="comment">// Get the title and author...</span>
author = pdfioFileGetAuthor(pdf);
title = pdfioFileGetTitle(pdf);
<span class="comment">// Get the creation date and convert to a string...</span>
creation_date = pdfioFileGetCreationDate(pdf);
creation_tm = localtime(&amp;creation_date);
strftime(creation_text, <span class="reserved">sizeof</span>(creation_text), <span class="string">&quot;%c&quot;</span>, creation_tm);
<span class="reserved">if</span> ((creation_date = pdfioFileGetCreationDate(pdf)) &gt; <span class="number">0</span>)
{
creation_tm = localtime(&amp;creation_date);
strftime(creation_text, <span class="reserved">sizeof</span>(creation_text), <span class="string">&quot;%c&quot;</span>, creation_tm);
}
<span class="reserved">else</span>
{
snprintf(creation_text, <span class="reserved">sizeof</span>(creation_text), <span class="string">&quot;-- not set --&quot;</span>);
}
<span class="comment">// Print file information to stdout...</span>
printf(<span class="string">&quot;%s:\n&quot;</span>, filename);
printf(<span class="string">&quot; Title: %s\n&quot;</span>, pdfioFileGetTitle(pdf));
printf(<span class="string">&quot; Author: %s\n&quot;</span>, pdfioFileGetAuthor(pdf));
printf(<span class="string">&quot; Title: %s\n&quot;</span>, title ? title : <span class="string">&quot;-- not set --&quot;</span>);
printf(<span class="string">&quot; Author: %s\n&quot;</span>, author ? author : <span class="string">&quot;-- not set --&quot;</span>);
printf(<span class="string">&quot; Created On: %s\n&quot;</span>, creation_text);
printf(<span class="string">&quot; Number Pages: %u\n&quot;</span>, (<span class="reserved">unsigned</span>)pdfioFileGetNumPages(pdf));
@ -2022,13 +2034,13 @@ dd-&gt;y -= margin_top + lineheight;
dd-&gt;y -= lineheight;
}
</code></pre>
<p>We then loops through the fragments for the current line, drawing checkboxes, images, and text as needed. When a hyperlink is present, we add the link to the <code>links</code> array in the <code>docdata_t</code> structure, mapping &quot;@&quot; and &quot;@@&quot; to an internal link corresponding to the linked text:</p>
<p>We then loops through the fragments for the current line, drawing checkboxes, images, and text as needed. Wh<EFBFBD>n a hyperlink is present, we add the link to the <code>links</code> array in the <code>docdata_t</code> structure, mapping &quot;@&quot; and &quot;@@&quot; to an internal link corresponding to the linked text:</p>
<pre><code class="language-c"><span class="reserved">if</span> (frag-&gt;url &amp;&amp; dd-&gt;num_links &lt; DOCLINK_MAX)
{
doclink_t *l = dd-&gt;links + dd-&gt;num_links;
<span class="comment">// Pointer to this link record</span>
<EFBFBD><span class="reserved">if</span> (!strcmp(frag-&gt;url, <span class="string">&quot;@&quot;</span>))
<span class="reserved">if</span> (!strcmp(frag-&gt;url, <span class="string">&quot;@&quot;</span>))
{
<span class="comment">// Use mapped text as link target...</span>
<span class="reserved">char</span> targetlink[<span class="number">129</span>]; <span class="comment">// Targeted link</span>

View File

@ -886,9 +886,11 @@ main(int argc, // I - Number of command-line arguments
{
const char *filename; // PDF filename
pdfio_file_t *pdf; // PDF file
const char *author; // Author name
time_t creation_date; // Creation date
struct tm *creation_tm; // Creation date/time information
char creation_text[256]; // Creation date/time as a string
const char *title; // Title
// Get the filename from the command-line...
@ -906,15 +908,25 @@ main(int argc, // I - Number of command-line arguments
if (pdf == NULL)
return (1);
// Get the title and author...
author = pdfioFileGetAuthor(pdf);
title = pdfioFileGetTitle(pdf);
// Get the creation date and convert to a string...
creation_date = pdfioFileGetCreationDate(pdf);
creation_tm = localtime(&creation_date);
strftime(creation_text, sizeof(creation_text), "%c", creation_tm);
if ((creation_date = pdfioFileGetCreationDate(pdf)) > 0)
{
creation_tm = localtime(&creation_date);
strftime(creation_text, sizeof(creation_text), "%c", creation_tm);
}
else
{
snprintf(creation_text, sizeof(creation_text), "-- not set --");
}
// Print file information to stdout...
printf("%s:\n", filename);
printf(" Title: %s\n", pdfioFileGetTitle(pdf));
printf(" Author: %s\n", pdfioFileGetAuthor(pdf));
printf(" Title: %s\n", title ? title : "-- not set --");
printf(" Author: %s\n", author ? author : "-- not set --");
printf(" Created On: %s\n", creation_text);
printf(" Number Pages: %u\n", (unsigned)pdfioFileGetNumPages(pdf));

View File

@ -1,7 +1,7 @@
#
# Makefile for PDFio examples.
#
# 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.
@ -15,7 +15,7 @@
CFLAGS = -g $(CPPFLAGS)
#CFLAGS = -g -fsanitize=address $(CPPFLAGS)
CPPFLAGS = -I.. -I/usr/local/include
LIBS = -L.. -L/usr/local/lib -lpdfio -lz
LIBS = -L.. -L/usr/local/lib -lpdfio -lz -lm
# Targets

View File

@ -1,7 +1,7 @@
//
// PDF metadata example for PDFio.
//
// Copyright © 2023-2024 by Michael R Sweet.
// Copyright © 2023-2025 by Michael R Sweet.
//
// Licensed under Apache License v2.0. See the file "LICENSE" for more
// information.
@ -25,9 +25,11 @@ main(int argc, // I - Number of command-line arguments
{
const char *filename; // PDF filename
pdfio_file_t *pdf; // PDF file
const char *author; // Author name
time_t creation_date; // Creation date
struct tm *creation_tm; // Creation date/time information
char creation_text[256]; // Creation date/time as a string
const char *title; // Title
// Get the filename from the command-line...
@ -46,15 +48,25 @@ main(int argc, // I - Number of command-line arguments
if (pdf == NULL)
return (1);
// Get the title and author...
author = pdfioFileGetAuthor(pdf);
title = pdfioFileGetTitle(pdf);
// Get the creation date and convert to a string...
creation_date = pdfioFileGetCreationDate(pdf);
creation_tm = localtime(&creation_date);
strftime(creation_text, sizeof(creation_text), "%c", creation_tm);
if ((creation_date = pdfioFileGetCreationDate(pdf)) > 0)
{
creation_tm = localtime(&creation_date);
strftime(creation_text, sizeof(creation_text), "%c", creation_tm);
}
else
{
snprintf(creation_text, sizeof(creation_text), "-- not set --");
}
// Print file information to stdout...
printf("%s:\n", filename);
printf(" Title: %s\n", pdfioFileGetTitle(pdf));
printf(" Author: %s\n", pdfioFileGetAuthor(pdf));
printf(" Title: %s\n", title ? title : "-- not set --");
printf(" Author: %s\n", author ? author : "-- not set --");
printf(" Created On: %s\n", creation_text);
printf(" Number Pages: %u\n", (unsigned)pdfioFileGetNumPages(pdf));

View File

@ -1,7 +1,7 @@
//
// Common support functions for pdfio.
//
// Copyright © 2021-2024 by Michael R Sweet.
// Copyright © 2021-2025 by Michael R Sweet.
//
// Licensed under Apache License v2.0. See the file "LICENSE" for more
// information.
@ -368,7 +368,7 @@ _pdfioFileSeek(pdfio_file_t *pdf, // I - PDF file
if (pdf->mode == _PDFIO_MODE_READ)
{
// Reading, see if we already have the data we need...
if (whence != SEEK_END && offset >= pdf->bufpos && offset < (pdf->bufpos + pdf->bufend - pdf->buffer))
if (whence != SEEK_END && offset >= pdf->bufpos && pdf->bufend && offset < (pdf->bufpos + pdf->bufend - pdf->buffer))
{
// Yes, seek within existing buffer...
pdf->bufptr = pdf->buffer + (offset - pdf->bufpos);
@ -398,7 +398,10 @@ _pdfioFileSeek(pdfio_file_t *pdf, // I - PDF file
}
// Seek within the file...
if ((offset = lseek(pdf->fd, offset, whence)) < 0)
if ((offset = lseek(pdf->fd, offset, whence)) < 0 && whence == SEEK_END && errno == EINVAL)
offset = lseek(pdf->fd, 0, SEEK_SET);
if (offset < 0)
{
_pdfioFileError(pdf, "Unable to seek within file - %s", strerror(errno));
return (-1);

View File

@ -1,7 +1,7 @@
//
// PDF file functions for PDFio.
//
// Copyright © 2021-2024 by Michael R Sweet.
// Copyright © 2021-2025 by Michael R Sweet.
//
// Licensed under Apache License v2.0. See the file "LICENSE" for more
// information.
@ -1938,7 +1938,6 @@ load_xref(
// Save the trailer dictionary and grab the root (catalog) and info
// objects...
pdf->trailer_dict = trailer.value.dict;
pdf->info_obj = pdfioDictGetObj(pdf->trailer_dict, "Info");
pdf->encrypt_obj = pdfioDictGetObj(pdf->trailer_dict, "Encrypt");
pdf->id_array = pdfioDictGetArray(pdf->trailer_dict, "ID");
@ -2086,7 +2085,6 @@ load_xref(
// Save the trailer dictionary and grab the root (catalog) and info
// objects...
pdf->trailer_dict = trailer.value.dict;
pdf->info_obj = pdfioDictGetObj(pdf->trailer_dict, "Info");
pdf->encrypt_obj = pdfioDictGetObj(pdf->trailer_dict, "Encrypt");
pdf->id_array = pdfioDictGetArray(pdf->trailer_dict, "ID");
@ -2123,6 +2121,8 @@ load_xref(
// Once we have all of the xref tables loaded, get the important objects and
// build the pages array...
pdf->info_obj = pdfioDictGetObj(pdf->trailer_dict, "Info");
if ((pdf->root_obj = pdfioDictGetObj(pdf->trailer_dict, "Root")) == NULL)
{
_pdfioFileError(pdf, "Missing Root object.");

View File

@ -3,7 +3,7 @@
<metadata>
<id>pdfio_native</id>
<title>PDFio Library for VS2019+</title>
<version>1.4.0</version>
<version>1.4.1</version>
<authors>Michael R Sweet</authors>
<owners>michaelrsweet</owners>
<projectUrl>https://github.com/michaelrsweet/pappl</projectUrl>
@ -13,10 +13,10 @@
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>PDFio Library for VS2019+</description>
<summary>PDFio is a simple C library for reading and writing PDF files. PDFio is licensed under the Apache License Version 2.0 with an (optional) exception to allow linking against GNU GPL2-only software.</summary>
<copyright>Copyright © 2019-2024 by Michael R Sweet</copyright>
<copyright>Copyright © 2019-2025 by Michael R Sweet</copyright>
<tags>pdf file native</tags>
<dependencies>
<dependency id="pdfio_native.redist" version="1.4.0" />
<dependency id="pdfio_native.redist" version="1.4.1" />
<dependency id="zlib_native.redist" version="1.2.11" />
</dependencies>
</metadata>

View File

@ -3,7 +3,7 @@
<metadata>
<id>pdfio_native.redist</id>
<title>PDFio Library for VS2019+</title>
<version>1.4.0</version>
<version>1.4.1</version>
<authors>Michael R Sweet</authors>
<owners>michaelrsweet</owners>
<projectUrl>https://github.com/michaelrsweet/pappl</projectUrl>
@ -13,7 +13,7 @@
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>PDFio Library for VS2019+</description>
<summary>PDFio is a simple C library for reading and writing PDF files. This package provides the redistributable content for the PDFio library. PDFio is licensed under the Apache License Version 2.0 with an (optional) exception to allow linking against GNU GPL2-only software.</summary>
<copyright>Copyright © 2019-2024 by Michael R Sweet</copyright>
<copyright>Copyright © 2019-2025 by Michael R Sweet</copyright>
<tags>pdf file native</tags>
<dependencies>
<dependency id="zlib_native.redist" version="1.2.11" />