diff options
55 files changed, 2901 insertions, 68 deletions
@@ -1,3 +1,49 @@ +2015-05-24 Jay Berkenbilt <ejb@ql.org> + + * 5.1.3: release + + * Bug fix: fix-qdf was not handling object streams with more than + 255 objects in them. + + * Handle Microsoft crypt provider initialization properly for case + where no keys have been previously created, such as in a fresh + Windows installation. + + * Include time.h in QUtil.hh for time_t + +2015-02-21 Jay Berkenbilt <ejb@ql.org> + + * Detect loops in Pages structure. Thanks to Gynvael Coldwind and + Mateusz Jurczyk of the Google Security Team for providing a sample + file with this problem. + + * Prevent buffer overrun when converting a password to an + encryption key. Thanks to Gynvael Coldwind and Mateusz Jurczyk of + the Google Security Team for providing a sample file with this + problem. + + * Ensure that arguments to "R" when parsing the file are direct + objects before trying to resolve them. This prevents specially + crafted files from causing qpdf to crash with a stack overflow. + Thanks to Gynvael Coldwind and Mateusz Jurczyk of the Google + Security Team for providing a sample file with this problem. + +2014-12-01 Jay Berkenbilt <ejb@ql.org> + + * Some broken PDF files lack the required /Type key for /Page and + /Pages nodes in the page dictionary. QPDF now uses other methods + to figure out what kind of node it is looking at so that it can + handle those files. Original reported at + https://bugs.launchpad.net/ubuntu/+source/qpdf/+bug/1397413 + +2014-11-14 Jay Berkenbilt <ejb@ql.org> + + * Bug fix: QPDFObjectHandle::getPageContents() no longer throws an + exception when called on a page that has no /Contents key in its + dictionary. This is allowed by the spec, and some software + packages generate files like this for pages that are blank in the + original. + 2014-06-07 Jay Berkenbilt <ejb@ql.org> * 5.1.2: release @@ -2,7 +2,7 @@ This is the QPDF package. Information about it can be found at http://qpdf.sourceforge.net. The source code repository is hosted at github: https://github.com/qpdf/qpdf. -QPDF is copyright (c) 2005-2014 Jay Berkenbilt +QPDF is copyright (c) 2005-2015 Jay Berkenbilt This software may be distributed under the terms of version 2 of the Artistic License which may be found in the source distribution as diff --git a/README.maintainer b/README.maintainer index 42429f6..d367388 100644 --- a/README.maintainer +++ b/README.maintainer @@ -70,7 +70,7 @@ Release Reminders done or retargeted. * Each year, update copyright notices. Just do a case-insensitive - search for copyright. Last updated: 2014. + search for copyright. Last updated: 2015. * To construct a source distribution from a pristine checkout, make_dist does the following: @@ -157,3 +157,18 @@ If you want to run make maintainer-clean or make distclean and you haven't run ./configure, you can pass CLEAN=1 to make on the command line to prevent it from complaining about configure not having been run. + +Local Windows Testing Procedure +=============================== + +This is what I do for routine testing on Windows. + +From Linux, run ./autogen.sh and make autofiles.zip + +From Windows in git bash, git clone from my Linux clone, unzip +external-libs, and unzip autofiles.zip. + +Look at make_windows_releases. Set up path the same way and run +whichever ./config-* is appropriate for whichever compiler I need to +test with. Run from msys started from one of the visual studio command +line shells. The build doesn't work from git bash on my local system. @@ -1,6 +1,57 @@ +Small, command-line tool only enhancements to do soon +===================================================== + + * Handle input file = output file as a special case. See issue 29. + Behavior: detect if output file is the same as one of the input + files. If so, refuse to operate unless --allow-overwrite is + specified. In that case, write to a temporary file and, if there + are no errors or warnings, rename the temporary output file over + the input file. If rename fails, delete the temporary file. + + * Consider providing alternative methods for specifying passwords. + The methods should be general enough to use for both encryption and + decryption passwords. Example methods could be reading the password + from a file, a file descriptor, or prompting. Prompting should + never be done with being specifically requested though; we don't + want to create a situation where running qpdf might block waiting + for input where it previously did not. Test case: encrypt an + encrypted file with the output file having different user/owner + passwords. Make sure we have a predictable way to read all three + passwords (input, output user, output owner). Maybe we have + something like --password-source=<method>:<which>,... where method could + be file=/path, fd=n, or prompt and which could be one of input, + user, owner. If a password source is provided for input, it takes + precedence over --password if specified later on the command line. + If a password source is specified for output passwords, the + corresponding passwords must be '-'. If more than one password is + read from the same source, passwords are newline separated. + Trailing newlines are ignored. Example: + + qpdf --password-source=fd=3:input,owner a.pdf b.pdf + + would read two lines from file descriptor 3. The first would the + password for reading a.pdf, and the second would be the owner + password for b.pdf. The encryption arguments would specify the + actual user password for b.pdf and - as the owner password. + + qpdf --password-source=file=/tmp/a:input --password=source=prompt:user,owner + + would read the input file from /tmp/a and would prompt twice: one + for the user password and once for the owner password. + + * Consider adding "uninstall" target to makefile. It should only + uninstall what it installed, which means that you must run + uninstall from the version you ran install with. It would only be + supported for the toolchains that support the install target + (libtool). + + 5.2.0 ===== + * Before release: remember to bump minor shared library version since + new methods were added (even though private). + * Figure out what about a3576a73593987b26cd3eff346f8f7c11f713cbd broke binary compatibility. @@ -67,6 +118,10 @@ General ======= + * Figure out how to find Visual Studio in Windows registry and see if + I can get it to work with make so I can simplify creation of + Windows releases. + * Provide support in QPDFWriter for writing incremental updates. Provide support in qpdf for preserving incremental updates. The goal should be that QDF mode should be fully functional for files @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for qpdf 5.1.2. +# Generated by GNU Autoconf 2.69 for qpdf 5.1.3. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. @@ -587,8 +587,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='qpdf' PACKAGE_TARNAME='qpdf' -PACKAGE_VERSION='5.1.2' -PACKAGE_STRING='qpdf 5.1.2' +PACKAGE_VERSION='5.1.3' +PACKAGE_STRING='qpdf 5.1.3' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1313,7 +1313,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 qpdf 5.1.2 to adapt to many kinds of systems. +\`configure' configures qpdf 5.1.3 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1378,7 +1378,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of qpdf 5.1.2:";; + short | recursive ) echo "Configuration of qpdf 5.1.3:";; esac cat <<\_ACEOF @@ -1519,7 +1519,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -qpdf configure 5.1.2 +qpdf configure 5.1.3 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2059,7 +2059,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 qpdf $as_me 5.1.2, which was +It was created by qpdf $as_me 5.1.3, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -16612,7 +16612,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 qpdf $as_me 5.1.2, which was +This file was extended by qpdf $as_me 5.1.3, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -16678,7 +16678,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -qpdf config.status 5.1.2 +qpdf config.status 5.1.3 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index deb4c15..3cb458d 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ dnl Process this file with autoconf to produce a configure script. dnl This config.in requires autoconf 2.5 or greater. AC_PREREQ([2.68]) -AC_INIT([qpdf],[5.1.2]) +AC_INIT([qpdf],[5.1.3]) AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_FILES([autoconf.mk]) diff --git a/doc/qpdf-manual.html b/doc/qpdf-manual.html index 358c909..0980143 100644 --- a/doc/qpdf-manual.html +++ b/doc/qpdf-manual.html @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>QPDF Manual</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><meta name="generator" content="DocBook XSL Stylesheets V1.78.1" /></head><body><div class="book"><div class="titlepage"><div><div><h1 class="title"><a id="idp42921312"></a>QPDF Manual</h1></div><div><h2 class="subtitle">For QPDF Version 5.1.2, June 7, 2014</h2></div><div><div class="author"><h3 class="author"><span class="firstname">Jay</span> <span class="surname">Berkenbilt</span></h3></div></div><div><p class="copyright">Copyright © 2005–2014 Jay Berkenbilt</p></div></div><hr /></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="preface"><a href="#acknowledgments">General Information</a></span></dt><dt><span class="chapter"><a href="#ref.overview">1. What is QPDF?</a></span></dt><dt><span class="chapter"><a href="#ref.installing">2. Building and Installing QPDF</a></span></dt><dd><dl><dt><span class="sect1"><a href="#ref.prerequisites">2.1. System Requirements</a></span></dt><dt><span class="sect1"><a href="#ref.building">2.2. Build Instructions</a></span></dt></dl></dd><dt><span class="chapter"><a href="#ref.using">3. Running QPDF</a></span></dt><dd><dl><dt><span class="sect1"><a href="#ref.invocation">3.1. Basic Invocation</a></span></dt><dt><span class="sect1"><a href="#ref.basic-options">3.2. Basic Options</a></span></dt><dt><span class="sect1"><a href="#ref.encryption-options">3.3. Encryption Options</a></span></dt><dt><span class="sect1"><a href="#ref.page-selection">3.4. Page Selection Options</a></span></dt><dt><span class="sect1"><a href="#ref.advanced-transformation">3.5. Advanced Transformation Options</a></span></dt><dt><span class="sect1"><a href="#ref.testing-options">3.6. Testing, Inspection, and Debugging Options</a></span></dt></dl></dd><dt><span class="chapter"><a href="#ref.qdf">4. QDF Mode</a></span></dt><dt><span class="chapter"><a href="#ref.using-library">5. Using the QPDF Library</a></span></dt><dt><span class="chapter"><a href="#ref.design">6. Design and Library Notes</a></span></dt><dd><dl><dt><span class="sect1"><a href="#ref.design.intro">6.1. Introduction</a></span></dt><dt><span class="sect1"><a href="#ref.design-goals">6.2. Design Goals</a></span></dt><dt><span class="sect1"><a href="#ref.casting">6.3. Casting Policy</a></span></dt><dt><span class="sect1"><a href="#ref.encryption">6.4. Encryption</a></span></dt><dt><span class="sect1"><a href="#ref.random-numbers">6.5. Random Number Generation</a></span></dt><dt><span class="sect1"><a href="#ref.adding-and-remove-pages">6.6. Adding and Removing Pages</a></span></dt><dt><span class="sect1"><a href="#ref.reserved-objects">6.7. Reserving Object Numbers</a></span></dt><dt><span class="sect1"><a href="#ref.foreign-objects">6.8. Copying Objects From Other PDF Files</a></span></dt><dt><span class="sect1"><a href="#ref.rewriting">6.9. Writing PDF Files</a></span></dt><dt><span class="sect1"><a href="#ref.filtered-streams">6.10. Filtered Streams</a></span></dt></dl></dd><dt><span class="chapter"><a href="#ref.linearization">7. Linearization</a></span></dt><dd><dl><dt><span class="sect1"><a href="#ref.linearization-strategy">7.1. Basic Strategy for Linearization</a></span></dt><dt><span class="sect1"><a href="#ref.linearized.preparation">7.2. Preparing For Linearization</a></span></dt><dt><span class="sect1"><a href="#ref.optimization">7.3. Optimization</a></span></dt><dt><span class="sect1"><a href="#ref.linearization.writing">7.4. Writing Linearized Files</a></span></dt><dt><span class="sect1"><a href="#ref.linearization-data">7.5. Calculating Linearization Data</a></span></dt><dt><span class="sect1"><a href="#ref.linearization-issues">7.6. Known Issues with Linearization</a></span></dt><dt><span class="sect1"><a href="#ref.linearization-debugging">7.7. Debugging Note</a></span></dt></dl></dd><dt><span class="chapter"><a href="#ref.object-and-xref-streams">8. Object and Cross-Reference Streams</a></span></dt><dd><dl><dt><span class="sect1"><a href="#ref.object-streams">8.1. Object Streams</a></span></dt><dt><span class="sect1"><a href="#ref.xref-streams">8.2. Cross-Reference Streams</a></span></dt><dd><dl><dt><span class="sect2"><a href="#ref.xref-stream-data">8.2.1. Cross-Reference Stream Data</a></span></dt></dl></dd><dt><span class="sect1"><a href="#ref.object-streams-linearization">8.3. Implications for Linearized Files</a></span></dt><dt><span class="sect1"><a href="#ref.object-stream-implementation">8.4. Implementation Notes</a></span></dt></dl></dd><dt><span class="appendix"><a href="#ref.release-notes">A. Release Notes</a></span></dt><dt><span class="appendix"><a href="#ref.upgrading-to-2.1">B. Upgrading from 2.0 to 2.1</a></span></dt><dt><span class="appendix"><a href="#ref.upgrading-to-3.0">C. Upgrading to 3.0</a></span></dt><dt><span class="appendix"><a href="#ref.upgrading-to-4.0">D. Upgrading to 4.0</a></span></dt></dl></div><div class="preface"><div class="titlepage"><div><div><h1 class="title"><a id="acknowledgments"></a>General Information</h1></div></div></div><p> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>QPDF Manual</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><meta name="generator" content="DocBook XSL Stylesheets V1.78.1" /></head><body><div class="book"><div class="titlepage"><div><div><h1 class="title"><a id="idp46198272"></a>QPDF Manual</h1></div><div><h2 class="subtitle">For QPDF Version 5.1.3, May 24, 2015</h2></div><div><div class="author"><h3 class="author"><span class="firstname">Jay</span> <span class="surname">Berkenbilt</span></h3></div></div><div><p class="copyright">Copyright © 2005–2014 Jay Berkenbilt</p></div></div><hr /></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="preface"><a href="#acknowledgments">General Information</a></span></dt><dt><span class="chapter"><a href="#ref.overview">1. What is QPDF?</a></span></dt><dt><span class="chapter"><a href="#ref.installing">2. Building and Installing QPDF</a></span></dt><dd><dl><dt><span class="sect1"><a href="#ref.prerequisites">2.1. System Requirements</a></span></dt><dt><span class="sect1"><a href="#ref.building">2.2. Build Instructions</a></span></dt></dl></dd><dt><span class="chapter"><a href="#ref.using">3. Running QPDF</a></span></dt><dd><dl><dt><span class="sect1"><a href="#ref.invocation">3.1. Basic Invocation</a></span></dt><dt><span class="sect1"><a href="#ref.basic-options">3.2. Basic Options</a></span></dt><dt><span class="sect1"><a href="#ref.encryption-options">3.3. Encryption Options</a></span></dt><dt><span class="sect1"><a href="#ref.page-selection">3.4. Page Selection Options</a></span></dt><dt><span class="sect1"><a href="#ref.advanced-transformation">3.5. Advanced Transformation Options</a></span></dt><dt><span class="sect1"><a href="#ref.testing-options">3.6. Testing, Inspection, and Debugging Options</a></span></dt></dl></dd><dt><span class="chapter"><a href="#ref.qdf">4. QDF Mode</a></span></dt><dt><span class="chapter"><a href="#ref.using-library">5. Using the QPDF Library</a></span></dt><dt><span class="chapter"><a href="#ref.design">6. Design and Library Notes</a></span></dt><dd><dl><dt><span class="sect1"><a href="#ref.design.intro">6.1. Introduction</a></span></dt><dt><span class="sect1"><a href="#ref.design-goals">6.2. Design Goals</a></span></dt><dt><span class="sect1"><a href="#ref.casting">6.3. Casting Policy</a></span></dt><dt><span class="sect1"><a href="#ref.encryption">6.4. Encryption</a></span></dt><dt><span class="sect1"><a href="#ref.random-numbers">6.5. Random Number Generation</a></span></dt><dt><span class="sect1"><a href="#ref.adding-and-remove-pages">6.6. Adding and Removing Pages</a></span></dt><dt><span class="sect1"><a href="#ref.reserved-objects">6.7. Reserving Object Numbers</a></span></dt><dt><span class="sect1"><a href="#ref.foreign-objects">6.8. Copying Objects From Other PDF Files</a></span></dt><dt><span class="sect1"><a href="#ref.rewriting">6.9. Writing PDF Files</a></span></dt><dt><span class="sect1"><a href="#ref.filtered-streams">6.10. Filtered Streams</a></span></dt></dl></dd><dt><span class="chapter"><a href="#ref.linearization">7. Linearization</a></span></dt><dd><dl><dt><span class="sect1"><a href="#ref.linearization-strategy">7.1. Basic Strategy for Linearization</a></span></dt><dt><span class="sect1"><a href="#ref.linearized.preparation">7.2. Preparing For Linearization</a></span></dt><dt><span class="sect1"><a href="#ref.optimization">7.3. Optimization</a></span></dt><dt><span class="sect1"><a href="#ref.linearization.writing">7.4. Writing Linearized Files</a></span></dt><dt><span class="sect1"><a href="#ref.linearization-data">7.5. Calculating Linearization Data</a></span></dt><dt><span class="sect1"><a href="#ref.linearization-issues">7.6. Known Issues with Linearization</a></span></dt><dt><span class="sect1"><a href="#ref.linearization-debugging">7.7. Debugging Note</a></span></dt></dl></dd><dt><span class="chapter"><a href="#ref.object-and-xref-streams">8. Object and Cross-Reference Streams</a></span></dt><dd><dl><dt><span class="sect1"><a href="#ref.object-streams">8.1. Object Streams</a></span></dt><dt><span class="sect1"><a href="#ref.xref-streams">8.2. Cross-Reference Streams</a></span></dt><dd><dl><dt><span class="sect2"><a href="#ref.xref-stream-data">8.2.1. Cross-Reference Stream Data</a></span></dt></dl></dd><dt><span class="sect1"><a href="#ref.object-streams-linearization">8.3. Implications for Linearized Files</a></span></dt><dt><span class="sect1"><a href="#ref.object-stream-implementation">8.4. Implementation Notes</a></span></dt></dl></dd><dt><span class="appendix"><a href="#ref.release-notes">A. Release Notes</a></span></dt><dt><span class="appendix"><a href="#ref.upgrading-to-2.1">B. Upgrading from 2.0 to 2.1</a></span></dt><dt><span class="appendix"><a href="#ref.upgrading-to-3.0">C. Upgrading to 3.0</a></span></dt><dt><span class="appendix"><a href="#ref.upgrading-to-4.0">D. Upgrading to 4.0</a></span></dt></dl></div><div class="preface"><div class="titlepage"><div><div><h1 class="title"><a id="acknowledgments"></a>General Information</h1></div></div></div><p> QPDF is a program that does structural, content-preserving transformations on PDF files. QPDF's website is located at <a class="ulink" href="http://qpdf.sourceforge.net/" target="_top">http://qpdf.sourceforge.net/</a>. QPDF's source code is hosted on github at <a class="ulink" href="https://github.com/qpdf/qpdf" target="_top">https://github.com/qpdf/qpdf</a>. @@ -972,7 +972,7 @@ outfile.pdf</code> password-protected files. QPDF does not enforce encryption parameters and will treat user and owner passwords equivalently. Either password may be used to access an encrypted file. - <a href="#ftn.idp49199344" class="footnote" id="idp49199344"><sup class="footnote">[1]</sup></a> + <a href="#ftn.idp52375920" class="footnote" id="idp52375920"><sup class="footnote">[1]</sup></a> <code class="classname">QPDF</code> will allow recovery of a user password given an owner password. The input PDF file must be seekable. (Output files written by <code class="classname">QPDFWriter</code> need @@ -1450,7 +1450,7 @@ outfile.pdf</code> filter should write to whatever type of output is required. The <code class="classname">QPDF</code> class has an interface to write raw or filtered stream contents to a given pipeline. - </p></div><div class="footnotes"><br /><hr style="width:100; text-align:left;margin-left: 0" /><div id="ftn.idp49199344" class="footnote"><p><a href="#idp49199344" class="para"><sup class="para">[1] </sup></a> + </p></div><div class="footnotes"><br /><hr style="width:100; text-align:left;margin-left: 0" /><div id="ftn.idp52375920" class="footnote"><p><a href="#idp52375920" class="para"><sup class="para">[1] </sup></a> As pointed out earlier, the intention is not for qpdf to be used to bypass security on files. but as any open source PDF consumer may be easily modified to bypass basic PDF document security, @@ -1813,7 +1813,26 @@ print "\n"; </p></div></div><div class="appendix"><div class="titlepage"><div><div><h1 class="title"><a id="ref.release-notes"></a>Appendix A. Release Notes</h1></div></div></div><p> For a detailed list of changes, please see the file <code class="filename">ChangeLog</code> in the source distribution. - </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">5.1.2: June 7, 2014</span></dt><dd><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p> + </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">5.1.3: May 24, 2015</span></dt><dd><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p> + Bug fix: fix-qdf was not properly handling files that + contained object streams with more than 255 objects in them. + </p></li><li class="listitem"><p> + Bug fix: qpdf was not properly initializing Microsoft's secure + crypto provider on fresh Windows installations that had not + had any keys created yet. + </p></li><li class="listitem"><p> + Fix a few errors found by Gynvael Coldwind and + Mateusz Jurczyk of the Google Security Team. Please see the + ChangeLog for details. + </p></li><li class="listitem"><p> + Properly handle pages that have no contents at all. There were + many cases in which qpdf handled this fine, but a few methods + blindly obtained page contents with handling the possibility + that there were no contents. + </p></li><li class="listitem"><p> + Make qpdf more robust for a few more kinds of problems that + may occur in invalid PDF files. + </p></li></ul></div></dd><dt><span class="term">5.1.2: June 7, 2014</span></dt><dd><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p> Bug fix: linearizing files could create a corrupted output file under extremely unlikely file size circumstances. See ChangeLog for details. The odds of getting hit by this are diff --git a/doc/qpdf-manual.pdf b/doc/qpdf-manual.pdf Binary files differindex a65bc64..b719782 100644 --- a/doc/qpdf-manual.pdf +++ b/doc/qpdf-manual.pdf diff --git a/include/qpdf/Buffer.hh b/include/qpdf/Buffer.hh index e19bf1f..26ab1c1 100644 --- a/include/qpdf/Buffer.hh +++ b/include/qpdf/Buffer.hh @@ -1,4 +1,4 @@ -// Copyright (c) 2005-2014 Jay Berkenbilt +// Copyright (c) 2005-2015 Jay Berkenbilt // // This file is part of qpdf. This software may be distributed under // the terms of version 2 of the Artistic License which may be found diff --git a/include/qpdf/BufferInputSource.hh b/include/qpdf/BufferInputSource.hh index 956a6ef..64ee460 100644 --- a/include/qpdf/BufferInputSource.hh +++ b/include/qpdf/BufferInputSource.hh @@ -1,4 +1,4 @@ -/* Copyright (c) 2005-2014 Jay Berkenbilt +/* Copyright (c) 2005-2015 Jay Berkenbilt * * This file is part of qpdf. This software may be distributed under * the terms of version 2 of the Artistic License which may be found diff --git a/include/qpdf/Constants.h b/include/qpdf/Constants.h index e8e3396..38f1e71 100644 --- a/include/qpdf/Constants.h +++ b/include/qpdf/Constants.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2005-2014 Jay Berkenbilt +/* Copyright (c) 2005-2015 Jay Berkenbilt * * This file is part of qpdf. This software may be distributed under * the terms of version 2 of the Artistic License which may be found diff --git a/include/qpdf/DLL.h b/include/qpdf/DLL.h index d570b99..a2d863f 100644 --- a/include/qpdf/DLL.h +++ b/include/qpdf/DLL.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2005-2014 Jay Berkenbilt +/* Copyright (c) 2005-2015 Jay Berkenbilt * * This file is part of qpdf. This software may be distributed under * the terms of version 2 of the Artistic License which may be found diff --git a/include/qpdf/FileInputSource.hh b/include/qpdf/FileInputSource.hh index a298a2b..6445736 100644 --- a/include/qpdf/FileInputSource.hh +++ b/include/qpdf/FileInputSource.hh @@ -1,4 +1,4 @@ -/* Copyright (c) 2005-2014 Jay Berkenbilt +/* Copyright (c) 2005-2015 Jay Berkenbilt * * This file is part of qpdf. This software may be distributed under * the terms of version 2 of the Artistic License which may be found diff --git a/include/qpdf/InputSource.hh b/include/qpdf/InputSource.hh index 1f66493..a731918 100644 --- a/include/qpdf/InputSource.hh +++ b/include/qpdf/InputSource.hh @@ -1,4 +1,4 @@ -/* Copyright (c) 2005-2014 Jay Berkenbilt +/* Copyright (c) 2005-2015 Jay Berkenbilt * * This file is part of qpdf. This software may be distributed under * the terms of version 2 of the Artistic License which may be found diff --git a/include/qpdf/Pipeline.hh b/include/qpdf/Pipeline.hh index 79c0c9b..1d2ac6b 100644 --- a/include/qpdf/Pipeline.hh +++ b/include/qpdf/Pipeline.hh @@ -1,4 +1,4 @@ -// Copyright (c) 2005-2014 Jay Berkenbilt +// Copyright (c) 2005-2015 Jay Berkenbilt // // This file is part of qpdf. This software may be distributed under // the terms of version 2 of the Artistic License which may be found diff --git a/include/qpdf/Pl_Buffer.hh b/include/qpdf/Pl_Buffer.hh index 3fc6f05..29f86b5 100644 --- a/include/qpdf/Pl_Buffer.hh +++ b/include/qpdf/Pl_Buffer.hh @@ -1,4 +1,4 @@ -// Copyright (c) 2005-2014 Jay Berkenbilt +// Copyright (c) 2005-2015 Jay Berkenbilt // // This file is part of qpdf. This software may be distributed under // the terms of version 2 of the Artistic License which may be found diff --git a/include/qpdf/Pl_Concatenate.hh b/include/qpdf/Pl_Concatenate.hh index 6832487..cf83006 100644 --- a/include/qpdf/Pl_Concatenate.hh +++ b/include/qpdf/Pl_Concatenate.hh @@ -1,4 +1,4 @@ -/* Copyright (c) 2005-2014 Jay Berkenbilt +/* Copyright (c) 2005-2015 Jay Berkenbilt * * This file is part of qpdf. This software may be distributed under * the terms of version 2 of the Artistic License which may be found diff --git a/include/qpdf/Pl_Count.hh b/include/qpdf/Pl_Count.hh index 229ecd3..515824a 100644 --- a/include/qpdf/Pl_Count.hh +++ b/include/qpdf/Pl_Count.hh @@ -1,4 +1,4 @@ -// Copyright (c) 2005-2014 Jay Berkenbilt +// Copyright (c) 2005-2015 Jay Berkenbilt // // This file is part of qpdf. This software may be distributed under // the terms of version 2 of the Artistic License which may be found diff --git a/include/qpdf/Pl_Discard.hh b/include/qpdf/Pl_Discard.hh index 39db192..da6dd5f 100644 --- a/include/qpdf/Pl_Discard.hh +++ b/include/qpdf/Pl_Discard.hh @@ -1,4 +1,4 @@ -// Copyright (c) 2005-2014 Jay Berkenbilt +// Copyright (c) 2005-2015 Jay Berkenbilt // // This file is part of qpdf. This software may be distributed under // the terms of version 2 of the Artistic License which may be found diff --git a/include/qpdf/Pl_Flate.hh b/include/qpdf/Pl_Flate.hh index 24780a9..a8090bb 100644 --- a/include/qpdf/Pl_Flate.hh +++ b/include/qpdf/Pl_Flate.hh @@ -1,4 +1,4 @@ -// Copyright (c) 2005-2014 Jay Berkenbilt +// Copyright (c) 2005-2015 Jay Berkenbilt // // This file is part of qpdf. This software may be distributed under // the terms of version 2 of the Artistic License which may be found diff --git a/include/qpdf/Pl_StdioFile.hh b/include/qpdf/Pl_StdioFile.hh index 19e73a1..e86d206 100644 --- a/include/qpdf/Pl_StdioFile.hh +++ b/include/qpdf/Pl_StdioFile.hh @@ -1,4 +1,4 @@ -// Copyright (c) 2005-2014 Jay Berkenbilt +// Copyright (c) 2005-2015 Jay Berkenbilt // // This file is part of qpdf. This software may be distributed under // the terms of version 2 of the Artistic License which may be found diff --git a/include/qpdf/PointerHolder.hh b/include/qpdf/PointerHolder.hh index 0f2ffa5..856897d 100644 --- a/include/qpdf/PointerHolder.hh +++ b/include/qpdf/PointerHolder.hh @@ -1,4 +1,4 @@ -// Copyright (c) 2005-2014 Jay Berkenbilt +// Copyright (c) 2005-2015 Jay Berkenbilt // // This file is part of qpdf. This software may be distributed under // the terms of version 2 of the Artistic License which may be found diff --git a/include/qpdf/QPDF.hh b/include/qpdf/QPDF.hh index dfce40c..de7c822 100644 --- a/include/qpdf/QPDF.hh +++ b/include/qpdf/QPDF.hh @@ -1,4 +1,4 @@ -// Copyright (c) 2005-2014 Jay Berkenbilt +// Copyright (c) 2005-2015 Jay Berkenbilt // // This file is part of qpdf. This software may be distributed under // the terms of version 2 of the Artistic License which may be found @@ -668,6 +668,9 @@ class QPDF void getAllPagesInternal(QPDFObjectHandle cur_pages, std::vector<QPDFObjectHandle>& result); + void getAllPagesInternal2(QPDFObjectHandle cur_pages, + std::vector<QPDFObjectHandle>& result, + std::set<QPDFObjGen>& visited); void insertPage(QPDFObjectHandle newpage, int pos); int findPage(QPDFObjGen const& og); int findPage(QPDFObjectHandle& page); @@ -1023,6 +1026,12 @@ class QPDF std::map<std::string, std::vector<QPDFObjectHandle> >&, std::vector<QPDFObjectHandle>& all_pages, bool allow_changes, bool warn_skipped_keys); + void pushInheritedAttributesToPageInternal2( + QPDFObjectHandle, + std::map<std::string, std::vector<QPDFObjectHandle> >&, + std::vector<QPDFObjectHandle>& all_pages, + bool allow_changes, bool warn_skipped_keys, + std::set<QPDFObjGen>& visited); void updateObjectMaps(ObjUser const& ou, QPDFObjectHandle oh); void updateObjectMapsInternal(ObjUser const& ou, QPDFObjectHandle oh, std::set<QPDFObjGen>& visited, bool top); diff --git a/include/qpdf/QPDFExc.hh b/include/qpdf/QPDFExc.hh index 191c84e..2ab2b22 100644 --- a/include/qpdf/QPDFExc.hh +++ b/include/qpdf/QPDFExc.hh @@ -1,4 +1,4 @@ -// Copyright (c) 2005-2014 Jay Berkenbilt +// Copyright (c) 2005-2015 Jay Berkenbilt // // This file is part of qpdf. This software may be distributed under // the terms of version 2 of the Artistic License which may be found diff --git a/include/qpdf/QPDFObjGen.hh b/include/qpdf/QPDFObjGen.hh index fde5678..8323fbb 100644 --- a/include/qpdf/QPDFObjGen.hh +++ b/include/qpdf/QPDFObjGen.hh @@ -1,4 +1,4 @@ -// Copyright (c) 2005-2014 Jay Berkenbilt +// Copyright (c) 2005-2015 Jay Berkenbilt // // This file is part of qpdf. This software may be distributed under // the terms of version 2 of the Artistic License which may be found diff --git a/include/qpdf/QPDFObject.hh b/include/qpdf/QPDFObject.hh index 6230eff..8ab0b75 100644 --- a/include/qpdf/QPDFObject.hh +++ b/include/qpdf/QPDFObject.hh @@ -1,4 +1,4 @@ -// Copyright (c) 2005-2014 Jay Berkenbilt +// Copyright (c) 2005-2015 Jay Berkenbilt // // This file is part of qpdf. This software may be distributed under // the terms of version 2 of the Artistic License which may be found diff --git a/include/qpdf/QPDFObjectHandle.hh b/include/qpdf/QPDFObjectHandle.hh index 007eaff..c90eee4 100644 --- a/include/qpdf/QPDFObjectHandle.hh +++ b/include/qpdf/QPDFObjectHandle.hh @@ -1,4 +1,4 @@ -// Copyright (c) 2005-2014 Jay Berkenbilt +// Copyright (c) 2005-2015 Jay Berkenbilt // // This file is part of qpdf. This software may be distributed under // the terms of version 2 of the Artistic License which may be found diff --git a/include/qpdf/QPDFTokenizer.hh b/include/qpdf/QPDFTokenizer.hh index 82fee71..2f3dfec 100644 --- a/include/qpdf/QPDFTokenizer.hh +++ b/include/qpdf/QPDFTokenizer.hh @@ -1,4 +1,4 @@ -// Copyright (c) 2005-2014 Jay Berkenbilt +// Copyright (c) 2005-2015 Jay Berkenbilt // // This file is part of qpdf. This software may be distributed under // the terms of version 2 of the Artistic License which may be found diff --git a/include/qpdf/QPDFWriter.hh b/include/qpdf/QPDFWriter.hh index e197344..8997e14 100644 --- a/include/qpdf/QPDFWriter.hh +++ b/include/qpdf/QPDFWriter.hh @@ -1,4 +1,4 @@ -// Copyright (c) 2005-2014 Jay Berkenbilt +// Copyright (c) 2005-2015 Jay Berkenbilt // // This file is part of qpdf. This software may be distributed under // the terms of version 2 of the Artistic License which may be found diff --git a/include/qpdf/QPDFXRefEntry.hh b/include/qpdf/QPDFXRefEntry.hh index ed29a9e..ec63e4f 100644 --- a/include/qpdf/QPDFXRefEntry.hh +++ b/include/qpdf/QPDFXRefEntry.hh @@ -1,4 +1,4 @@ -// Copyright (c) 2005-2014 Jay Berkenbilt +// Copyright (c) 2005-2015 Jay Berkenbilt // // This file is part of qpdf. This software may be distributed under // the terms of version 2 of the Artistic License which may be found diff --git a/include/qpdf/QTC.hh b/include/qpdf/QTC.hh index 1875c44..e7ff9a7 100644 --- a/include/qpdf/QTC.hh +++ b/include/qpdf/QTC.hh @@ -1,4 +1,4 @@ -// Copyright (c) 2005-2014 Jay Berkenbilt +// Copyright (c) 2005-2015 Jay Berkenbilt // // This file is part of qpdf. This software may be distributed under // the terms of version 2 of the Artistic License which may be found diff --git a/include/qpdf/QUtil.hh b/include/qpdf/QUtil.hh index 5c2e548..19c74e9 100644 --- a/include/qpdf/QUtil.hh +++ b/include/qpdf/QUtil.hh @@ -1,4 +1,4 @@ -// Copyright (c) 2005-2014 Jay Berkenbilt +// Copyright (c) 2005-2015 Jay Berkenbilt // // This file is part of qpdf. This software may be distributed under // the terms of version 2 of the Artistic License which may be found @@ -14,6 +14,7 @@ #include <list> #include <stdexcept> #include <stdio.h> +#include <time.h> class RandomDataProvider; diff --git a/include/qpdf/RandomDataProvider.hh b/include/qpdf/RandomDataProvider.hh index 79c8508..d1af66d 100644 --- a/include/qpdf/RandomDataProvider.hh +++ b/include/qpdf/RandomDataProvider.hh @@ -1,4 +1,4 @@ -/* Copyright (c) 2005-2014 Jay Berkenbilt +/* Copyright (c) 2005-2015 Jay Berkenbilt * * This file is part of qpdf. This software may be distributed under * the terms of version 2 of the Artistic License which may be found diff --git a/include/qpdf/Types.h b/include/qpdf/Types.h index c833da6..2f5c3e6 100644 --- a/include/qpdf/Types.h +++ b/include/qpdf/Types.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2005-2014 Jay Berkenbilt +/* Copyright (c) 2005-2015 Jay Berkenbilt * * This file is part of qpdf. This software may be distributed under * the terms of version 2 of the Artistic License which may be found diff --git a/include/qpdf/qpdf-c.h b/include/qpdf/qpdf-c.h index 809ca97..96ea8aa 100644 --- a/include/qpdf/qpdf-c.h +++ b/include/qpdf/qpdf-c.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2005-2014 Jay Berkenbilt +/* Copyright (c) 2005-2015 Jay Berkenbilt * * This file is part of qpdf. This software may be distributed under * the terms of version 2 of the Artistic License which may be found diff --git a/libqpdf/QPDF.cc b/libqpdf/QPDF.cc index 0d7bea4..9701a4c 100644 --- a/libqpdf/QPDF.cc +++ b/libqpdf/QPDF.cc @@ -20,7 +20,7 @@ #include <qpdf/QPDF_Null.hh> #include <qpdf/QPDF_Dictionary.hh> -std::string QPDF::qpdf_version = "5.1.2"; +std::string QPDF::qpdf_version = "5.1.3"; static char const* EMPTY_PDF = "%PDF-1.3\n" diff --git a/libqpdf/QPDFObjectHandle.cc b/libqpdf/QPDFObjectHandle.cc index ef92e3a..64a4e3c 100644 --- a/libqpdf/QPDFObjectHandle.cc +++ b/libqpdf/QPDFObjectHandle.cc @@ -633,7 +633,7 @@ QPDFObjectHandle::getPageContents() { result.push_back(contents); } - else + else if (! contents.isNull()) { throw std::runtime_error("unknown object type inspecting /Contents " "key in page dictionary"); @@ -966,7 +966,9 @@ QPDFObjectHandle::parseInternal(PointerHolder<InputSource> input, std::string const& value = token.getValue(); if ((value == "R") && (in_array || in_dictionary) && (olist.size() >= 2) && + (! olist.at(olist.size() - 1).isIndirect()) && (olist.at(olist.size() - 1).isInteger()) && + (! olist.at(olist.size() - 2).isIndirect()) && (olist.at(olist.size() - 2).isInteger())) { if (context == 0) diff --git a/libqpdf/QPDF_encryption.cc b/libqpdf/QPDF_encryption.cc index 2328480..71c28d0 100644 --- a/libqpdf/QPDF_encryption.cc +++ b/libqpdf/QPDF_encryption.cc @@ -428,7 +428,9 @@ QPDF::compute_encryption_key_from_password( } MD5::Digest digest; iterate_md5_digest(md5, digest, ((data.getR() >= 3) ? 50 : 0)); - return std::string(reinterpret_cast<char*>(digest), data.getLengthBytes()); + return std::string(reinterpret_cast<char*>(digest), + std::min(static_cast<int>(sizeof(digest)), + data.getLengthBytes())); } static void diff --git a/libqpdf/QPDF_optimization.cc b/libqpdf/QPDF_optimization.cc index 5299d90..fad710d 100644 --- a/libqpdf/QPDF_optimization.cc +++ b/libqpdf/QPDF_optimization.cc @@ -174,6 +174,30 @@ QPDF::pushInheritedAttributesToPageInternal( std::vector<QPDFObjectHandle>& pages, bool allow_changes, bool warn_skipped_keys) { + std::set<QPDFObjGen> visited; + pushInheritedAttributesToPageInternal2( + cur_pages, key_ancestors, pages, allow_changes, + warn_skipped_keys, visited); +} + +void +QPDF::pushInheritedAttributesToPageInternal2( + QPDFObjectHandle cur_pages, + std::map<std::string, std::vector<QPDFObjectHandle> >& key_ancestors, + std::vector<QPDFObjectHandle>& pages, + bool allow_changes, bool warn_skipped_keys, + std::set<QPDFObjGen>& visited) +{ + QPDFObjGen this_og = cur_pages.getObjGen(); + if (visited.count(this_og) > 0) + { + throw QPDFExc( + qpdf_e_pages, this->file->getName(), + this->last_object_description, 0, + "Loop detected in /Pages structure (inherited attributes)"); + } + visited.insert(this_og); + // Extract the underlying dictionary object std::string type = cur_pages.getKey("/Type").getName(); @@ -259,9 +283,9 @@ QPDF::pushInheritedAttributesToPageInternal( int n = kids.getArrayNItems(); for (int i = 0; i < n; ++i) { - pushInheritedAttributesToPageInternal( + pushInheritedAttributesToPageInternal2( kids.getArrayItem(i), key_ancestors, pages, - allow_changes, warn_skipped_keys); + allow_changes, warn_skipped_keys, visited); } // For each inheritable key, pop the stack. If the stack @@ -318,6 +342,7 @@ QPDF::pushInheritedAttributesToPageInternal( this->file->getLastOffset(), "invalid Type " + type + " in page tree"); } + visited.erase(this_og); } void diff --git a/libqpdf/QPDF_pages.cc b/libqpdf/QPDF_pages.cc index e8d107b..f9b421c 100644 --- a/libqpdf/QPDF_pages.cc +++ b/libqpdf/QPDF_pages.cc @@ -56,14 +56,45 @@ void QPDF::getAllPagesInternal(QPDFObjectHandle cur_pages, std::vector<QPDFObjectHandle>& result) { - std::string type = cur_pages.getKey("/Type").getName(); + std::set<QPDFObjGen> visited; + getAllPagesInternal2(cur_pages, result, visited); +} + +void +QPDF::getAllPagesInternal2(QPDFObjectHandle cur_pages, + std::vector<QPDFObjectHandle>& result, + std::set<QPDFObjGen>& visited) +{ + QPDFObjGen this_og = cur_pages.getObjGen(); + if (visited.count(this_og) > 0) + { + throw QPDFExc( + qpdf_e_pages, this->file->getName(), + this->last_object_description, 0, + "Loop detected in /Pages structure (getAllPages)"); + } + visited.insert(this_og); + std::string type; + QPDFObjectHandle type_key = cur_pages.getKey("/Type"); + if (type_key.isName()) + { + type = type_key.getName(); + } + else if (cur_pages.hasKey("/Kids")) + { + type = "/Pages"; + } + else + { + type = "/Page"; + } if (type == "/Pages") { QPDFObjectHandle kids = cur_pages.getKey("/Kids"); int n = kids.getArrayNItems(); for (int i = 0; i < n; ++i) { - getAllPagesInternal(kids.getArrayItem(i), result); + getAllPagesInternal2(kids.getArrayItem(i), result, visited); } } else if (type == "/Page") @@ -77,6 +108,7 @@ QPDF::getAllPagesInternal(QPDFObjectHandle cur_pages, this->file->getLastOffset(), "invalid Type " + type + " in page tree"); } + visited.erase(this_og); } void diff --git a/libqpdf/SecureRandomDataProvider.cc b/libqpdf/SecureRandomDataProvider.cc index 2870ab9..0b0b6c7 100644 --- a/libqpdf/SecureRandomDataProvider.cc +++ b/libqpdf/SecureRandomDataProvider.cc @@ -42,9 +42,40 @@ class WindowsCryptProvider public: WindowsCryptProvider() { - if (! CryptAcquireContext(&crypt_prov, NULL, NULL, PROV_RSA_FULL, 0)) + if (!CryptAcquireContext(&crypt_prov, + "Container", + NULL, + PROV_RSA_FULL, + 0)) { - throw std::runtime_error("unable to acquire crypt context"); +#ifdef __GNUC__ +# if ((__GNUC__ * 100) + __GNUC_MINOR__) >= 406 +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wold-style-cast" +# pragma GCC diagnostic ignored "-Wsign-compare" +# endif +#endif + if (GetLastError() == NTE_BAD_KEYSET) +#ifdef __GNUC__ +# if ((__GNUC__ * 100) + __GNUC_MINOR__) >= 406 +# pragma GCC diagnostic pop +# endif +#endif + { + if (! CryptAcquireContext(&crypt_prov, + "Container", + NULL, + PROV_RSA_FULL, + CRYPT_NEWKEYSET)) + { + throw std::runtime_error( + "unable to acquire crypt context with new keyset"); + } + } + else + { + throw std::runtime_error("unable to acquire crypt context"); + } } } ~WindowsCryptProvider() diff --git a/libqpdf/build.mk b/libqpdf/build.mk index a62622b..2cd3a54 100644 --- a/libqpdf/build.mk +++ b/libqpdf/build.mk @@ -96,4 +96,4 @@ $(COBJS_libqpdf): libqpdf/$(OUTPUT_DIR)/%.$(LOBJ): libqpdf/%.c # * Otherwise, increment REVISION $(TARGETS_libqpdf): $(OBJS_libqpdf) - $(call makelib,$(OBJS_libqpdf),$@,$(LDFLAGS),$(LIBS),14,2,1) + $(call makelib,$(OBJS_libqpdf),$@,$(LDFLAGS),$(LIBS),15,0,2) diff --git a/manual/qpdf-manual.xml b/manual/qpdf-manual.xml index 27dec9f..3174e68 100644 --- a/manual/qpdf-manual.xml +++ b/manual/qpdf-manual.xml @@ -5,8 +5,8 @@ <!ENTITY mdash "—"> <!ENTITY ndash "–"> <!ENTITY nbsp " "> -<!ENTITY swversion "5.1.2"> -<!ENTITY lastreleased "June 7, 2014"> +<!ENTITY swversion "5.1.3"> +<!ENTITY lastreleased "May 24, 2015"> ]> <book> <bookinfo> @@ -2666,6 +2666,47 @@ print "\n"; </para> <variablelist> <varlistentry> + <term>5.1.3: May 24, 2015</term> + <listitem> + <itemizedlist> + <listitem> + <para> + Bug fix: fix-qdf was not properly handling files that + contained object streams with more than 255 objects in them. + </para> + </listitem> + <listitem> + <para> + Bug fix: qpdf was not properly initializing Microsoft's secure + crypto provider on fresh Windows installations that had not + had any keys created yet. + </para> + </listitem> + <listitem> + <para> + Fix a few errors found by Gynvael Coldwind and + Mateusz Jurczyk of the Google Security Team. Please see the + ChangeLog for details. + </para> + </listitem> + <listitem> + <para> + Properly handle pages that have no contents at all. There were + many cases in which qpdf handled this fine, but a few methods + blindly obtained page contents with handling the possibility + that there were no contents. + </para> + </listitem> + <listitem> + <para> + Make qpdf more robust for a few more kinds of problems that + may occur in invalid PDF files. + </para> + </listitem> + </itemizedlist> + </listitem> + </varlistentry> + <varlistentry> <term>5.1.2: June 7, 2014</term> <listitem> <itemizedlist> diff --git a/qpdf/fix-qdf b/qpdf/fix-qdf index b0e56e1..2892a46 100755 --- a/qpdf/fix-qdf +++ b/qpdf/fix-qdf @@ -53,6 +53,7 @@ my $stream_start = 0; my $stream_length = 0; my $xref_offset = 0; my $xref_f1_nbytes = 0; +my $xref_f2_nbytes = 0; my $xref_size = 0; my $cur_state = 0; @@ -122,11 +123,28 @@ while (defined($line = get_line())) $t >>= 8; ++$xref_f1_nbytes; } - my $esize = $xref_f1_nbytes + 2; + # Figure out how many bytes we need for ostream index. + # Make sure we get at least 1 byte even if there are no + # object streams. + my $max_objects = 1; + foreach my $e (@xref) + { + my ($type, $f1, $f2) = @$e; + if ((defined $f2) && ($f2 > $max_objects)) + { + $max_objects = $f2; + } + } + while ($max_objects) + { + $max_objects >>=8; + ++$xref_f2_nbytes; + } + my $esize = 1 + $xref_f1_nbytes + $xref_f2_nbytes; $xref_size = 1 + @xref; my $length = $xref_size * $esize; print " /Length $length\n"; - print " /W [ 1 $xref_f1_nbytes 1 ]\n"; + print " /W [ 1 $xref_f1_nbytes $xref_f2_nbytes ]\n"; $state = $st_in_xref_stream_dict; } } @@ -200,19 +218,25 @@ while (defined($line = get_line())) } if ($line =~ m/^stream\n/) { - my $pack = "(C C$xref_f1_nbytes C)"; + my $pack = "(C C$xref_f1_nbytes C$xref_f2_nbytes)"; print pack($pack, 0, 0, 0); foreach my $x (@xref) { my ($type, $f1, $f2) = @$x; $f2 = 0 unless defined $f2; - my @f1 = (); - for (my $i = 0; $i < $xref_f1_nbytes; ++$i) - { - unshift(@f1, $f1 & 0xff); - $f1 >>= 8; - } - print pack($pack, $type, @f1, $f2); + my @f1 = (); + my @f2 = (); + foreach my $d ([\@f1, $f1, $xref_f1_nbytes], + [\@f2, $f2, $xref_f2_nbytes]) + { + my ($fa, $f, $nbytes) = @$d; + for (my $i = 0; $i < $nbytes; ++$i) + { + unshift(@$fa, $f & 0xff); + $f >>= 8; + } + } + print pack($pack, $type, @f1, @f2); } print "\nendstream\nendobj\n\n"; print "startxref\n$xref_offset\n\%\%EOF\n"; diff --git a/qpdf/qpdf.cc b/qpdf/qpdf.cc index a534d30..92b3b61 100644 --- a/qpdf/qpdf.cc +++ b/qpdf/qpdf.cc @@ -974,7 +974,7 @@ int main(int argc, char* argv[]) // 12345678901234567890123456789012345678901234567890123456789012345678901234567890 std::cout << whoami << " version " << QPDF::QPDFVersion() << std::endl - << "Copyright (c) 2005-2014 Jay Berkenbilt" + << "Copyright (c) 2005-2015 Jay Berkenbilt" << std::endl << "This software may be distributed under the terms of version 2 of the" << std::endl diff --git a/qpdf/qtest/qpdf.test b/qpdf/qtest/qpdf.test index 8e69784..006f95f 100644 --- a/qpdf/qtest/qpdf.test +++ b/qpdf/qtest/qpdf.test @@ -199,7 +199,7 @@ $td->runtest("remove page we don't have", show_ntests(); # ---------- $td->notify("--- Miscellaneous Tests ---"); -$n_tests += 72; +$n_tests += 76; $td->runtest("qpdf version", {$td->COMMAND => "qpdf --version"}, @@ -554,6 +554,23 @@ $td->runtest("check file", {$td->FILE => "a.pdf"}, {$td->FILE => "indirect-decode-parms-out.pdf"}); +$td->runtest("handle page no with contents", + {$td->COMMAND => "qpdf --show-pages page-no-content.pdf"}, + {$td->FILE => "page-no-content.out", $td->EXIT_STATUS => 0}, + $td->NORMALIZE_NEWLINES); +$td->runtest("no type key for page nodes", + {$td->COMMAND => "qpdf --check no-pages-types.pdf"}, + {$td->FILE => "no-pages-types.out", $td->EXIT_STATUS => 0}, + $td->NORMALIZE_NEWLINES); +$td->runtest("ensure arguments to R are direct", + {$td->COMMAND => "qpdf --check indirect-r-arg.pdf"}, + {$td->FILE => "indirect-r-arg.out", $td->EXIT_STATUS => 2}, + $td->NORMALIZE_NEWLINES); +$td->runtest("detect loops in pages structure", + {$td->COMMAND => "qpdf --check pages-loop.pdf"}, + {$td->FILE => "pages-loop.out", $td->EXIT_STATUS => 2}, + $td->NORMALIZE_NEWLINES); + show_ntests(); # ---------- $td->notify("--- Numeric range parsing tests ---"); @@ -1976,7 +1993,7 @@ compare_pdfs("inline-images-cr.pdf", "a.pdf"); show_ntests(); # ---------- $td->notify("--- fix-qdf Tests ---"); -$n_tests += 4; +$n_tests += 5; for (my $n = 1; $n <= 2; ++$n) { @@ -1990,6 +2007,10 @@ for (my $n = 1; $n <= 2; ++$n) {$td->FILE => "fix$n.qdf.out", $td->EXIT_STATUS => 0}); } +$td->runtest("fix-qdf with big object stream", # > 255 objects in a stream + {$td->COMMAND => "fix-qdf big-ostream.pdf"}, + {$td->FILE => "big-ostream.pdf", + $td->EXIT_STATUS => 0}); show_ntests(); # ---------- diff --git a/qpdf/qtest/qpdf/big-ostream.pdf b/qpdf/qtest/qpdf/big-ostream.pdf new file mode 100644 index 0000000..44554c9 --- /dev/null +++ b/qpdf/qtest/qpdf/big-ostream.pdf @@ -0,0 +1,2207 @@ +%PDF-1.5 +%¿÷¢þ +%QDF-1.0 + +1 0 obj +<< + /Type /ObjStm + /Length 25675 + /N 264 + /First 2515 +>> +stream +2 0 +3 97 +4 212 +5 478 +6 5663 +7 5725 +8 5788 +9 5851 +10 5915 +11 5979 +12 6044 +13 6109 +14 6174 +15 6239 +16 6304 +17 6369 +18 6434 +19 6499 +20 6564 +21 6629 +22 6694 +23 6759 +24 6824 +25 6889 +26 6954 +27 7019 +28 7084 +29 7149 +30 7214 +31 7279 +32 7344 +33 7409 +34 7474 +35 7539 +36 7604 +37 7669 +38 7734 +39 7799 +40 7864 +41 7929 +42 7994 +43 8059 +44 8124 +45 8189 +46 8254 +47 8319 +48 8384 +49 8449 +50 8514 +51 8579 +52 8644 +53 8709 +54 8774 +55 8839 +56 8904 +57 8969 +58 9034 +59 9099 +60 9164 +61 9229 +62 9294 +63 9359 +64 9424 +65 9489 +66 9554 +67 9619 +68 9684 +69 9749 +70 9814 +71 9879 +72 9944 +73 10009 +74 10074 +75 10139 +76 10204 +77 10269 +78 10334 +79 10399 +80 10464 +81 10529 +82 10594 +83 10659 +84 10724 +85 10789 +86 10854 +87 10919 +88 10984 +89 11049 +90 11114 +91 11179 +92 11244 +93 11309 +94 11374 +95 11439 +96 11504 +97 11570 +98 11637 +99 11704 +100 11772 +101 11840 +102 11909 +103 11978 +104 12047 +105 12116 +106 12185 +107 12254 +108 12323 +109 12392 +110 12461 +111 12530 +112 12599 +113 12668 +114 12737 +115 12806 +116 12875 +117 12944 +118 13013 +119 13082 +120 13151 +121 13220 +122 13289 +123 13358 +124 13427 +125 13496 +126 13565 +127 13634 +128 13703 +129 13772 +130 13841 +131 13910 +132 13979 +133 14048 +134 14117 +135 14186 +136 14255 +137 14324 +138 14393 +139 14462 +140 14531 +141 14600 +142 14669 +143 14738 +144 14807 +145 14876 +146 14945 +147 15014 +148 15083 +149 15152 +150 15221 +151 15290 +152 15359 +153 15428 +154 15497 +155 15566 +156 15635 +157 15704 +158 15773 +159 15842 +160 15911 +161 15980 +162 16049 +163 16118 +164 16187 +165 16256 +166 16325 +167 16394 +168 16463 +169 16532 +170 16601 +171 16670 +172 16739 +173 16808 +174 16877 +175 16946 +176 17015 +177 17084 +178 17153 +179 17222 +180 17291 +181 17360 +182 17429 +183 17498 +184 17567 +185 17636 +186 17705 +187 17774 +188 17843 +189 17912 +190 17981 +191 18050 +192 18119 +193 18188 +194 18257 +195 18326 +196 18395 +197 18464 +198 18533 +199 18602 +200 18671 +201 18740 +202 18809 +203 18878 +204 18947 +205 19016 +206 19085 +207 19154 +208 19223 +209 19292 +210 19361 +211 19430 +212 19499 +213 19568 +214 19637 +215 19706 +216 19775 +217 19844 +218 19913 +219 19982 +220 20051 +221 20120 +222 20189 +223 20258 +224 20327 +225 20396 +226 20465 +227 20534 +228 20603 +229 20672 +230 20741 +231 20810 +232 20879 +233 20948 +234 21017 +235 21086 +236 21155 +237 21224 +238 21293 +239 21362 +240 21431 +241 21500 +242 21569 +243 21638 +244 21707 +245 21776 +246 21845 +247 21914 +248 21983 +249 22052 +250 22121 +251 22190 +252 22259 +253 22328 +254 22397 +255 22466 +256 22535 +257 22604 +258 22673 +259 22742 +260 22811 +261 22880 +262 22949 +263 23018 +264 23087 +265 23156 +%% Object stream: object 2, index 0; original object ID: 1 +<< + /Pages 3 0 R + /Type /Catalog +>> +%% Object stream: object 3, index 1; original object ID: 2 +<< + /Count 1 + /Kids [ + 4 0 R + ] + /Type /Pages +>> +%% Object stream: object 4, index 2; original object ID: 3 +%% Page 1 +<< + /Contents 266 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Other 5 0 R + /Parent 3 0 R + /Resources << + /Font << + /F1 269 0 R + >> + /ProcSet 270 0 R + >> + /Type /Page +>> +%% Object stream: object 5, index 3; original object ID: 8 +[ + 6 0 R + 7 0 R + 8 0 R + 9 0 R + 10 0 R + 11 0 R + 12 0 R + 13 0 R + 14 0 R + 15 0 R + 16 0 R + 17 0 R + 18 0 R + 19 0 R + 20 0 R + 21 0 R + 22 0 R + 23 0 R + 24 0 R + 25 0 R + 26 0 R + 27 0 R + 28 0 R + 29 0 R + 30 0 R + 31 0 R + 32 0 R + 33 0 R + 34 0 R + 35 0 R + 36 0 R + 37 0 R + 38 0 R + 39 0 R + 40 0 R + 41 0 R + 42 0 R + 43 0 R + 44 0 R + 45 0 R + 46 0 R + 47 0 R + 48 0 R + 49 0 R + 50 0 R + 51 0 R + 52 0 R + 53 0 R + 54 0 R + 55 0 R + 56 0 R + 57 0 R + 58 0 R + 59 0 R + 60 0 R + 61 0 R + 62 0 R + 63 0 R + 64 0 R + 65 0 R + 66 0 R + 67 0 R + 68 0 R + 69 0 R + 70 0 R + 71 0 R + 72 0 R + 73 0 R + 74 0 R + 75 0 R + 76 0 R + 77 0 R + 78 0 R + 79 0 R + 80 0 R + 81 0 R + 82 0 R + 83 0 R + 84 0 R + 85 0 R + 86 0 R + 87 0 R + 88 0 R + 89 0 R + 90 0 R + 91 0 R + 92 0 R + 93 0 R + 94 0 R + 95 0 R + 96 0 R + 97 0 R + 98 0 R + 99 0 R + 100 0 R + 101 0 R + 102 0 R + 103 0 R + 104 0 R + 105 0 R + 106 0 R + 107 0 R + 108 0 R + 109 0 R + 110 0 R + 111 0 R + 112 0 R + 113 0 R + 114 0 R + 115 0 R + 116 0 R + 117 0 R + 118 0 R + 119 0 R + 120 0 R + 121 0 R + 122 0 R + 123 0 R + 124 0 R + 125 0 R + 126 0 R + 127 0 R + 128 0 R + 129 0 R + 130 0 R + 131 0 R + 132 0 R + 133 0 R + 134 0 R + 135 0 R + 136 0 R + 137 0 R + 138 0 R + 139 0 R + 140 0 R + 141 0 R + 142 0 R + 143 0 R + 144 0 R + 145 0 R + 146 0 R + 147 0 R + 148 0 R + 149 0 R + 150 0 R + 151 0 R + 152 0 R + 153 0 R + 154 0 R + 155 0 R + 156 0 R + 157 0 R + 158 0 R + 159 0 R + 160 0 R + 161 0 R + 162 0 R + 163 0 R + 164 0 R + 165 0 R + 166 0 R + 167 0 R + 168 0 R + 169 0 R + 170 0 R + 171 0 R + 172 0 R + 173 0 R + 174 0 R + 175 0 R + 176 0 R + 177 0 R + 178 0 R + 179 0 R + 180 0 R + 181 0 R + 182 0 R + 183 0 R + 184 0 R + 185 0 R + 186 0 R + 187 0 R + 188 0 R + 189 0 R + 190 0 R + 191 0 R + 192 0 R + 193 0 R + 194 0 R + 195 0 R + 196 0 R + 197 0 R + 198 0 R + 199 0 R + 200 0 R + 201 0 R + 202 0 R + 203 0 R + 204 0 R + 205 0 R + 206 0 R + 207 0 R + 208 0 R + 209 0 R + 210 0 R + 211 0 R + 212 0 R + 213 0 R + 214 0 R + 215 0 R + 216 0 R + 217 0 R + 218 0 R + 219 0 R + 220 0 R + 221 0 R + 222 0 R + 223 0 R + 224 0 R + 225 0 R + 226 0 R + 227 0 R + 228 0 R + 229 0 R + 230 0 R + 231 0 R + 232 0 R + 233 0 R + 234 0 R + 235 0 R + 236 0 R + 237 0 R + 238 0 R + 239 0 R + 240 0 R + 241 0 R + 242 0 R + 243 0 R + 244 0 R + 245 0 R + 246 0 R + 247 0 R + 248 0 R + 249 0 R + 250 0 R + 251 0 R + 252 0 R + 253 0 R + 254 0 R + 255 0 R + 256 0 R + 257 0 R + 258 0 R + 259 0 R + 260 0 R + 261 0 R + 262 0 R + 263 0 R + 264 0 R + 265 0 R + 271 0 R + 272 0 R + 273 0 R + 274 0 R + 275 0 R + 276 0 R + 277 0 R + 278 0 R + 279 0 R + 280 0 R + 281 0 R + 282 0 R + 283 0 R + 284 0 R + 285 0 R + 286 0 R + 287 0 R + 288 0 R + 289 0 R + 290 0 R + 291 0 R + 292 0 R + 293 0 R + 294 0 R + 295 0 R + 296 0 R + 297 0 R + 298 0 R + 299 0 R + 300 0 R + 301 0 R + 302 0 R + 303 0 R + 304 0 R + 305 0 R + 306 0 R + 307 0 R + 308 0 R + 309 0 R + 310 0 R + 311 0 R + 312 0 R + 313 0 R + 314 0 R + 315 0 R + 316 0 R + 317 0 R + 318 0 R + 319 0 R + 320 0 R + 321 0 R + 322 0 R + 323 0 R + 324 0 R + 325 0 R + 326 0 R + 327 0 R + 328 0 R + 329 0 R + 330 0 R + 331 0 R + 332 0 R + 333 0 R + 334 0 R + 335 0 R + 336 0 R + 337 0 R + 338 0 R + 339 0 R + 340 0 R + 341 0 R + 342 0 R + 343 0 R + 344 0 R + 345 0 R + 346 0 R + 347 0 R + 348 0 R + 349 0 R + 350 0 R + 351 0 R + 352 0 R + 353 0 R + 354 0 R + 355 0 R + 356 0 R + 357 0 R + 358 0 R + 359 0 R + 360 0 R + 361 0 R + 362 0 R + 363 0 R + 364 0 R + 365 0 R + 366 0 R + 367 0 R + 368 0 R + 369 0 R + 370 0 R + 371 0 R + 372 0 R + 373 0 R + 374 0 R + 375 0 R + 376 0 R + 377 0 R + 378 0 R + 379 0 R + 380 0 R + 381 0 R + 382 0 R + 383 0 R + 384 0 R + 385 0 R + 386 0 R + 387 0 R + 388 0 R + 389 0 R + 390 0 R + 391 0 R + 392 0 R + 393 0 R + 394 0 R + 395 0 R + 396 0 R + 397 0 R + 398 0 R + 399 0 R + 400 0 R + 401 0 R + 402 0 R + 403 0 R + 404 0 R + 405 0 R + 406 0 R + 407 0 R + 408 0 R + 409 0 R + 410 0 R + 411 0 R + 412 0 R + 413 0 R + 414 0 R + 415 0 R + 416 0 R + 417 0 R + 418 0 R + 419 0 R + 420 0 R + 421 0 R + 422 0 R + 423 0 R + 424 0 R + 425 0 R + 426 0 R + 427 0 R + 428 0 R + 429 0 R + 430 0 R + 431 0 R + 432 0 R + 433 0 R + 434 0 R + 435 0 R + 436 0 R + 437 0 R + 438 0 R + 439 0 R + 440 0 R + 441 0 R + 442 0 R + 443 0 R + 444 0 R + 445 0 R + 446 0 R + 447 0 R + 448 0 R + 449 0 R + 450 0 R + 451 0 R + 452 0 R + 453 0 R + 454 0 R + 455 0 R + 456 0 R + 457 0 R + 458 0 R + 459 0 R + 460 0 R + 461 0 R + 462 0 R + 463 0 R + 464 0 R + 465 0 R + 466 0 R + 467 0 R + 468 0 R + 469 0 R + 470 0 R + 471 0 R + 472 0 R + 473 0 R + 474 0 R + 475 0 R + 476 0 R + 477 0 R + 478 0 R + 479 0 R + 480 0 R + 481 0 R + 482 0 R + 483 0 R + 484 0 R + 485 0 R + 486 0 R + 487 0 R + 488 0 R + 489 0 R + 490 0 R + 491 0 R + 492 0 R + 493 0 R + 494 0 R + 495 0 R + 496 0 R + 497 0 R + 498 0 R + 499 0 R + 500 0 R + 501 0 R + 502 0 R + 503 0 R + 504 0 R + 505 0 R + 506 0 R + 507 0 R + 508 0 R + 509 0 R + 510 0 R + 511 0 R + 512 0 R + 513 0 R + 514 0 R + 515 0 R + 516 0 R + 517 0 R + 518 0 R + 519 0 R + 520 0 R + 521 0 R + 522 0 R + 523 0 R + 524 0 R + 525 0 R + 526 0 R + 527 0 R + 528 0 R + 529 0 R + 530 0 R + 531 0 R + 532 0 R +] +%% Object stream: object 6, index 4; original object ID: 9 +9 +%% Object stream: object 7, index 5; original object ID: 10 +10 +%% Object stream: object 8, index 6; original object ID: 11 +11 +%% Object stream: object 9, index 7; original object ID: 12 +12 +%% Object stream: object 10, index 8; original object ID: 13 +13 +%% Object stream: object 11, index 9; original object ID: 14 +14 +%% Object stream: object 12, index 10; original object ID: 15 +15 +%% Object stream: object 13, index 11; original object ID: 16 +16 +%% Object stream: object 14, index 12; original object ID: 17 +17 +%% Object stream: object 15, index 13; original object ID: 18 +18 +%% Object stream: object 16, index 14; original object ID: 19 +19 +%% Object stream: object 17, index 15; original object ID: 20 +20 +%% Object stream: object 18, index 16; original object ID: 21 +21 +%% Object stream: object 19, index 17; original object ID: 22 +22 +%% Object stream: object 20, index 18; original object ID: 23 +23 +%% Object stream: object 21, index 19; original object ID: 24 +24 +%% Object stream: object 22, index 20; original object ID: 25 +25 +%% Object stream: object 23, index 21; original object ID: 26 +26 +%% Object stream: object 24, index 22; original object ID: 27 +27 +%% Object stream: object 25, index 23; original object ID: 28 +28 +%% Object stream: object 26, index 24; original object ID: 29 +29 +%% Object stream: object 27, index 25; original object ID: 30 +30 +%% Object stream: object 28, index 26; original object ID: 31 +31 +%% Object stream: object 29, index 27; original object ID: 32 +32 +%% Object stream: object 30, index 28; original object ID: 33 +33 +%% Object stream: object 31, index 29; original object ID: 34 +34 +%% Object stream: object 32, index 30; original object ID: 35 +35 +%% Object stream: object 33, index 31; original object ID: 36 +36 +%% Object stream: object 34, index 32; original object ID: 37 +37 +%% Object stream: object 35, index 33; original object ID: 38 +38 +%% Object stream: object 36, index 34; original object ID: 39 +39 +%% Object stream: object 37, index 35; original object ID: 40 +40 +%% Object stream: object 38, index 36; original object ID: 41 +41 +%% Object stream: object 39, index 37; original object ID: 42 +42 +%% Object stream: object 40, index 38; original object ID: 43 +43 +%% Object stream: object 41, index 39; original object ID: 44 +44 +%% Object stream: object 42, index 40; original object ID: 45 +45 +%% Object stream: object 43, index 41; original object ID: 46 +46 +%% Object stream: object 44, index 42; original object ID: 47 +47 +%% Object stream: object 45, index 43; original object ID: 48 +48 +%% Object stream: object 46, index 44; original object ID: 49 +49 +%% Object stream: object 47, index 45; original object ID: 50 +50 +%% Object stream: object 48, index 46; original object ID: 51 +51 +%% Object stream: object 49, index 47; original object ID: 52 +52 +%% Object stream: object 50, index 48; original object ID: 53 +53 +%% Object stream: object 51, index 49; original object ID: 54 +54 +%% Object stream: object 52, index 50; original object ID: 55 +55 +%% Object stream: object 53, index 51; original object ID: 56 +56 +%% Object stream: object 54, index 52; original object ID: 57 +57 +%% Object stream: object 55, index 53; original object ID: 58 +58 +%% Object stream: object 56, index 54; original object ID: 59 +59 +%% Object stream: object 57, index 55; original object ID: 60 +60 +%% Object stream: object 58, index 56; original object ID: 61 +61 +%% Object stream: object 59, index 57; original object ID: 62 +62 +%% Object stream: object 60, index 58; original object ID: 63 +63 +%% Object stream: object 61, index 59; original object ID: 64 +64 +%% Object stream: object 62, index 60; original object ID: 65 +65 +%% Object stream: object 63, index 61; original object ID: 66 +66 +%% Object stream: object 64, index 62; original object ID: 67 +67 +%% Object stream: object 65, index 63; original object ID: 68 +68 +%% Object stream: object 66, index 64; original object ID: 69 +69 +%% Object stream: object 67, index 65; original object ID: 70 +70 +%% Object stream: object 68, index 66; original object ID: 71 +71 +%% Object stream: object 69, index 67; original object ID: 72 +72 +%% Object stream: object 70, index 68; original object ID: 73 +73 +%% Object stream: object 71, index 69; original object ID: 74 +74 +%% Object stream: object 72, index 70; original object ID: 75 +75 +%% Object stream: object 73, index 71; original object ID: 76 +76 +%% Object stream: object 74, index 72; original object ID: 77 +77 +%% Object stream: object 75, index 73; original object ID: 78 +78 +%% Object stream: object 76, index 74; original object ID: 79 +79 +%% Object stream: object 77, index 75; original object ID: 80 +80 +%% Object stream: object 78, index 76; original object ID: 81 +81 +%% Object stream: object 79, index 77; original object ID: 82 +82 +%% Object stream: object 80, index 78; original object ID: 83 +83 +%% Object stream: object 81, index 79; original object ID: 84 +84 +%% Object stream: object 82, index 80; original object ID: 85 +85 +%% Object stream: object 83, index 81; original object ID: 86 +86 +%% Object stream: object 84, index 82; original object ID: 87 +87 +%% Object stream: object 85, index 83; original object ID: 88 +88 +%% Object stream: object 86, index 84; original object ID: 89 +89 +%% Object stream: object 87, index 85; original object ID: 90 +90 +%% Object stream: object 88, index 86; original object ID: 91 +91 +%% Object stream: object 89, index 87; original object ID: 92 +92 +%% Object stream: object 90, index 88; original object ID: 93 +93 +%% Object stream: object 91, index 89; original object ID: 94 +94 +%% Object stream: object 92, index 90; original object ID: 95 +95 +%% Object stream: object 93, index 91; original object ID: 96 +96 +%% Object stream: object 94, index 92; original object ID: 97 +97 +%% Object stream: object 95, index 93; original object ID: 98 +98 +%% Object stream: object 96, index 94; original object ID: 99 +99 +%% Object stream: object 97, index 95; original object ID: 100 +100 +%% Object stream: object 98, index 96; original object ID: 101 +101 +%% Object stream: object 99, index 97; original object ID: 102 +102 +%% Object stream: object 100, index 98; original object ID: 103 +103 +%% Object stream: object 101, index 99; original object ID: 104 +104 +%% Object stream: object 102, index 100; original object ID: 105 +105 +%% Object stream: object 103, index 101; original object ID: 106 +106 +%% Object stream: object 104, index 102; original object ID: 107 +107 +%% Object stream: object 105, index 103; original object ID: 108 +108 +%% Object stream: object 106, index 104; original object ID: 109 +109 +%% Object stream: object 107, index 105; original object ID: 110 +110 +%% Object stream: object 108, index 106; original object ID: 111 +111 +%% Object stream: object 109, index 107; original object ID: 112 +112 +%% Object stream: object 110, index 108; original object ID: 113 +113 +%% Object stream: object 111, index 109; original object ID: 114 +114 +%% Object stream: object 112, index 110; original object ID: 115 +115 +%% Object stream: object 113, index 111; original object ID: 116 +116 +%% Object stream: object 114, index 112; original object ID: 117 +117 +%% Object stream: object 115, index 113; original object ID: 118 +118 +%% Object stream: object 116, index 114; original object ID: 119 +119 +%% Object stream: object 117, index 115; original object ID: 120 +120 +%% Object stream: object 118, index 116; original object ID: 121 +121 +%% Object stream: object 119, index 117; original object ID: 122 +122 +%% Object stream: object 120, index 118; original object ID: 123 +123 +%% Object stream: object 121, index 119; original object ID: 124 +124 +%% Object stream: object 122, index 120; original object ID: 125 +125 +%% Object stream: object 123, index 121; original object ID: 126 +126 +%% Object stream: object 124, index 122; original object ID: 127 +127 +%% Object stream: object 125, index 123; original object ID: 128 +128 +%% Object stream: object 126, index 124; original object ID: 129 +129 +%% Object stream: object 127, index 125; original object ID: 130 +130 +%% Object stream: object 128, index 126; original object ID: 131 +131 +%% Object stream: object 129, index 127; original object ID: 132 +132 +%% Object stream: object 130, index 128; original object ID: 133 +133 +%% Object stream: object 131, index 129; original object ID: 134 +134 +%% Object stream: object 132, index 130; original object ID: 135 +135 +%% Object stream: object 133, index 131; original object ID: 136 +136 +%% Object stream: object 134, index 132; original object ID: 137 +137 +%% Object stream: object 135, index 133; original object ID: 138 +138 +%% Object stream: object 136, index 134; original object ID: 139 +139 +%% Object stream: object 137, index 135; original object ID: 140 +140 +%% Object stream: object 138, index 136; original object ID: 141 +141 +%% Object stream: object 139, index 137; original object ID: 142 +142 +%% Object stream: object 140, index 138; original object ID: 143 +143 +%% Object stream: object 141, index 139; original object ID: 144 +144 +%% Object stream: object 142, index 140; original object ID: 145 +145 +%% Object stream: object 143, index 141; original object ID: 146 +146 +%% Object stream: object 144, index 142; original object ID: 147 +147 +%% Object stream: object 145, index 143; original object ID: 148 +148 +%% Object stream: object 146, index 144; original object ID: 149 +149 +%% Object stream: object 147, index 145; original object ID: 150 +150 +%% Object stream: object 148, index 146; original object ID: 151 +151 +%% Object stream: object 149, index 147; original object ID: 152 +152 +%% Object stream: object 150, index 148; original object ID: 153 +153 +%% Object stream: object 151, index 149; original object ID: 154 +154 +%% Object stream: object 152, index 150; original object ID: 155 +155 +%% Object stream: object 153, index 151; original object ID: 156 +156 +%% Object stream: object 154, index 152; original object ID: 157 +157 +%% Object stream: object 155, index 153; original object ID: 158 +158 +%% Object stream: object 156, index 154; original object ID: 159 +159 +%% Object stream: object 157, index 155; original object ID: 160 +160 +%% Object stream: object 158, index 156; original object ID: 161 +161 +%% Object stream: object 159, index 157; original object ID: 162 +162 +%% Object stream: object 160, index 158; original object ID: 163 +163 +%% Object stream: object 161, index 159; original object ID: 164 +164 +%% Object stream: object 162, index 160; original object ID: 165 +165 +%% Object stream: object 163, index 161; original object ID: 166 +166 +%% Object stream: object 164, index 162; original object ID: 167 +167 +%% Object stream: object 165, index 163; original object ID: 168 +168 +%% Object stream: object 166, index 164; original object ID: 169 +169 +%% Object stream: object 167, index 165; original object ID: 170 +170 +%% Object stream: object 168, index 166; original object ID: 171 +171 +%% Object stream: object 169, index 167; original object ID: 172 +172 +%% Object stream: object 170, index 168; original object ID: 173 +173 +%% Object stream: object 171, index 169; original object ID: 174 +174 +%% Object stream: object 172, index 170; original object ID: 175 +175 +%% Object stream: object 173, index 171; original object ID: 176 +176 +%% Object stream: object 174, index 172; original object ID: 177 +177 +%% Object stream: object 175, index 173; original object ID: 178 +178 +%% Object stream: object 176, index 174; original object ID: 179 +179 +%% Object stream: object 177, index 175; original object ID: 180 +180 +%% Object stream: object 178, index 176; original object ID: 181 +181 +%% Object stream: object 179, index 177; original object ID: 182 +182 +%% Object stream: object 180, index 178; original object ID: 183 +183 +%% Object stream: object 181, index 179; original object ID: 184 +184 +%% Object stream: object 182, index 180; original object ID: 185 +185 +%% Object stream: object 183, index 181; original object ID: 186 +186 +%% Object stream: object 184, index 182; original object ID: 187 +187 +%% Object stream: object 185, index 183; original object ID: 188 +188 +%% Object stream: object 186, index 184; original object ID: 189 +189 +%% Object stream: object 187, index 185; original object ID: 190 +190 +%% Object stream: object 188, index 186; original object ID: 191 +191 +%% Object stream: object 189, index 187; original object ID: 192 +192 +%% Object stream: object 190, index 188; original object ID: 193 +193 +%% Object stream: object 191, index 189; original object ID: 194 +194 +%% Object stream: object 192, index 190; original object ID: 195 +195 +%% Object stream: object 193, index 191; original object ID: 196 +196 +%% Object stream: object 194, index 192; original object ID: 197 +197 +%% Object stream: object 195, index 193; original object ID: 198 +198 +%% Object stream: object 196, index 194; original object ID: 199 +199 +%% Object stream: object 197, index 195; original object ID: 200 +200 +%% Object stream: object 198, index 196; original object ID: 201 +201 +%% Object stream: object 199, index 197; original object ID: 202 +202 +%% Object stream: object 200, index 198; original object ID: 203 +203 +%% Object stream: object 201, index 199; original object ID: 204 +204 +%% Object stream: object 202, index 200; original object ID: 205 +205 +%% Object stream: object 203, index 201; original object ID: 206 +206 +%% Object stream: object 204, index 202; original object ID: 207 +207 +%% Object stream: object 205, index 203; original object ID: 208 +208 +%% Object stream: object 206, index 204; original object ID: 209 +209 +%% Object stream: object 207, index 205; original object ID: 210 +210 +%% Object stream: object 208, index 206; original object ID: 211 +211 +%% Object stream: object 209, index 207; original object ID: 212 +212 +%% Object stream: object 210, index 208; original object ID: 213 +213 +%% Object stream: object 211, index 209; original object ID: 214 +214 +%% Object stream: object 212, index 210; original object ID: 215 +215 +%% Object stream: object 213, index 211; original object ID: 216 +216 +%% Object stream: object 214, index 212; original object ID: 217 +217 +%% Object stream: object 215, index 213; original object ID: 218 +218 +%% Object stream: object 216, index 214; original object ID: 219 +219 +%% Object stream: object 217, index 215; original object ID: 220 +220 +%% Object stream: object 218, index 216; original object ID: 221 +221 +%% Object stream: object 219, index 217; original object ID: 222 +222 +%% Object stream: object 220, index 218; original object ID: 223 +223 +%% Object stream: object 221, index 219; original object ID: 224 +224 +%% Object stream: object 222, index 220; original object ID: 225 +225 +%% Object stream: object 223, index 221; original object ID: 226 +226 +%% Object stream: object 224, index 222; original object ID: 227 +227 +%% Object stream: object 225, index 223; original object ID: 228 +228 +%% Object stream: object 226, index 224; original object ID: 229 +229 +%% Object stream: object 227, index 225; original object ID: 230 +230 +%% Object stream: object 228, index 226; original object ID: 231 +231 +%% Object stream: object 229, index 227; original object ID: 232 +232 +%% Object stream: object 230, index 228; original object ID: 233 +233 +%% Object stream: object 231, index 229; original object ID: 234 +234 +%% Object stream: object 232, index 230; original object ID: 235 +235 +%% Object stream: object 233, index 231; original object ID: 236 +236 +%% Object stream: object 234, index 232; original object ID: 237 +237 +%% Object stream: object 235, index 233; original object ID: 238 +238 +%% Object stream: object 236, index 234; original object ID: 239 +239 +%% Object stream: object 237, index 235; original object ID: 240 +240 +%% Object stream: object 238, index 236; original object ID: 241 +241 +%% Object stream: object 239, index 237; original object ID: 242 +242 +%% Object stream: object 240, index 238; original object ID: 243 +243 +%% Object stream: object 241, index 239; original object ID: 244 +244 +%% Object stream: object 242, index 240; original object ID: 245 +245 +%% Object stream: object 243, index 241; original object ID: 246 +246 +%% Object stream: object 244, index 242; original object ID: 247 +247 +%% Object stream: object 245, index 243; original object ID: 248 +248 +%% Object stream: object 246, index 244; original object ID: 249 +249 +%% Object stream: object 247, index 245; original object ID: 250 +250 +%% Object stream: object 248, index 246; original object ID: 251 +251 +%% Object stream: object 249, index 247; original object ID: 252 +252 +%% Object stream: object 250, index 248; original object ID: 253 +253 +%% Object stream: object 251, index 249; original object ID: 254 +254 +%% Object stream: object 252, index 250; original object ID: 255 +255 +%% Object stream: object 253, index 251; original object ID: 256 +256 +%% Object stream: object 254, index 252; original object ID: 257 +257 +%% Object stream: object 255, index 253; original object ID: 258 +258 +%% Object stream: object 256, index 254; original object ID: 259 +259 +%% Object stream: object 257, index 255; original object ID: 260 +260 +%% Object stream: object 258, index 256; original object ID: 261 +261 +%% Object stream: object 259, index 257; original object ID: 262 +262 +%% Object stream: object 260, index 258; original object ID: 263 +263 +%% Object stream: object 261, index 259; original object ID: 264 +264 +%% Object stream: object 262, index 260; original object ID: 265 +265 +%% Object stream: object 263, index 261; original object ID: 266 +266 +%% Object stream: object 264, index 262; original object ID: 267 +267 +%% Object stream: object 265, index 263; original object ID: 268 +268 +endstream +endobj + +%% Contents for page 1 +%% Original object ID: 4 0 +266 0 obj +<< + /Length 267 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Potato) Tj +ET +endstream +endobj + +267 0 obj +44 +endobj + +268 0 obj +<< + /Type /ObjStm + /Length 20694 + /N 264 + /First 2540 +>> +stream +269 0 +270 163 +271 245 +272 312 +273 379 +274 446 +275 513 +276 580 +277 647 +278 714 +279 782 +280 850 +281 918 +282 986 +283 1054 +284 1122 +285 1190 +286 1258 +287 1326 +288 1394 +289 1462 +290 1530 +291 1598 +292 1666 +293 1734 +294 1802 +295 1870 +296 1938 +297 2006 +298 2074 +299 2142 +300 2210 +301 2278 +302 2346 +303 2414 +304 2482 +305 2550 +306 2618 +307 2686 +308 2754 +309 2822 +310 2890 +311 2958 +312 3026 +313 3094 +314 3162 +315 3230 +316 3298 +317 3366 +318 3434 +319 3502 +320 3570 +321 3638 +322 3706 +323 3774 +324 3842 +325 3910 +326 3978 +327 4046 +328 4114 +329 4182 +330 4250 +331 4318 +332 4386 +333 4454 +334 4522 +335 4590 +336 4658 +337 4726 +338 4794 +339 4862 +340 4930 +341 4998 +342 5066 +343 5134 +344 5202 +345 5270 +346 5338 +347 5406 +348 5474 +349 5542 +350 5610 +351 5678 +352 5746 +353 5814 +354 5882 +355 5950 +356 6018 +357 6086 +358 6154 +359 6222 +360 6290 +361 6358 +362 6426 +363 6494 +364 6562 +365 6630 +366 6698 +367 6766 +368 6834 +369 6903 +370 6972 +371 7041 +372 7110 +373 7179 +374 7248 +375 7317 +376 7386 +377 7455 +378 7524 +379 7593 +380 7662 +381 7731 +382 7800 +383 7869 +384 7938 +385 8007 +386 8076 +387 8145 +388 8214 +389 8283 +390 8352 +391 8421 +392 8490 +393 8559 +394 8628 +395 8697 +396 8766 +397 8835 +398 8904 +399 8973 +400 9042 +401 9111 +402 9180 +403 9249 +404 9318 +405 9387 +406 9456 +407 9525 +408 9594 +409 9663 +410 9732 +411 9801 +412 9870 +413 9939 +414 10008 +415 10077 +416 10146 +417 10215 +418 10284 +419 10353 +420 10422 +421 10491 +422 10560 +423 10629 +424 10698 +425 10767 +426 10836 +427 10905 +428 10974 +429 11043 +430 11112 +431 11181 +432 11250 +433 11319 +434 11388 +435 11457 +436 11526 +437 11595 +438 11664 +439 11733 +440 11802 +441 11871 +442 11940 +443 12009 +444 12078 +445 12147 +446 12216 +447 12285 +448 12354 +449 12423 +450 12492 +451 12561 +452 12630 +453 12699 +454 12768 +455 12837 +456 12906 +457 12975 +458 13044 +459 13113 +460 13182 +461 13251 +462 13320 +463 13389 +464 13458 +465 13527 +466 13596 +467 13665 +468 13734 +469 13803 +470 13872 +471 13941 +472 14010 +473 14079 +474 14148 +475 14217 +476 14286 +477 14355 +478 14424 +479 14493 +480 14562 +481 14631 +482 14700 +483 14769 +484 14838 +485 14907 +486 14976 +487 15045 +488 15114 +489 15183 +490 15252 +491 15321 +492 15390 +493 15459 +494 15528 +495 15597 +496 15666 +497 15735 +498 15804 +499 15873 +500 15942 +501 16011 +502 16080 +503 16149 +504 16218 +505 16287 +506 16356 +507 16425 +508 16494 +509 16563 +510 16632 +511 16701 +512 16770 +513 16839 +514 16908 +515 16977 +516 17046 +517 17115 +518 17184 +519 17253 +520 17322 +521 17391 +522 17460 +523 17529 +524 17598 +525 17667 +526 17736 +527 17805 +528 17874 +529 17943 +530 18012 +531 18081 +532 18150 +%% Object stream: object 269, index 0; original object ID: 6 +<< + /BaseFont /Helvetica + /Encoding /WinAnsiEncoding + /Name /F1 + /Subtype /Type1 + /Type /Font +>> +%% Object stream: object 270, index 1; original object ID: 7 +[ + /PDF + /Text +] +%% Object stream: object 271, index 2; original object ID: 269 +269 +%% Object stream: object 272, index 3; original object ID: 270 +270 +%% Object stream: object 273, index 4; original object ID: 271 +271 +%% Object stream: object 274, index 5; original object ID: 272 +272 +%% Object stream: object 275, index 6; original object ID: 273 +273 +%% Object stream: object 276, index 7; original object ID: 274 +274 +%% Object stream: object 277, index 8; original object ID: 275 +275 +%% Object stream: object 278, index 9; original object ID: 276 +276 +%% Object stream: object 279, index 10; original object ID: 277 +277 +%% Object stream: object 280, index 11; original object ID: 278 +278 +%% Object stream: object 281, index 12; original object ID: 279 +279 +%% Object stream: object 282, index 13; original object ID: 280 +280 +%% Object stream: object 283, index 14; original object ID: 281 +281 +%% Object stream: object 284, index 15; original object ID: 282 +282 +%% Object stream: object 285, index 16; original object ID: 283 +283 +%% Object stream: object 286, index 17; original object ID: 284 +284 +%% Object stream: object 287, index 18; original object ID: 285 +285 +%% Object stream: object 288, index 19; original object ID: 286 +286 +%% Object stream: object 289, index 20; original object ID: 287 +287 +%% Object stream: object 290, index 21; original object ID: 288 +288 +%% Object stream: object 291, index 22; original object ID: 289 +289 +%% Object stream: object 292, index 23; original object ID: 290 +290 +%% Object stream: object 293, index 24; original object ID: 291 +291 +%% Object stream: object 294, index 25; original object ID: 292 +292 +%% Object stream: object 295, index 26; original object ID: 293 +293 +%% Object stream: object 296, index 27; original object ID: 294 +294 +%% Object stream: object 297, index 28; original object ID: 295 +295 +%% Object stream: object 298, index 29; original object ID: 296 +296 +%% Object stream: object 299, index 30; original object ID: 297 +297 +%% Object stream: object 300, index 31; original object ID: 298 +298 +%% Object stream: object 301, index 32; original object ID: 299 +299 +%% Object stream: object 302, index 33; original object ID: 300 +300 +%% Object stream: object 303, index 34; original object ID: 301 +301 +%% Object stream: object 304, index 35; original object ID: 302 +302 +%% Object stream: object 305, index 36; original object ID: 303 +303 +%% Object stream: object 306, index 37; original object ID: 304 +304 +%% Object stream: object 307, index 38; original object ID: 305 +305 +%% Object stream: object 308, index 39; original object ID: 306 +306 +%% Object stream: object 309, index 40; original object ID: 307 +307 +%% Object stream: object 310, index 41; original object ID: 308 +308 +%% Object stream: object 311, index 42; original object ID: 309 +309 +%% Object stream: object 312, index 43; original object ID: 310 +310 +%% Object stream: object 313, index 44; original object ID: 311 +311 +%% Object stream: object 314, index 45; original object ID: 312 +312 +%% Object stream: object 315, index 46; original object ID: 313 +313 +%% Object stream: object 316, index 47; original object ID: 314 +314 +%% Object stream: object 317, index 48; original object ID: 315 +315 +%% Object stream: object 318, index 49; original object ID: 316 +316 +%% Object stream: object 319, index 50; original object ID: 317 +317 +%% Object stream: object 320, index 51; original object ID: 318 +318 +%% Object stream: object 321, index 52; original object ID: 319 +319 +%% Object stream: object 322, index 53; original object ID: 320 +320 +%% Object stream: object 323, index 54; original object ID: 321 +321 +%% Object stream: object 324, index 55; original object ID: 322 +322 +%% Object stream: object 325, index 56; original object ID: 323 +323 +%% Object stream: object 326, index 57; original object ID: 324 +324 +%% Object stream: object 327, index 58; original object ID: 325 +325 +%% Object stream: object 328, index 59; original object ID: 326 +326 +%% Object stream: object 329, index 60; original object ID: 327 +327 +%% Object stream: object 330, index 61; original object ID: 328 +328 +%% Object stream: object 331, index 62; original object ID: 329 +329 +%% Object stream: object 332, index 63; original object ID: 330 +330 +%% Object stream: object 333, index 64; original object ID: 331 +331 +%% Object stream: object 334, index 65; original object ID: 332 +332 +%% Object stream: object 335, index 66; original object ID: 333 +333 +%% Object stream: object 336, index 67; original object ID: 334 +334 +%% Object stream: object 337, index 68; original object ID: 335 +335 +%% Object stream: object 338, index 69; original object ID: 336 +336 +%% Object stream: object 339, index 70; original object ID: 337 +337 +%% Object stream: object 340, index 71; original object ID: 338 +338 +%% Object stream: object 341, index 72; original object ID: 339 +339 +%% Object stream: object 342, index 73; original object ID: 340 +340 +%% Object stream: object 343, index 74; original object ID: 341 +341 +%% Object stream: object 344, index 75; original object ID: 342 +342 +%% Object stream: object 345, index 76; original object ID: 343 +343 +%% Object stream: object 346, index 77; original object ID: 344 +344 +%% Object stream: object 347, index 78; original object ID: 345 +345 +%% Object stream: object 348, index 79; original object ID: 346 +346 +%% Object stream: object 349, index 80; original object ID: 347 +347 +%% Object stream: object 350, index 81; original object ID: 348 +348 +%% Object stream: object 351, index 82; original object ID: 349 +349 +%% Object stream: object 352, index 83; original object ID: 350 +350 +%% Object stream: object 353, index 84; original object ID: 351 +351 +%% Object stream: object 354, index 85; original object ID: 352 +352 +%% Object stream: object 355, index 86; original object ID: 353 +353 +%% Object stream: object 356, index 87; original object ID: 354 +354 +%% Object stream: object 357, index 88; original object ID: 355 +355 +%% Object stream: object 358, index 89; original object ID: 356 +356 +%% Object stream: object 359, index 90; original object ID: 357 +357 +%% Object stream: object 360, index 91; original object ID: 358 +358 +%% Object stream: object 361, index 92; original object ID: 359 +359 +%% Object stream: object 362, index 93; original object ID: 360 +360 +%% Object stream: object 363, index 94; original object ID: 361 +361 +%% Object stream: object 364, index 95; original object ID: 362 +362 +%% Object stream: object 365, index 96; original object ID: 363 +363 +%% Object stream: object 366, index 97; original object ID: 364 +364 +%% Object stream: object 367, index 98; original object ID: 365 +365 +%% Object stream: object 368, index 99; original object ID: 366 +366 +%% Object stream: object 369, index 100; original object ID: 367 +367 +%% Object stream: object 370, index 101; original object ID: 368 +368 +%% Object stream: object 371, index 102; original object ID: 369 +369 +%% Object stream: object 372, index 103; original object ID: 370 +370 +%% Object stream: object 373, index 104; original object ID: 371 +371 +%% Object stream: object 374, index 105; original object ID: 372 +372 +%% Object stream: object 375, index 106; original object ID: 373 +373 +%% Object stream: object 376, index 107; original object ID: 374 +374 +%% Object stream: object 377, index 108; original object ID: 375 +375 +%% Object stream: object 378, index 109; original object ID: 376 +376 +%% Object stream: object 379, index 110; original object ID: 377 +377 +%% Object stream: object 380, index 111; original object ID: 378 +378 +%% Object stream: object 381, index 112; original object ID: 379 +379 +%% Object stream: object 382, index 113; original object ID: 380 +380 +%% Object stream: object 383, index 114; original object ID: 381 +381 +%% Object stream: object 384, index 115; original object ID: 382 +382 +%% Object stream: object 385, index 116; original object ID: 383 +383 +%% Object stream: object 386, index 117; original object ID: 384 +384 +%% Object stream: object 387, index 118; original object ID: 385 +385 +%% Object stream: object 388, index 119; original object ID: 386 +386 +%% Object stream: object 389, index 120; original object ID: 387 +387 +%% Object stream: object 390, index 121; original object ID: 388 +388 +%% Object stream: object 391, index 122; original object ID: 389 +389 +%% Object stream: object 392, index 123; original object ID: 390 +390 +%% Object stream: object 393, index 124; original object ID: 391 +391 +%% Object stream: object 394, index 125; original object ID: 392 +392 +%% Object stream: object 395, index 126; original object ID: 393 +393 +%% Object stream: object 396, index 127; original object ID: 394 +394 +%% Object stream: object 397, index 128; original object ID: 395 +395 +%% Object stream: object 398, index 129; original object ID: 396 +396 +%% Object stream: object 399, index 130; original object ID: 397 +397 +%% Object stream: object 400, index 131; original object ID: 398 +398 +%% Object stream: object 401, index 132; original object ID: 399 +399 +%% Object stream: object 402, index 133; original object ID: 400 +400 +%% Object stream: object 403, index 134; original object ID: 401 +401 +%% Object stream: object 404, index 135; original object ID: 402 +402 +%% Object stream: object 405, index 136; original object ID: 403 +403 +%% Object stream: object 406, index 137; original object ID: 404 +404 +%% Object stream: object 407, index 138; original object ID: 405 +405 +%% Object stream: object 408, index 139; original object ID: 406 +406 +%% Object stream: object 409, index 140; original object ID: 407 +407 +%% Object stream: object 410, index 141; original object ID: 408 +408 +%% Object stream: object 411, index 142; original object ID: 409 +409 +%% Object stream: object 412, index 143; original object ID: 410 +410 +%% Object stream: object 413, index 144; original object ID: 411 +411 +%% Object stream: object 414, index 145; original object ID: 412 +412 +%% Object stream: object 415, index 146; original object ID: 413 +413 +%% Object stream: object 416, index 147; original object ID: 414 +414 +%% Object stream: object 417, index 148; original object ID: 415 +415 +%% Object stream: object 418, index 149; original object ID: 416 +416 +%% Object stream: object 419, index 150; original object ID: 417 +417 +%% Object stream: object 420, index 151; original object ID: 418 +418 +%% Object stream: object 421, index 152; original object ID: 419 +419 +%% Object stream: object 422, index 153; original object ID: 420 +420 +%% Object stream: object 423, index 154; original object ID: 421 +421 +%% Object stream: object 424, index 155; original object ID: 422 +422 +%% Object stream: object 425, index 156; original object ID: 423 +423 +%% Object stream: object 426, index 157; original object ID: 424 +424 +%% Object stream: object 427, index 158; original object ID: 425 +425 +%% Object stream: object 428, index 159; original object ID: 426 +426 +%% Object stream: object 429, index 160; original object ID: 427 +427 +%% Object stream: object 430, index 161; original object ID: 428 +428 +%% Object stream: object 431, index 162; original object ID: 429 +429 +%% Object stream: object 432, index 163; original object ID: 430 +430 +%% Object stream: object 433, index 164; original object ID: 431 +431 +%% Object stream: object 434, index 165; original object ID: 432 +432 +%% Object stream: object 435, index 166; original object ID: 433 +433 +%% Object stream: object 436, index 167; original object ID: 434 +434 +%% Object stream: object 437, index 168; original object ID: 435 +435 +%% Object stream: object 438, index 169; original object ID: 436 +436 +%% Object stream: object 439, index 170; original object ID: 437 +437 +%% Object stream: object 440, index 171; original object ID: 438 +438 +%% Object stream: object 441, index 172; original object ID: 439 +439 +%% Object stream: object 442, index 173; original object ID: 440 +440 +%% Object stream: object 443, index 174; original object ID: 441 +441 +%% Object stream: object 444, index 175; original object ID: 442 +442 +%% Object stream: object 445, index 176; original object ID: 443 +443 +%% Object stream: object 446, index 177; original object ID: 444 +444 +%% Object stream: object 447, index 178; original object ID: 445 +445 +%% Object stream: object 448, index 179; original object ID: 446 +446 +%% Object stream: object 449, index 180; original object ID: 447 +447 +%% Object stream: object 450, index 181; original object ID: 448 +448 +%% Object stream: object 451, index 182; original object ID: 449 +449 +%% Object stream: object 452, index 183; original object ID: 450 +450 +%% Object stream: object 453, index 184; original object ID: 451 +451 +%% Object stream: object 454, index 185; original object ID: 452 +452 +%% Object stream: object 455, index 186; original object ID: 453 +453 +%% Object stream: object 456, index 187; original object ID: 454 +454 +%% Object stream: object 457, index 188; original object ID: 455 +455 +%% Object stream: object 458, index 189; original object ID: 456 +456 +%% Object stream: object 459, index 190; original object ID: 457 +457 +%% Object stream: object 460, index 191; original object ID: 458 +458 +%% Object stream: object 461, index 192; original object ID: 459 +459 +%% Object stream: object 462, index 193; original object ID: 460 +460 +%% Object stream: object 463, index 194; original object ID: 461 +461 +%% Object stream: object 464, index 195; original object ID: 462 +462 +%% Object stream: object 465, index 196; original object ID: 463 +463 +%% Object stream: object 466, index 197; original object ID: 464 +464 +%% Object stream: object 467, index 198; original object ID: 465 +465 +%% Object stream: object 468, index 199; original object ID: 466 +466 +%% Object stream: object 469, index 200; original object ID: 467 +467 +%% Object stream: object 470, index 201; original object ID: 468 +468 +%% Object stream: object 471, index 202; original object ID: 469 +469 +%% Object stream: object 472, index 203; original object ID: 470 +470 +%% Object stream: object 473, index 204; original object ID: 471 +471 +%% Object stream: object 474, index 205; original object ID: 472 +472 +%% Object stream: object 475, index 206; original object ID: 473 +473 +%% Object stream: object 476, index 207; original object ID: 474 +474 +%% Object stream: object 477, index 208; original object ID: 475 +475 +%% Object stream: object 478, index 209; original object ID: 476 +476 +%% Object stream: object 479, index 210; original object ID: 477 +477 +%% Object stream: object 480, index 211; original object ID: 478 +478 +%% Object stream: object 481, index 212; original object ID: 479 +479 +%% Object stream: object 482, index 213; original object ID: 480 +480 +%% Object stream: object 483, index 214; original object ID: 481 +481 +%% Object stream: object 484, index 215; original object ID: 482 +482 +%% Object stream: object 485, index 216; original object ID: 483 +483 +%% Object stream: object 486, index 217; original object ID: 484 +484 +%% Object stream: object 487, index 218; original object ID: 485 +485 +%% Object stream: object 488, index 219; original object ID: 486 +486 +%% Object stream: object 489, index 220; original object ID: 487 +487 +%% Object stream: object 490, index 221; original object ID: 488 +488 +%% Object stream: object 491, index 222; original object ID: 489 +489 +%% Object stream: object 492, index 223; original object ID: 490 +490 +%% Object stream: object 493, index 224; original object ID: 491 +491 +%% Object stream: object 494, index 225; original object ID: 492 +492 +%% Object stream: object 495, index 226; original object ID: 493 +493 +%% Object stream: object 496, index 227; original object ID: 494 +494 +%% Object stream: object 497, index 228; original object ID: 495 +495 +%% Object stream: object 498, index 229; original object ID: 496 +496 +%% Object stream: object 499, index 230; original object ID: 497 +497 +%% Object stream: object 500, index 231; original object ID: 498 +498 +%% Object stream: object 501, index 232; original object ID: 499 +499 +%% Object stream: object 502, index 233; original object ID: 500 +500 +%% Object stream: object 503, index 234; original object ID: 501 +501 +%% Object stream: object 504, index 235; original object ID: 502 +502 +%% Object stream: object 505, index 236; original object ID: 503 +503 +%% Object stream: object 506, index 237; original object ID: 504 +504 +%% Object stream: object 507, index 238; original object ID: 505 +505 +%% Object stream: object 508, index 239; original object ID: 506 +506 +%% Object stream: object 509, index 240; original object ID: 507 +507 +%% Object stream: object 510, index 241; original object ID: 508 +508 +%% Object stream: object 511, index 242; original object ID: 509 +509 +%% Object stream: object 512, index 243; original object ID: 510 +510 +%% Object stream: object 513, index 244; original object ID: 511 +511 +%% Object stream: object 514, index 245; original object ID: 512 +512 +%% Object stream: object 515, index 246; original object ID: 513 +513 +%% Object stream: object 516, index 247; original object ID: 514 +514 +%% Object stream: object 517, index 248; original object ID: 515 +515 +%% Object stream: object 518, index 249; original object ID: 516 +516 +%% Object stream: object 519, index 250; original object ID: 517 +517 +%% Object stream: object 520, index 251; original object ID: 518 +518 +%% Object stream: object 521, index 252; original object ID: 519 +519 +%% Object stream: object 522, index 253; original object ID: 520 +520 +%% Object stream: object 523, index 254; original object ID: 521 +521 +%% Object stream: object 524, index 255; original object ID: 522 +522 +%% Object stream: object 525, index 256; original object ID: 523 +523 +%% Object stream: object 526, index 257; original object ID: 524 +524 +%% Object stream: object 527, index 258; original object ID: 525 +525 +%% Object stream: object 528, index 259; original object ID: 526 +526 +%% Object stream: object 529, index 260; original object ID: 527 +527 +%% Object stream: object 530, index 261; original object ID: 528 +528 +%% Object stream: object 531, index 262; original object ID: 529 +529 +%% Object stream: object 532, index 263; original object ID: 530 +530 +endstream +endobj + +533 0 obj +<< + /Type /XRef + /Length 2670 + /W [ 1 2 2 ] + /Root 2 0 R + /Size 534 + /ID [<2d98332206f35946375ab6da40293f06><dd6e9d4209d585c25e793fc4d932f319>] +>> +stream + + + +endstream +endobj + +startxref +46758 +%%EOF diff --git a/qpdf/qtest/qpdf/indirect-r-arg.out b/qpdf/qtest/qpdf/indirect-r-arg.out new file mode 100644 index 0000000..e065ec1 --- /dev/null +++ b/qpdf/qtest/qpdf/indirect-r-arg.out @@ -0,0 +1 @@ +indirect-r-arg.pdf (file position 76): unknown token while reading object (R) diff --git a/qpdf/qtest/qpdf/indirect-r-arg.pdf b/qpdf/qtest/qpdf/indirect-r-arg.pdf new file mode 100644 index 0000000..2a6d18e --- /dev/null +++ b/qpdf/qtest/qpdf/indirect-r-arg.pdf @@ -0,0 +1,102 @@ +%PDF-1.3 +%¿÷¢þ +%QDF-1.0 + +%% Original object ID: 1 0 +1 0 obj +<< + /X 1 0 R 0 R + /Pages 2 0 R + /Type /Catalog +>> +endobj + +%% Original object ID: 2 0 +2 0 obj +<< + /Count 1 + /Kids [ + 3 0 R + ] + /Type /Pages +>> +endobj + +%% Page 1 +%% Original object ID: 3 0 +3 0 obj +<< + /Contents 4 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 2 0 R + /Resources << + /Font << + /F1 6 0 R + >> + /ProcSet 7 0 R + >> + /Type /Page +>> +endobj + +%% Contents for page 1 +%% Original object ID: 4 0 +4 0 obj +<< + /Length 5 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Potato) Tj +ET +endstream +endobj + +5 0 obj +44 +endobj + +%% Original object ID: 6 0 +6 0 obj +<< + /BaseFont /Helvetica + /Encoding /WinAnsiEncoding + /Name /F1 + /Subtype /Type1 + /Type /Font +>> +endobj + +%% Original object ID: 5 0 +7 0 obj +[ + /PDF + /Text +] +endobj + +xref +0 8 +0000000000 65535 f +0000000052 00000 n +0000000148 00000 n +0000000257 00000 n +0000000499 00000 n +0000000598 00000 n +0000000644 00000 n +0000000789 00000 n +trailer << + /Root 1 0 R + /Size 8 + /ID [<9e2756c6254602d0b896148e97ee7414><9e2756c6254602d0b896148e97ee7414>] +>> +startxref +824 +%%EOF diff --git a/qpdf/qtest/qpdf/no-pages-types.out b/qpdf/qtest/qpdf/no-pages-types.out new file mode 100644 index 0000000..0d5eb23 --- /dev/null +++ b/qpdf/qtest/qpdf/no-pages-types.out @@ -0,0 +1,6 @@ +checking no-pages-types.pdf +PDF Version: 1.3 +File is not encrypted +File is not linearized +No syntax or stream encoding errors found; the file may still contain +errors that qpdf cannot detect diff --git a/qpdf/qtest/qpdf/no-pages-types.pdf b/qpdf/qtest/qpdf/no-pages-types.pdf new file mode 100644 index 0000000..9bef0bb --- /dev/null +++ b/qpdf/qtest/qpdf/no-pages-types.pdf @@ -0,0 +1,79 @@ +%PDF-1.3 +1 0 obj +<< + /Type /Catalog + /Pages 2 0 R +>> +endobj + +2 0 obj +<< + /Zype /Pages + /Kids [ + 3 0 R + ] + /Count 1 +>> +endobj + +3 0 obj +<< + /Zype /Page + /Parent 2 0 R + /MediaBox [0 0 612 792] + /Contents 4 0 R + /Resources << + /ProcSet 5 0 R + /Font << + /F1 6 0 R + >> + >> +>> +endobj + +4 0 obj +<< + /Length 44 +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Potato) Tj +ET +endstream +endobj + +5 0 obj +[ + /PDF + /Text +] +endobj + +6 0 obj +<< + /Type /Font + /Subtype /Type1 + /Name /F1 + /BaseFont /Helvetica + /Encoding /WinAnsiEncoding +>> +endobj + +xref +0 7 +0000000000 65535 f +0000000009 00000 n +0000000063 00000 n +0000000135 00000 n +0000000307 00000 n +0000000403 00000 n +0000000438 00000 n +trailer << + /Size 7 + /Root 1 0 R +>> +startxref +556 +%%EOF diff --git a/qpdf/qtest/qpdf/page-no-content.out b/qpdf/qtest/qpdf/page-no-content.out new file mode 100644 index 0000000..15df72d --- /dev/null +++ b/qpdf/qtest/qpdf/page-no-content.out @@ -0,0 +1,8 @@ +page 1: 3 0 R + content: + 6 0 R +page 2: 4 0 R + content: +page 3: 5 0 R + content: + 9 0 R diff --git a/qpdf/qtest/qpdf/page-no-content.pdf b/qpdf/qtest/qpdf/page-no-content.pdf Binary files differnew file mode 100644 index 0000000..77b7832 --- /dev/null +++ b/qpdf/qtest/qpdf/page-no-content.pdf diff --git a/qpdf/qtest/qpdf/pages-loop.out b/qpdf/qtest/qpdf/pages-loop.out new file mode 100644 index 0000000..08643aa --- /dev/null +++ b/qpdf/qtest/qpdf/pages-loop.out @@ -0,0 +1,5 @@ +checking pages-loop.pdf +PDF Version: 1.3 +File is not encrypted +File is not linearized +pages-loop.pdf (object 3 0): Loop detected in /Pages structure (getAllPages) diff --git a/qpdf/qtest/qpdf/pages-loop.pdf b/qpdf/qtest/qpdf/pages-loop.pdf new file mode 100644 index 0000000..a41b750 --- /dev/null +++ b/qpdf/qtest/qpdf/pages-loop.pdf @@ -0,0 +1,102 @@ +%PDF-1.3 +%¿÷¢þ +%QDF-1.0 + +%% Original object ID: 1 0 +1 0 obj +<< + /Pages 2 0 R + /Type /Catalog +>> +endobj + +%% Original object ID: 2 0 +2 0 obj +<< + /Count 1 + /Kids [ + 3 0 R + 2 0 R + ] + /Type /Pages +>> +endobj + +%% Page 1 +%% Original object ID: 3 0 +3 0 obj +<< + /Contents 4 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 2 0 R + /Resources << + /Font << + /F1 6 0 R + >> + /ProcSet 7 0 R + >> + /Type /Page +>> +endobj + +%% Contents for page 1 +%% Original object ID: 4 0 +4 0 obj +<< + /Length 5 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Potato) Tj +ET +endstream +endobj + +5 0 obj +44 +endobj + +%% Original object ID: 6 0 +6 0 obj +<< + /BaseFont /Helvetica + /Encoding /WinAnsiEncoding + /Name /F1 + /Subtype /Type1 + /Type /Font +>> +endobj + +%% Original object ID: 5 0 +7 0 obj +[ + /PDF + /Text +] +endobj + +xref +0 8 +0000000000 65535 f +0000000052 00000 n +0000000133 00000 n +0000000252 00000 n +0000000494 00000 n +0000000593 00000 n +0000000639 00000 n +0000000784 00000 n +trailer << + /Root 1 0 R + /Size 8 + /ID [<395875d4235973eebbade9c7e9e7f857><395875d4235973eebbade9c7e9e7f857>] +>> +startxref +819 +%%EOF |