diff -Nru qpdf-8.0.2/aclocal.m4 qpdf-10.0.1/aclocal.m4 --- qpdf-8.0.2/aclocal.m4 2018-03-06 16:46:15.000000000 +0000 +++ qpdf-10.0.1/aclocal.m4 2020-04-09 15:48:26.000000000 +0000 @@ -1,6 +1,6 @@ -# generated automatically by aclocal 1.15 -*- Autoconf -*- +# generated automatically by aclocal 1.16.1 -*- Autoconf -*- -# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# Copyright (C) 1996-2018 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -12,9 +12,11 @@ # PARTICULAR PURPOSE. m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) +m4_include([m4/ax_cxx_compile_stdcxx.m4]) m4_include([m4/ax_random_device.m4]) m4_include([m4/libtool.m4]) m4_include([m4/ltoptions.m4]) m4_include([m4/ltsugar.m4]) m4_include([m4/ltversion.m4]) m4_include([m4/lt~obsolete.m4]) +m4_include([m4/pkg.m4]) diff -Nru qpdf-8.0.2/appimage/build-appimage qpdf-10.0.1/appimage/build-appimage --- qpdf-8.0.2/appimage/build-appimage 2018-03-06 16:34:07.000000000 +0000 +++ qpdf-10.0.1/appimage/build-appimage 2020-04-09 15:48:26.000000000 +0000 @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright (c) 2018 Jay Berkenbilt and Kurt Pfeifle +# Copyright (c) 2019-2020 Jay Berkenbilt and Kurt Pfeifle # # This script is mainly meant to build an 'AppImage' from GitHub # sources of QPDF via Travis CI on an Ubuntu Trusty (14.04) LTS system @@ -49,14 +49,14 @@ _osversion=$(cat /etc/os-release | grep PRETTY_NAME | awk -F'=' '{print $2}' | sed 's#"##g') # Warn users building the AppImage locally: -if [[ ! $_osversion =~ Ubuntu\ 14.04.*\ LTS ]]; then +if [[ ! $_osversion =~ Ubuntu\ 16.04.*\ LTS ]]; then set +x echo "" # 0 1 2 3 4 5 6 7 # 01234567890123456789012345678901234567890123456789012345678901234567890123456789 echo "+===========================================================================+" echo "|| WARNING: You are about to build a QPDF AppImage on a system which is ||" - echo "|| NOT Ubuntu 14.04 LTS ('Trusty'). ||" + echo "|| NOT Ubuntu 16.04 LTS ('Xenial'). ||" echo "|| ||" echo "|| It is recommended that you use a distribution that is at least a ||" echo "|| few years old to maximize the number of Linux distributions the ||" @@ -83,8 +83,8 @@ rm -rf $here/build # Prepare build of QPDF from sources: -./autogen.sh ./configure --prefix=/usr --enable-werror \ + --enable-crypto-gnutls --disable-implicit-crypto \ --enable-show-failed-test-output \ --enable-html-doc --enable-pdf-doc "$CUSTOM_CONFIGURE" @@ -93,7 +93,7 @@ if [ "$SKIP_TESTS" = "" ]; then # Run built-in QPDF checks: - make check + make -k check fi # Prepare AppDir which is the basis for the AppImage: diff -Nru qpdf-8.0.2/appimage/Dockerfile qpdf-10.0.1/appimage/Dockerfile --- qpdf-8.0.2/appimage/Dockerfile 2018-03-06 16:34:07.000000000 +0000 +++ qpdf-10.0.1/appimage/Dockerfile 2020-04-09 15:48:26.000000000 +0000 @@ -1,7 +1,7 @@ -FROM ubuntu:14.04 +FROM ubuntu:16.04 RUN apt-get update && \ - apt-get -y install screen autoconf git \ - build-essential zlib1g-dev libjpeg-dev \ + apt-get -y install screen autoconf git sudo \ + build-essential zlib1g-dev libjpeg-dev libgnutls28-dev \ docbook-xsl fop xsltproc \ inkscape imagemagick busybox-static wget fuse && \ apt-get clean && \ diff -Nru qpdf-8.0.2/appimage/entrypoint qpdf-10.0.1/appimage/entrypoint --- qpdf-8.0.2/appimage/entrypoint 2018-03-06 16:34:07.000000000 +0000 +++ qpdf-10.0.1/appimage/entrypoint 2020-04-09 15:48:26.000000000 +0000 @@ -4,8 +4,8 @@ touch /tmp/skip-tests fi if [ $(id -u) = 0 ]; then - if [ ! -d /tmp/build/.gnupg ]; then - echo "/tmp/build must exist and must contain .gnupg" + if [ ! -d /tmp/build ]; then + echo "/tmp/build must exist" exit 2 fi id=$(stat -c %u /tmp/build) @@ -25,4 +25,4 @@ if [ -f /tmp/skip-tests ]; then export SKIP_TESTS=1 fi -./appimage/build-appimage --sign +./appimage/build-appimage diff -Nru qpdf-8.0.2/appimage/qpdf.appdata.xml qpdf-10.0.1/appimage/qpdf.appdata.xml --- qpdf-8.0.2/appimage/qpdf.appdata.xml 2018-03-06 16:34:07.000000000 +0000 +++ qpdf-10.0.1/appimage/qpdf.appdata.xml 2020-04-09 15:48:26.000000000 +0000 @@ -1,5 +1,5 @@ - + org.QPDF.qpdf.desktop MIT diff -Nru qpdf-8.0.2/autoconf.mk.in qpdf-10.0.1/autoconf.mk.in --- qpdf-8.0.2/autoconf.mk.in 2018-03-06 16:34:07.000000000 +0000 +++ qpdf-10.0.1/autoconf.mk.in 2020-04-09 15:48:26.000000000 +0000 @@ -30,6 +30,9 @@ OBJDUMP=@OBJDUMP@ GENDEPS=@GENDEPS@ LIBTOOL=@LIBTOOL@ +USE_CRYPTO_NATIVE=@USE_CRYPTO_NATIVE@ +USE_CRYPTO_OPENSSL=@USE_CRYPTO_OPENSSL@ +USE_CRYPTO_GNUTLS=@USE_CRYPTO_GNUTLS@ DOCBOOKX_DTD=@DOCBOOKX_DTD@ FOP=@FOP@ XSLTPROC=@XSLTPROC@ @@ -37,10 +40,16 @@ BUILD_HTML=@BUILD_HTML@ BUILD_PDF=@BUILD_PDF@ VALIDATE_DOC=@VALIDATE_DOC@ +OSS_FUZZ=@OSS_FUZZ@ QPDF_SKIP_TEST_COMPARE_IMAGES=@QPDF_SKIP_TEST_COMPARE_IMAGES@ BUILDRULES=@BUILDRULES@ HAVE_LD_VERSION_SCRIPT=@HAVE_LD_VERSION_SCRIPT@ +IS_32BIT=@IS_32BIT@ WINDOWS_WORDSIZE=@WINDOWS_WORDSIZE@ +WINDOWS_WMAIN_COMPILE=@WINDOWS_WMAIN_COMPILE@ +WINDOWS_WMAIN_LINK=@WINDOWS_WMAIN_LINK@ +WINDOWS_WMAIN_XLINK_FLAGS=@WINDOWS_WMAIN_XLINK_FLAGS@ +WINDOWS_MAIN_XLINK_FLAGS=@WINDOWS_MAIN_XLINK_FLAGS@ SHOW_FAILED_TEST_OUTPUT=@SHOW_FAILED_TEST_OUTPUT@ # Allow environment variable to override QPDF_LARGE_FILE_TEST_PATH?=@QPDF_LARGE_FILE_TEST_PATH@ diff -Nru qpdf-8.0.2/autofiles.sums qpdf-10.0.1/autofiles.sums --- qpdf-8.0.2/autofiles.sums 1970-01-01 00:00:00.000000000 +0000 +++ qpdf-10.0.1/autofiles.sums 2020-04-09 15:48:26.000000000 +0000 @@ -0,0 +1,11 @@ +e764290be37a921ecba94755b6da22dd9e9b98644b8fdfdd0fa7f1331ce56a05 configure.ac +d3f9ee6f6f0846888d9a10fd3dad2e4b1258be84205426cf04d7cef02d61dad7 aclocal.m4 +b0ce6d1dba8effa47d25154b2bb56eddafc997254a0f3f903cf9b6abffc03616 libqpdf/qpdf/qpdf-config.h.in +5297971a0ef90bcd5563eb3f7127a032bb76d3ae2af7258bf13479caf8983a60 m4/ax_cxx_compile_stdcxx.m4 +35bc5c645dc42d47f2daeea06f8f3e767c8a1aee6a35eb2b4854fd2ce66c3413 m4/ax_random_device.m4 +6a1e4f8aa2902d7993300660c43e6ee479b4b6781ed7d5ef9c9f9f1cc46623b7 m4/libtool.m4 +e77ebba8361b36f14b4d0927173a034b98c5d05049697a9ded84d85eb99a7990 m4/ltoptions.m4 +5a6735cda60e0ba0d1b706c0ef648f5d096298da46daefd9cdecdb6a0f4584d3 m4/ltsugar.m4 +a27b754709de61575197bf5a980696c98ae49da3f92f0de8ee7f42dd543b7465 m4/ltversion.m4 +26fa3285c35dd6ab00ed1e466ba92a17e4655e01897731ec18a587a4cf5e4f8d m4/lt~obsolete.m4 +9fab676fae13feb97d5183a8ed86ae9398c76d21927c28bc59460d230f3e0884 m4/pkg.m4 diff -Nru qpdf-8.0.2/autogen.sh qpdf-10.0.1/autogen.sh --- qpdf-8.0.2/autogen.sh 2018-03-06 16:34:07.000000000 +0000 +++ qpdf-10.0.1/autogen.sh 2020-04-09 15:48:26.000000000 +0000 @@ -1,4 +1,7 @@ #!/bin/sh +set -e aclocal -I m4 autoheader autoconf +rm -f m4/*~ 2>/dev/null || true +sha256sum configure.ac aclocal.m4 libqpdf/qpdf/qpdf-config.h.in m4/* >| autofiles.sums diff -Nru qpdf-8.0.2/azure-pipelines/build-appimage qpdf-10.0.1/azure-pipelines/build-appimage --- qpdf-8.0.2/azure-pipelines/build-appimage 1970-01-01 00:00:00.000000000 +0000 +++ qpdf-10.0.1/azure-pipelines/build-appimage 2020-04-09 15:48:26.000000000 +0000 @@ -0,0 +1,22 @@ +#!/bin/bash +# +# Any extra args are passed to the docker run command before the +# invocation of qpdfbuild. This is useful for iterating locally as +# described in README-maintainer. +# +set -ex +cd appimage +docker build -t qpdfbuild . +rm -rf build +mkdir build +cd .. +git clone .git appimage/build/qpdf +docker run --privileged --rm \ + -v $PWD/appimage/build:/tmp/build ${1+"$@"} qpdfbuild +rm -rf distribution +mkdir distribution +cp -p appimage/build/qpdf/appimage/build/qpdf*AppImage* distribution +for i in distribution/*; do + mv $i $(echo $i | sed -e 's/\.AppImage/-ci.AppImage/') +done +sha256sum distribution/* diff -Nru qpdf-8.0.2/azure-pipelines/build-fuzzer qpdf-10.0.1/azure-pipelines/build-fuzzer --- qpdf-8.0.2/azure-pipelines/build-fuzzer 1970-01-01 00:00:00.000000000 +0000 +++ qpdf-10.0.1/azure-pipelines/build-fuzzer 2020-04-09 15:48:26.000000000 +0000 @@ -0,0 +1,11 @@ +#!/bin/bash +set -ex +export WORK=$PWD/work +export OUT=$PWD/out +mkdir -p $WORK $OUT +sudo apt-get update +sudo apt-get -y install \ + autoconf build-essential zlib1g-dev libjpeg-dev +./fuzz/oss-fuzz-build +ls -l out/qpdf*fuzzer +ls -l out/ diff -Nru qpdf-8.0.2/azure-pipelines/build-linux qpdf-10.0.1/azure-pipelines/build-linux --- qpdf-8.0.2/azure-pipelines/build-linux 1970-01-01 00:00:00.000000000 +0000 +++ qpdf-10.0.1/azure-pipelines/build-linux 2020-04-09 15:48:26.000000000 +0000 @@ -0,0 +1,19 @@ +#!/bin/bash +set -ex +sudo apt-get update +sudo apt-get -y install \ + autoconf build-essential zlib1g-dev libjpeg-dev libgnutls28-dev \ + libssl-dev docbook-xsl fop xsltproc libxml2-utils inkscape imagemagick +./configure --enable-werror --enable-doc-maintenance \ + --enable-crypto-native --enable-crypto-openssl --enable-crypto-gnutls \ + --enable-show-failed-test-output +make -j$(nproc) -k +for i in $(./qpdf/build/qpdf --show-crypto); do + echo "*** Running tests with crypto provider $i" + env QPDF_CRYPTO_PROVIDER=$i make -k check +done +make distfiles.zip +./make_dist --ci --no-tests +mkdir distribution +cp /tmp/qpdf*-ci.tar.gz distribution +sha256sum distribution/* diff -Nru qpdf-8.0.2/azure-pipelines/build-linux32 qpdf-10.0.1/azure-pipelines/build-linux32 --- qpdf-8.0.2/azure-pipelines/build-linux32 1970-01-01 00:00:00.000000000 +0000 +++ qpdf-10.0.1/azure-pipelines/build-linux32 2020-04-09 15:48:26.000000000 +0000 @@ -0,0 +1,24 @@ +#!/bin/bash +set -ex + +# dpkg --add-architecture not needed for Ubuntu 18.04 +sudo dpkg --add-architecture i386 + +sudo apt-get update + +# For Ubuntu 18.04: +# +# sudo apt-get -y install \ +# autoconf build-essential zlib1g-dev:i386 libjpeg-dev:i386 \ +# g++-multilib-i686-linux-gnu +# ./configure --enable-werror --enable-show-failed-test-output \ +# CC=i686-linux-gnu-gcc CXX=i686-linux-gnu-g++ + +sudo apt-get -y install \ + autoconf build-essential zlib1g-dev:i386 libjpeg-dev:i386 \ + libssl-dev:i386 g++-multilib +./configure --enable-werror --enable-show-failed-test-output \ + CFLAGS=-m32 CXXFLAGS=-m32 LDFLAGS=-m32 + +make -j$(nproc) -k +make -k check diff -Nru qpdf-8.0.2/azure-pipelines/build-mac qpdf-10.0.1/azure-pipelines/build-mac --- qpdf-8.0.2/azure-pipelines/build-mac 1970-01-01 00:00:00.000000000 +0000 +++ qpdf-10.0.1/azure-pipelines/build-mac 2020-04-09 15:48:26.000000000 +0000 @@ -0,0 +1,15 @@ +#!/bin/bash +set -ex +curl -L https://github.com/qpdf/qpdf/raw/external-libs/jpegsrc.v9c.tar.gz -o jpegsrc.v9c.tar.gz +tar xzf jpegsrc.v9c.tar.gz +cd jpeg-9c +./configure +make -k +sudo make install +cd .. +if [ -f distfiles/distfiles.zip ]; then + unzip distfiles/distfiles.zip +fi +./configure --enable-werror --enable-show-failed-test-output +make -j$(nproc) -k +make -k check diff -Nru qpdf-8.0.2/azure-pipelines/build-windows qpdf-10.0.1/azure-pipelines/build-windows --- qpdf-8.0.2/azure-pipelines/build-windows 1970-01-01 00:00:00.000000000 +0000 +++ qpdf-10.0.1/azure-pipelines/build-windows 2020-04-09 15:48:26.000000000 +0000 @@ -0,0 +1,39 @@ +#!/bin/bash +set -ex +cd $(dirname $0)/.. +wordsize=$1 +tool=$2 + +if [[ $tool == mingw ]]; then + pacman -Sy --noconfirm make base-devel tar zip unzip + if [[ $wordsize == 64 ]]; then + pacman -Sy --noconfirm mingw-w64-x86_64-toolchain + PATH="/c/tools/msys64/mingw64/bin:$PATH" + else + pacman -Sy --noconfirm mingw-w64-i686-toolchain + PATH="/c/tools/msys64/mingw32/bin:$PATH" + fi + g++ -v +elif [[ $tool == msvc ]]; then + cl +fi +if [ -f distfiles/distfiles.zip ]; then + unzip distfiles/distfiles.zip +fi +curl -L https://github.com/qpdf/qpdf/raw/external-libs/qpdf-external-libs-bin.zip -o qpdf-external-libs-bin.zip +unzip qpdf-external-libs-bin.zip +cwd=`pwd` +PATH=$cwd/libqpdf/build:$PATH + +installdir=install-$tool$wordsize +rm -rf $installdir +./config-$tool --enable-show-failed-test-output --disable-crypto-gnutls --disable-crypto-openssl +make -j$(nproc) -k +make -k check +make install + +v=`(cd $installdir; ls -d qpdf-*)` +cp -p README-windows-install.txt $installdir/$v/README.txt +mkdir distribution +(cd $installdir; zip -r ../distribution/$v-bin-$tool$wordsize-ci.zip $v) +sha256sum distribution/* diff -Nru qpdf-8.0.2/azure-pipelines/build-windows.bat qpdf-10.0.1/azure-pipelines/build-windows.bat --- qpdf-8.0.2/azure-pipelines/build-windows.bat 1970-01-01 00:00:00.000000000 +0000 +++ qpdf-10.0.1/azure-pipelines/build-windows.bat 2020-04-09 15:48:26.000000000 +0000 @@ -0,0 +1,16 @@ +@echo on +@rem Usage: build-windows {32|64} {msvc|mingw} +if %2 == msvc ( + if %1 == 64 ( + call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat" + ) else ( + call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars32.bat" + ) + choco install zip + bash ./azure-pipelines/build-windows %1 %2 +) else ( + @rem The vs2017-win2016 pool has an ancient 64-bit-only mingw. + @rem Install msys2 so we can get current gcc toolchains. + choco install msys2 + C:\tools\msys64\usr\bin\env.exe MSYSTEM=MINGW64 /bin/bash -l %CD%/azure-pipelines/build-windows %1 %2 +) diff -Nru qpdf-8.0.2/azure-pipelines/test-sanitizers qpdf-10.0.1/azure-pipelines/test-sanitizers --- qpdf-8.0.2/azure-pipelines/test-sanitizers 1970-01-01 00:00:00.000000000 +0000 +++ qpdf-10.0.1/azure-pipelines/test-sanitizers 2020-04-09 15:48:26.000000000 +0000 @@ -0,0 +1,16 @@ +#!/bin/bash +set -e +sudo apt-get update +sudo apt-get -y install \ + autoconf build-essential zlib1g-dev libjpeg-dev libgnutls28-dev +./configure \ + CFLAGS="-fsanitize=address -fsanitize=undefined -g" \ + CXXFLAGS="-fsanitize=address -fsanitize=undefined -g" \ + LDFLAGS="-fsanitize=address -fsanitize=undefined" \ + --enable-crypto-native --enable-crypto-openssl --enable-crypto-gnutls \ + --enable-werror --disable-shared --enable-show-failed-test-output +make -j$(nproc) -k +for i in $(./qpdf/build/qpdf --show-crypto); do + echo "*** Running tests with crypto provider $i" + env QPDF_CRYPTO_PROVIDER=$i make -k check +done diff -Nru qpdf-8.0.2/azure-pipelines.yml qpdf-10.0.1/azure-pipelines.yml --- qpdf-8.0.2/azure-pipelines.yml 1970-01-01 00:00:00.000000000 +0000 +++ qpdf-10.0.1/azure-pipelines.yml 2020-04-09 15:48:26.000000000 +0000 @@ -0,0 +1,135 @@ +jobs: +- job: Linux + pool: + vmImage: ubuntu-16.04 + steps: + - script: azure-pipelines/build-linux + displayName: 'Generate, build, and test' + - task: PublishBuildArtifacts@1 + inputs: + pathtoPublish: '$(System.DefaultWorkingDirectory)/distfiles.zip' + artifactName: distfiles + displayName: 'Upload extra distribution files' + condition: eq(variables['System.PullRequest.IsFork'], 'False') + - task: PublishBuildArtifacts@1 + inputs: + pathtoPublish: '$(System.DefaultWorkingDirectory)/distribution' + artifactName: distribution + displayName: 'Upload source distribution' + condition: eq(variables['System.PullRequest.IsFork'], 'False') + - task: PublishTestResults@2 + inputs: + testRunTitle: Linux + buildPlatform: Linux +- job: Windows + pool: + # If updating this, see note in TODO about MSVC wildcard expansion. + vmImage: windows-2019 + strategy: + matrix: + msvc32: + wordsize: 32 + tool: msvc + msvc64: + wordsize: 64 + tool: msvc + mingw32: + wordsize: 32 + tool: mingw + mingw64: + wordsize: 64 + tool: mingw + maxParallel: 4 + steps: + - bash: git config --global core.autocrlf input + displayName: 'Disable git autocrlf' + - checkout: self + displayName: 'Get sources' + - task: DownloadBuildArtifacts@0 + displayName: 'Download distribution files' + inputs: + artifactName: distfiles + downloadPath: $(System.DefaultWorkingDirectory) + condition: eq(variables['System.PullRequest.IsFork'], 'False') + - script: azure-pipelines/build-windows.bat $(wordsize) $(tool) + displayName: 'Build, test, generate binary distributions' + - task: PublishBuildArtifacts@1 + inputs: + pathtoPublish: '$(System.DefaultWorkingDirectory)/distribution' + artifactName: distribution + displayName: 'Upload binary distributions' + condition: eq(variables['System.PullRequest.IsFork'], 'False') + - task: PublishTestResults@2 + inputs: + testRunTitle: Windows-$(wordsize)$(tool) + buildPlatform: Windows-$(wordsize)$(tool) + dependsOn: Linux + condition: succeeded() +- job: macOS + pool: + vmImage: macOS-10.14 + steps: + - task: DownloadBuildArtifacts@0 + displayName: 'Download distribution files' + inputs: + artifactName: distfiles + downloadPath: $(System.DefaultWorkingDirectory) + condition: eq(variables['System.PullRequest.IsFork'], 'False') + - script: azure-pipelines/build-mac + displayName: 'Mac build and test' + - task: PublishTestResults@2 + inputs: + testRunTitle: MacOS + buildPlatform: MacOS + dependsOn: Linux + condition: succeeded() +- job: AppImage + pool: + vmImage: ubuntu-16.04 + steps: + - script: azure-pipelines/build-appimage + displayName: 'Build AppImage' + - task: PublishBuildArtifacts@1 + inputs: + pathtoPublish: '$(System.DefaultWorkingDirectory)/distribution' + artifactName: distribution + displayName: 'Upload AppImage' + condition: eq(variables['System.PullRequest.IsFork'], 'False') + - task: PublishTestResults@2 + inputs: + testRunTitle: AppImage + buildPlatform: AppImage + dependsOn: Linux + condition: succeeded() +- job: Linux32 + pool: + vmImage: ubuntu-16.04 + steps: + - script: azure-pipelines/build-linux32 + displayName: 'Linux 32-bit' + - task: PublishTestResults@2 + inputs: + testRunTitle: Linux32 + buildPlatform: Linux32 + dependsOn: Linux + condition: succeeded() +- job: Fuzzers + pool: + vmImage: ubuntu-16.04 + steps: + - script: azure-pipelines/build-fuzzer + displayName: 'Build Fuzzer' + dependsOn: Linux + condition: succeeded() +- job: Sanitizers + pool: + vmImage: ubuntu-16.04 + steps: + - script: azure-pipelines/test-sanitizers + displayName: 'Sanitizer Tests' + - task: PublishTestResults@2 + inputs: + testRunTitle: Sanitizers + buildPlatform: Sanitizers + dependsOn: Linux + condition: succeeded() diff -Nru qpdf-8.0.2/ChangeLog qpdf-10.0.1/ChangeLog --- qpdf-8.0.2/ChangeLog 2018-03-06 16:34:07.000000000 +0000 +++ qpdf-10.0.1/ChangeLog 2020-04-09 15:48:26.000000000 +0000 @@ -1,3 +1,1237 @@ +2020-04-09 Jay Berkenbilt + + * 10.0.1: release + +2020-04-08 Jay Berkenbilt + + * Bug fix: qpdf 10.0.0 introduced a bug in which + QPDFObjectHandle::getStreamData would return the raw data when + called on an unfilterable stream instead of throwing an exception + like it's supposed to. Fixes #425. + +2020-04-07 Jay Berkenbilt + + * Improve pdf-invert-images example to show a pattern of copying + streams into another QPDF object to enable a stream data provider + to access the original stream data. + + * Fix error that caused a compilation error with clang. Fixes + #424. + +2020-04-06 Jay Berkenbilt + + * 10.0.0: release + + * Move random number generation into the crypto providers. The old + os-based secure random number generation with fallback to insecure + random number generation (only if allowed at build time) has moved + into the native crypto provider. If using other providers + (currently gnutls or openssl), random number generation will use + those libraries. The old interfaces for supplying your own random + number generator are still in place. Fixes #418. + + * Source-level incompatibility: remove QUtil::srandom. There was + no reason to ever call this, and it didn't do anything unless + insecure random number generation was compiled in, which it is not + by default. If you were calling this, just remove the call because + it wasn't doing anything anyway. + + * Add openssl crypto provider, contributed by Dean Scarff. This + provider is implemented using OpenSSL and also works with + BoringSSL. + +2020-04-04 Jay Berkenbilt + + * Add a new provideStreamData method for StreamDataProvider that + allows a success code to be returned and that accepts the + suppress_warnings and will_retry methods. This makes it possible + to have a StreamDataProvider call pipeStreamData and propagate its + results back. This change allows better error handling and + recovery when objects are copied from other files and when + "immediate copy from" is enabled. + + * When copying foreign streams, the same type of recovery from + streams with filtering errors is performed as when dealing with + streams in the original input. This could happen, for example, if + you are using the --pages option to take pages from another file + and that file has errors in it. + + * Add a new version of QPDFObjectHandle::pipeStreamData whose + return value indicates overall success or failure rather than + whether nor not filtering was attempted. It should have always + been this way. This change was done in a backward-compatible + fashion. Previously existing pipeStreamData methods' return values + mean the same as always. + + * Add "objectinfo" section to json output. In this release, + information about whether each object is a stream or not is + provided. There's otherwise no way to tell conclusively from the + json output. Over time, other computed information about objects + may be added here. + + * Add new option --remove-unreferenced-resources that takes auto, + yes, or no as options. This tells qpdf whether to attempt to + remove unreferenced resources from pages when doing page splitting + operations. Prior to this change, the default was to attempt to + remove unreferenced resources, but this operation was very slow, + especially for large and complex files. The new default is "auto", + which tells qpdf to analyze the file for shared resources. This is + a relatively quick test. If no shared resources are found, then we + don't attempt to remove unreferenced resources, because + unreferenced resources never occur in files without shared + resources. To force qpdf to look for and remove unreferenced + resources, use --remove-unreferenced-resources=yes. The option + --preserve-unreferenced-resources is now a synonym for + --remove-unreferenced-resources=no. + + * Use std::atomic for unique ID generation internally within the + library. This eliminates the already extremely low chance of a + collision, improves thread safety, and removes a dependency on a + random number generator. Thanks to Dean Scarff for the + contribution. + +2020-04-03 Jay Berkenbilt + + * Allow qpdf to be built on systems without wchar_t. All "normal" + systems have wchar_t because it is part of the C++ standard, but + there are some stripped down environments that don't have it. See + README.md (search for wchar_t) for instructions and a discussion. + Fixes #406. + + * Add two extra optional arguments to + QPDFPageObjectHelper::placeFormXObject to control whether the + placed item is allowed to be shrunk or expanded to fit within or + maximally fill the destination rectangle. Prior to this change, + placeFormXObject might shrink it but would never expand it. + + * When calling the C API, accept any non-zero value as TRUE rather + than just 1. This appears to resolve issues on Windows when + calling some versions of the DLL directly from other languages. + +2020-04-02 Jay Berkenbilt + + * Add method QPDFObjectHandle::unsafeShallowCopy for copying only + top-level dictionary keys or array items. See comments in + QPDFObjectHandle.hh for when this should be used. + + * Remove Members class indirection for QPDFObjectHandle. Those are + copied and assigned too often, and that change caused a very + substantial performance hit. + +2020-03-31 Jay Berkenbilt + + * When detecting unreferenced images during page splitting, if any + XObjects are form XObjects, recursively descend into them and + remove any unreferenced objects from them too. Fixes #373. + + * Add QPDFObjectHandle::filterAsContents, which filters a stream's + data as if it were page contents. This can be useful to filter + form XObjects the same way we would filter page contents. + + * If QPDF_EXECUTABLE is set, use it as the path to qpdf for + purposes of completion. This variable is only read during the + execution of `qpdf --completion-zsh` and `qpdf + --completion-bash`. It is not used during the actual evaluation of + completions. + +2020-02-22 Jay Berkenbilt + + * Update pdf-set-form-values.cc to use and mention + generateAppearance, which hadn't been added when the example was + originally created. + + * Detect, warn, and correct the case of /Pages in the document + catalog incorrectly pointing to a page or intermediate node + instead of the root of the pages tree. Fixes #398. + +2020-01-26 Jay Berkenbilt + + * 9.1.1: release + + * Bug fix: in qdf mode, do not write out any XRef streams that may + have appeared in the original file. These are usually + unreferenced, but with --preserve-unreferenced, they could be + written out, which breaks fix-qdf's assumption that there is at + most one XRef stream and that it appears at the end of the file. + Fixes #386. + + * Bug fix: when externalizing inline images, a colorspace value + that was a lookup key in the page's /Resource -> /ColorSpace + dictionary was not properly handled. Fixes #392. + + * Add "encrypt" key to the json output. This contains largely the + same information as given by --show-encryption but in a + consistent, parseable format. + + * Add options --is-encrypted and --requires-password. These can be + used with files, including encrypted files with unknown passwords, + to determine whether or not a file is encrypted and whether a + password is required to open the file. The --requires-password + option can also be used to determine whether a supplied password + is correct. Information is supplied through exit codes, making + these options particularly useful for shell scripts. Fixes #390. + +2020-01-14 Jay Berkenbilt + + * Fix for Windows being unable to acquire crypt context with a new + keyset. Thanks to Cloudmersive for the fix. Fixes #387. + + * Rewrite fix-qdf in C++. This means fix-qdf is a proper + executable now, and there is no longer a runtime requirement on + perl. + + * Add QUtil::call_main_from_wmain, a helper function that can be + called in the body of wmain to convert UTF-16 arguments to UTF-8 + arguments and then call another main function. + +2020-01-13 Jay Berkenbilt + + * QUtil::read_lines_from_file: add new versions that use FILE*, + use FILE* instead if std::ifstream internally to support correct + handling of Unicode filenames in Windows, and add the option to + preserve line endings. + +2019-11-17 Jay Berkenbilt + + * 9.1.0: release + + * This is the first version of qpdf that requires C++-11. + +2019-11-09 Jay Berkenbilt + + * 9.1.rc1: release + + * Improve behavior of wildcard expansion for msvc executable when + run from the Windows cmd.exe shell. Unlike in UNIX environments, + Windows leaves it up to the executable to expand its own + wildcards. Fixes #224. + + * Allow :even or :odd to be appended to numeric ranges for + --pages, --rotate, and other options that take page ranges. + + * When reading /P from the encryption dictionary, use static_cast + instead of QIntC to convert the value to a signed integer. The + value of /P is a bit field, and PDF files have been found in the + wild where /P is represented as an unsigned integer even though + the spec states that it is a signed 32-bit value. By using + static_cast, we allow qpdf to compensate for writers that + incorrectly represent the correct bit field as an unsigned value. + Fixes #382. + +2019-11-05 Jay Berkenbilt + + * Add support for pluggable crypto providers, enabling multiple + implementations of the cryptographic functions needed by qpdf. + This feature was added by request of Red Hat, which recognized the + use of qpdf's native crypto implementations as a potential + security liability, preferring instead to get all crypto + functionality from a third-party library that receives a lot of + scrutiny. However it was also important to me to not impose any + unnecessary third party dependencies on my users or packagers, + some of which build qpdf for lots of environments, some of which + may not easily support gnutls. Starting in qpdf 9.1.0, it is be + possible to build qpdf with both the native and gnutls crypto + providers or with either in isolation. In support of this feature, + new classes QPDFCryptoProvider and QPDFCryptoImpl have been added + to the public interface. See QPDFCryptoImpl.hh for details about + adding your own crypto provider and QPDFCryptoProvider.hh for + details about choosing which one is used. Note that selection of + crypto providers is invisible to anyone who doesn't explicitly + care. Neither end users nor developers have to be concerned about + it. + + * The environment variable QPDF_CRYPTO_PROVIDER can be used to + override qpdf's default choice of crypto provider. The + --show-crypto flag to the qpdf CLI can be used to present a list + of supported crypto providers with the default provider always + listed first. + + * Add gnutls crypto provider. Thanks to Zdenek Dohnal for + contributing the code that I ultimately used in the gnutls crypto + provider and for engaging in an extended discussion about this + feature. Fixes #218. + +2019-10-22 Jay Berkenbilt + + * Incorporate changes from Masamichi Hosoda + to properly handle signature in the following ways: + - Always represent /Contents in a signature dictionary as a hex + string + - Do not compress signature dictionaries when generating object + streams + - Do not encrypt/decrypt the /Contents field of the signature + dictionary when creating or reading encrypted files + + * Incorporate changes from Masamichi Hosoda + to add additional methods for making it possible to gain deeper + insight into cross reference tables and object renumbering. These + new API calls make it possible for applications to go into PDF + files created by qpdf and make changes to them that go beyond + working with the PDF at the object level. The specific use case + for these changes was to write an external tool to perform digital + signature, but there could be other uses as well. New methods + include the following, all of which are described in their + respective headers: + - QPDF::getXRefTable() + - QPDFObjectHandle::getParsedOffset() + - QPDFWriter::getRenumberedObjGen(QPDFObjGen) + - QPDFWriter::getWrittenXRefTable() + +2019-10-12 Jay Berkenbilt + + * 9.0.2: release + + * Change the name of the temporary file used by --replace-input to + work with arbitrary absolute or relative paths without requiring + path splitting logic. Fixes #365. + +2019-09-20 Jay Berkenbilt + + * 9.0.1: release + +2019-09-19 Jay Berkenbilt + + * When converting an array to a Rectangle, ensure that llx <= urx + and lly <= ury. This prevents flatten-annotations from flipping + fields whose coordinates are messed up in the input. Fixes #363. + + * Warn when duplicated dictionary keys are found during parsing. + The behavior remains as before: later keys override earlier ones. + However, this generates a warning now rather than being silently + ignored. Fixes #345. + +2019-09-17 Jay Berkenbilt + + * Fix a few integer warnings for big-endian systems. + + * QIntC tests: don't assume char is signed. Fixes #361. + +2019-08-31 Jay Berkenbilt + + * 9.0.0: release + + * Add QPDF::anyWarnings() method to find out whether there have + been any warnings without resetting the list. + + * Add QPDF::closeInputSource() method to release the input source + so the input file can be deleted or renamed. + + * Add methods rename_file and remove_file to QUtil. + +2019-08-24 Jay Berkenbilt + + * Add QPDF::userPasswordMatched() and QPDF::ownerPasswordMatched() + methods so it can be determined separately whether the supplied + password matched the user password, the owner password, or both. + Fixes #159. + +2019-08-23 Jay Berkenbilt + + * Add --recompress-streams option to qpdf and + QPDFWriter::setRecompressFlate to cause QPDFWriter to recompress + streams that are already compressed with /FlateDecode. + + * Add option Pl_Flate::setCompressionLevel to globally set the + zlib compression level used by all Pl_Flate pipelines. + + * Add --compression-level flag to qpdf to set the zlib compression + level. When combined with --recompress-flate, this will cause most + of qpdf's streams to use the maximum compression level. This + results in only a very small amount of savings in size that comes + at a fairly significant performance cost, but it could be useful + for archival files or other cases where every byte counts and + creation time doesn't matter so much. Note that using + --object-streams=generate in combination with these options gives + you the biggest advantage. Fixes #113. + +2019-08-22 Jay Berkenbilt + + * In QPDFObjectHandle::ParserCallbacks, in addition to + handleObject(QPDFObjectHandle), allow developers to override + handleObject(QPDFObjectHandle, size_t offset, size_t length). If + this method appears instead, it is called with the offset of the + object in the content stream (which may be concatenated from an + array of streams) and the length of the object. Intervening + whitespace and comments are not included in offset and length. + + * Add method + QPDFObjectHandle::ParserCallbacks::contentSize(size_t). If + defined, it is called by the content stream parser before the + first call to handleObject, and the argument is the total size in + bytes of the content streams. + + * Add QPDFObjectHandle::isDirectNull() -- a const method that + allows determining whether an object is a literal null without + attempting to resolve it. + + * Stop replacing indirect references to null with literal null in + arrays when writing output with QPDFWriter. + +2019-08-19 Jay Berkenbilt + + * Accept (and warn for) extraneous whitespace preceding the xref + table. Fixes #341. + + * Accept (and warn for) extraneous whitespace between the stream + keyword and newline. Fixes #329. + + * Properly handle name tokens containing # not preceding two + hexadecimal digits. Such names are invalid in PDF >= 1.2 but valid + in PDF 1.0 and 1.1. Prior to this fix, qpdf's behavior was to + treat such tokens as an error for PDF >= 1.2, but for older PDF + tokens, the name was silently accepted, and when the name token + was written out, the # was changed to #23, which is the correct + way to represent a # character. This behavior was problematic for + several reasons: one is that, ordinarily, content streams are not + parsed, so this would cause things like image references whose + names contained # to break. Also, even if the input file was 1.0 + or 1.1, there's no guarantee that the output file wouldn't be + written at a new version, resulting in invalid name tokens. The + new behavior is to issue a warning upon encountering such a token + but to accept it, regardless of the PDF version. Such tokens are + written out properly as well. Additionally, the warning message + indicates that the tokens are invalid for PDF >= 1.2. Fixes #332. + + * Non-compatible API change: remove + QPDFTokenizer::allowPoundAnywhereInName(). There were a lot of + problems with this. When it was used, any name tokens read would + always be modified on output, which is never the correct behavior. + This method used to signal QPDFTokenizer to not treat # specially + in name tokens, which resulted in the incorrect behavior whose fix + is described in the preceding item. + +2019-08-18 Jay Berkenbilt + + * When traversing the pages tree, if an invalid /Type key is + encountered, fix it. This is not done for all operations, but it + will be done for any case in which getAllPages is called. This + includes all page-based CLI operations. (Hopefully) Fixes #349. + +2019-08-17 Jay Berkenbilt + + * Change internal implementation of QPDF arrays to use sparse + arrays, which results in using much less memory for arrays with + large numbers of nulls. Various files have been encountered in the + wild that contains thousands of arrays with millions of nulls. + Fixes #305, #311. + +2019-07-03 Jay Berkenbilt + + * Non-compatible API change: change + QPDFOutlineDocumentHelper::getTopLevelOutlines and + QPDFOutlineObjectHelper::getKids to return a std::vector instead + of a std::list of QPDFOutlineObjectHelper objects. This is to work + around bugs with some compilers' STL implementations that are + choking with list here. There's no deep reason for these to be + lists instead of vectors. Fixes #297. + +2019-06-22 Jay Berkenbilt + + * Handle encrypted files with missing or invalid /Length entries + in the encryption dictionary. + + * QPDFWriter: allow calling set*EncryptionParameters before + calling setFilename. Fixes #336. + + * It now works to run --completion-bash and --completion-zsh when + qpdf is started from an AppImage. + + * Provided a more useful error message when Windows can't get + security context. Thanks to user zdenop for supplying some code. + Fixes #286. + + * Favor PointerHolder over manual memory allocation in shippable + code where possible. Fixes #235. + + * If pkg-config is available, use it to local libjpeg and zlib. If + not, fall back to old behavior. Fixes #324. + + * The "make install" target explicitly sets a mode rather than + relying the user's umask. Fixes #326. + + * When a file has linearization warnings but no errors, qpdf + --check and --check-linearization now exit with code 3 instead + of 2. Fixes #50. + + * Add new function QUtil::read_file_into_memory. + +2019-06-21 Jay Berkenbilt + + * When supported, qpdf builds with -fvisibility=hidden, which + removes non-exported symbols from the shared library in a manner + similar to how Windows DLLs work. This is better for performance + and also better for safety and protection of private interfaces. + See https://gcc.gnu.org/wiki/Visibility. *NOTE*: If you are + getting linker errors trying to catch exceptions or derive things + from a base class in the qpdf library, it's possible that a + QPDF_DLL_CLASS declaration is missing somewhere. Please report + this as a bug at https://github.com/qpdf/qpdf/issues. + + * Source-level incompatibility: remove the version + QPDF::copyForeignObject with an unused boolean parameter. If you + were, for some reason, calling this, just take the parameter away. + + * Source-level incompatibility: remove the version + QPDFTokenizer::expectInlineImage with no arguments. It didn't + produce correct inline images. This is a very low-level routine. + There is little reason to call it outside of qpdf's lexical + engine. + + * Source-level incompatibility: rename QUtil::strcasecmp to + QUtil::str_compare_nocase. This is a non-compatible change, but + QUtil::strcasecmp is hardly the most important part of qpdf's API. + The reason for this change is that strcasecmp is a macro on some + systems, and that was causing problems when QUtil.hh was included + in certain circumstances. Fixes #242. + +2019-06-20 Jay Berkenbilt + + * Enable compilation with additional warnings for integer + conversion and sign (-Wsign-conversion, -Wconversion for gcc and + similar; -W3 for msvc) if supported. These warnings are on by + default can be turned off by passing --disable-int-warnings + + * Fix all integer sign and conversion warnings. This makes all + integer type conversions that have potential data loss explicit + with calls that do range checks and raise an exception. + + * Change out_bufsize argument to Pl_Flate's constructor for int to + unsigned int for compatibility with underlying zlib + implementation. + + * Change QPDFObjectHandle::pipeStreamData's encode_flags argument + from unsigned long to int since int is the underlying type of the + enumerated type values that are passed to it. This change should + be invisible to virtually all code unless you are compiling with + strict warning flags and explicitly casting to unsigned long. + + * Add methods to QPDFObjectHandle to return the value of Integer + objects as int and unsigned int with range checking and fallback + behavior to avoid silent underflow/overflow conditions. + + * Add functions to QUtil to convert unsigned integers to strings, + avoiding implicit conversion between unsigned and signed integer + types. + + * Add QIntC.hh, containing integer type converters that do range + checking. + +2019-06-18 Jay Berkenbilt + + * Remove previously submitted qpdf_read_memory_fuzzer as it is a + small subset of qpdf_fuzzer. + +2019-06-15 Jay Berkenbilt + + * Update CI (Azure Pipelines) to run tests with some sanitizers. + + * Do "ideal integration" with oss-fuzz. This includes adding a + better fuzzer with a seed corpus and adding automated tests of the + fuzzer with the test data. + + * When parsing files, while reading an object, if there are too + many consecutive errors without enough intervening successes, give + up on the specific object. This reduces cases in which very badly + damaged files send qpdf into a tail spin reading one character at + a time and reporting warnings. + +2019-06-13 Jay Berkenbilt + + * Perform initial integration of Google's oss-fuzz project by + copying the fuzzer someone from Google already did into the qpdf + repository and adding build support. This shift in control is in + preparation for an ideal integration with oss-fuzz. + +2019-06-09 Jay Berkenbilt + + * When /DecodeParms is an empty list, ignore it on read and delete + it on write. Fixes #331. + +2019-05-18 Jay Berkenbilt + + * 8.4.2: release + +2019-05-16 Jay Berkenbilt + + * Fix memory error in Windows-only code from typo. Fixes #330. + +2019-04-27 Jay Berkenbilt + + * 8.4.1: release + +2019-04-20 Jay Berkenbilt + + * When qpdf --version is run, it will detect if the qpdf CLI was + built with a different version of qpdf than the library. This + usually indicates that multiple versions of qpdf are installed and + that the library path is not set up properly. This situation + sometimes causes confusing behavior for users who are not actually + running the version of qpdf they think they are running. + + * Add parameter --remove-page-labels to remove page labels from + output. In qpdf 8.3.0, the behavior changed so that page labels + were preserved when merging and splitting files. Some users were + relying on the fact that if you ran qpdf --empty --pages ... all + page labels were dropped. This option makes it possible to get + that behavior if it is explicitly desired. Fixes #317. + + * Add parameter --keep-files-open-threshold to override the + maximum number of files that qpdf will allow to be kept open at + once. Fixes #288. + + * Handle Unicode characters in filenames properly on Windows. The + changes to support Unicode on the CLI in Windows broke Unicode + filenames on that platform. Fixes #298. + + * Slightly tighten logic that determines whether an object is a + page. The previous logic was sometimes failing to preserve + annotations because they were passing the overly loose test for + whether something was a page. This fix has a slight risk of + causing some extraneous objects to be copied during page splitting + and merging for erroneous PDF files whose page objects contain + invalid types or are missing the /Type key entirely, both of which + would be invalid according to the PDF specification. + + * Revert change that included preservation of outlines (bookmarks) + in --split-pages. The way it was implemented caused a very + significant performance penalty when splitting pages with + outlines. We need a better solution that only copies the relevant + items, not the whole tree. + +2019-03-11 Jay Berkenbilt + + * JSON serialization: add missing leading 0 to decimal values + between -1 and 1. Fixes #308. + +2019-02-01 Jay Berkenbilt + + * 8.4.0: release + +2019-01-31 Jay Berkenbilt + + * Bug fix: do better pre-checks on images before optimizing; + refuse to optimize images that can't be converted to JPEG because + of colorspace or depth. + + * Add new options --externalize-inline-images, which converts + inline images larger than a specified size to regular images, and + --ii-min-bytes, which tweaks that size. + + * When optimizing images, inline images are now included in the + optimization, first being converted to regular images. Use + --keep-inline-images to exclude them from optimization. Fixes #278. + + * Add method QPDFPageObjectHelper::externalizeInlineImages, which + converts inline images whose size is at least a specified amount + to regular images. + + * Remove traces of acroread, which hasn't been available in Linux + for a long time. + +2019-01-30 Jay Berkenbilt + + * Do not include space after ID operator in inline image data. The + token now correctly contains the image data, the EI operator, + and the delimiter that precedes the EI operator. + + * Improve locating of an inline image's EI operator to correctly + handle the case of EI appearing inside the image data. + + * Very low-level QPDFTokenizer API now includes an + expectInlineImage method that takes an input stream, enabling it + to locate an inline image's EI operator better. When this method + is called, the inline image token returned will not contain the EI + operator and will contain correct image data. This is called + automatically everywhere within the qpdf library. Most user code + will never have to use the low-level tokenizer API. If you use + Pl_QPDFTokenizer, this will be done automatically for you. If you + use the low-level API and call expectInlineImage, you should call + the new version. + +2019-01-29 Jay Berkenbilt + + * Bug fix: when returning an inline image token, the tokenizer no + longer includes the delimiter that follows EI. The + QPDFObjectHandle created from the token was correct. + + * Handle files with direct page objects, which is not allowed by + the PDF spec but has been seen in the wild. Fixes #164. + +2019-01-28 Jay Berkenbilt + + * Bug fix: when using --stream-data=compress, object streams and + xref streams were not compressed. They were compressed if no + --stream-data option was specified. Fixes #271. + + * When linearizing or getting the list of all pages in a file, + replace duplicated page objects with a shallow copy of the page + object. Linearization and all page manipulation APIs require page + objects to be unique. Pages that were originally duplicated will + still share contents and any other indirect resources. Fixes #268. + +2019-01-26 Jay Berkenbilt + + * Add --overlay and --underlay options. Fixes #207. + + * Create examples/pdf-overlay-page.cc to demonstrate use of + page/form XObject interaction + + * Add new methods QPDFPageObjectHelper::getFormXObjectForPage, + which creates a form XObject equivalent to a page, and + QPDFObjectHandle::placeFormXObject, which generates content stream + code to placing a form XObject on a page. + +2019-01-25 Jay Berkenbilt + + * Add new method QPDFObjectHandle::getUniqueResourceName() to + return an unused key available to be used in a resource + dictionary. + + * Add new method QPDFPageObjectHelper::getAttribute() that + properly handles inherited attributes and allows for creation of a + copy of shared attributes. This is very useful if you are getting + an attribute of a page dictionary with the intent to modify it + privately for that page. + + * Fix QPDFPageObjectHelper::getPageImages (and the legacy + QPDFObjectHandle::getPageImages()) to properly handle images in + inherited resources dictionaries. + +2019-01-20 Jay Berkenbilt + + * Tweak the content code generated for variable text fields to + better handle font sizes and multi-line text. + + * When generating appearance streams for variable text + annotations, properly handle the cases of there being no + appearance dictionary, no appearance stream, or an appearance + stream with no BMC..EMC marker. + + * When flattening annotations, remove annotations from the file + that don't have appearance streams. These were previously being + preserved, but since they are invisible, there is no reason to + preserve them when flattening annotations. + +2019-01-19 Jay Berkenbilt + + * NOTE: qpdf CLI: some non-compatible changes were made to how + qpdf interprets password arguments that contain Unicode characters + that fall outside of ASCII. On Windows, the non-compatibility was + unavoidable, as explained in the release notes. On all platforms, + it is possible to get the old behavior if desired, though the old + behavior would almost always result in files that other + applications were unable to open. As it stands, qpdf should now be + able to open passwords encrypted with a wide range of passwords + that some other viewers might not handle, though even now, qpdf's + Unicode password handling is not 100% complete. + + * Add --password-mode option, which allows fine-grained control of + how password arguments are treated. This is discussed fully in the + manual. Fixes #215. + + * Add option --suppress-password-recovery to disable the behavior + of searching for a correct password by re-encoding the provided + password. This option can be useful if you want to ensure you know + exactly what password is being used. + +2019-01-17 Jay Berkenbilt + + * When attempting to open an encrypted file with a password, if + the password doesn't work, try alternative passwords created by + re-interpreting the supplied password with different string + encodings. This makes qpdf able to recover passwords with + non-ASCII characters when either the decryption or encryption + operation was performed with an incorrectly encoded password. + + * Fix data loss bug: qpdf was discarding referenced resources in + the case in which a page's resource dictionary contained an + indirect reference for either /Font or /XObject that contained + fonts or XObjects not referenced on all pages that shared the + resource. This was a "typo" in the code. The comment explained the + correct behavior, and the code was clearly intended to handle this + issue, but the implementation had an error in it. This is fixed by + a single-line change, which can be found in git commit + 4bc434000c42a7191e705c8a38216ca6743ad9ff. That commit can be used + as a patch that applies cleanly against qpdf 8.1.0 and forward. + The bug was introduced in version 8.1.0. For the record, this is + the first bug in qpdf's history that could result in silent loss + of data when processing a correct input file. Fixes #276. + +2019-01-15 Jay Berkenbilt + + * Add QUtil::possible_repaired_encodings which, given a string, + generates other strings that represent re-interpretation of the + bytes in a different coding system. This is used to help recover + passwords if the password string was improperly encoded on a + different system due to user error or a software bug. + +2019-01-14 Jay Berkenbilt + + * Add new CLI flags to 128-bit and 256-bit encryption: --assemble, + --annotate, --form, and --modify-other to control encryption + permissions with more granularity than was allowed with the + --modify flag. Fixes #214. + + * Add new versions of + QPDFWriter::setR{3,4,5,6}EncryptionParameters that allow + individual setting of the various permission bits. The old + interfaces are retained for backward compatibility. In the "C" + API, add qpdf_set_r{3,4,5,6}_encryption_parameters2. The new + interfaces use separate booleans for various permissions instead + of the qpdf_r3_modify_e enumerated type, which set permission bits + in predefined groups. + + * Add versions of utf8 to single-byte character transcoders that + return a success code. + +2019-01-13 Jay Berkenbilt + + * Add several more string transcoding and analysis methods to + QUtil for bidirectional conversion between PDF Doc, Win Ansi, Mac + Roman, UTF-6, and UTF-16 along with detection of valid UTF-8 and + UTF-16. + +2019-01-12 Jay Berkenbilt + + * In the --pages option, allow the same page to be specified more + than once. You can now do "--pages A.pdf 1,1 --" or + "--pages A.pdf 1 A.pdf 1" instead of having to use two different + paths to specify A.pdf. Fixes #272. + + * Add QPDFPageObjectHelper::shallowCopyPage(). This method creates + a new page object that is a "shallow copy" of the given page as + described in the comments in QPDFPageObjectHelper. The resulting + object has not been added anywhere but is ready to be passed to + QPDFPageDocumentHelper::addPage of its own QPDF or another QPDF + object. + + * Add QPDF::getUniqueId() method to return an identifier that is + intended to be unique within the scope of all QPDF objects created + by the calling application in a single run. + + * In --pages, allow "." as a replacement for the current input + file, making it possible to say "qpdf A.pdf --pages . 1-3 --" + instead of having to repeat the input filename. + +2019-01-10 Jay Berkenbilt + + * Add new configure option --enable-avoid-windows-handle, which + causes the symbol AVOID_WINDOWS_HANDLE to be defined. If set, we + avoid using Windows I/O HANDLE, which is disallowed in some + versions of the Windows SDK, such as for Windows phones. + QUtil::same_file will always return false in this case. Only + applies to Windows builds. + + * Add new method QPDF::setImmediateCopyFrom. When called on a + source QPDF object, streams can be copied FROM that object to + other ones without having to keep the source QPDF or its input + source around. The cost is copying the streams into RAM. See + comments in QPDF.hh for setImmediateCopyFrom for a detailed + explanation. + +2019-01-07 Jay Berkenbilt + + * 8.3.0: release + + * Add sample completion files in completions. These can be used by + packagers to install on the system wherever bash and zsh keep + their vendor-supplied completions. + + * Add configure flag --enable-check-autofiles, which is on by + default. Packagers whose packaging systems automatically refresh + autoconf or libtool files should pass --disable-check-autofiles to + ./configure to suppress warnings about automatically generated + files being outdated. + +2019-01-06 Jay Berkenbilt + + * Remove the restriction in most cases that the source QPDF used + in a copyForeignObject call has to stick around until the + destination QPDF is written. The exceptional case is when the + source stream gets is data using a + QPDFObjectHandle::StreamDataProvider. For a more in-depth + discussion, see comments around copyForeignObject in QPDF.hh. + Fixes #219. + +2019-01-05 Jay Berkenbilt + + * When generating appearances, if the font uses one of the + standard, built-in encodings, restrict the character set to that + rather than just to ASCII. This will allow most appearances to + contain characters from the ISO-Latin-1 range plus a few + additional characters. + + * Add methods QUtil::utf8_to_win_ansi and + QUtil::utf8_to_mac_roman. + + * Add method QUtil::utf8_to_utf16. + +2019-01-04 Jay Berkenbilt + + * Add new option --optimize-images, which recompresses every image + using DCT (JPEG) compression as long as the image is not already + compressed with lossy compression and recompressing the image + reduces its size. The additional options --oi-min-width, + --oi-min-height, and --oi-min-area prevent recompression of images + whose width, height, or pixel area (width * height) are below a + specified threshold. + + * Add new option --collate. When specified, the semantics of + --pages change from concatenation to collation. See the manual for + a more detailed discussion. Fixes #259. + + * Add new method QPDFWriter::getFinalVersion, which returns the + PDF version that will ultimately be written to the final file. See + comments in QPDFWriter.hh for some restrictions on its use. Fixes + #266. + + * When unexpected errors are found while checking linearization + data, print an error message instead of calling assert, which + cause the program to crash. Fixes #209, #231. + + * Detect and recover from dangling references. If a PDF file + contained an indirect reference to a non-existent object (which is + valid), when adding a new object to the file, it was possible for + the new object to take the object ID of the dangling reference, + thereby causing the dangling reference to point to the new object. + This case is now prevented. Fixes #240. + +2019-01-03 Jay Berkenbilt + + * Add --generate-appearances flag to the qpdf command-line tool to + trigger generation of appearance streams. + + * Fix behavior of form field value setting to handle the following + cases: + - Strings are always written as UTF-16 + - Check boxes and radio buttons are handled properly with + synchronization of values and appearance states + + * Define constants in qpdf/Constants.h for interpretation of + annotation and form field flags + + * Add QPDFAnnotationObjectHelper::getFlags + + * Add many new methods to QPDFFormFieldObjectHelper for querying + flags and field types + + * Add new methods for appearance stream generation. See comments + in QPDFFormFieldObjectHelper.hh for generateAppearance() for a + description of limitations. + - QPDFAcroFormDocumentHelper::generateAppearancesIfNeeded + - QPDFFormFieldObjectHelper::generateAppearance + + * Bug fix: when writing form field values, always write string + values encoded as UTF-16. + + * Add method QUtil::utf8_to_ascii, which returns an ASCII string + for a UTF-8 string, replacing out-of-range characters with a + specified substitute. + +2019-01-02 Jay Berkenbilt + + * Add method QPDFObjectHandle::getResourceNames that returns a set + of strings representing all second-level keys in a dictionary + (i.e. all keys of all direct dictionary members). + +2018-12-31 Jay Berkenbilt + + * Add --flatten-annotations flag to the qpdf command-line tool for + annotation flattening. + + * Add methods for flattening form fields and annotations: + - QPDFPageDocumentHelper::flattenAnnotations - integrate + annotation appearance streams into page contents with special + handling for form fields: if appearance streams are up to date + (/NeedAppearances is false in /AcroForm), the /AcroForm key of + the document catalog is removed. Otherwise, a warning is + issued, and form fields are ignored. Non-form-field + annotations are always flattened if an appearance stream can + be found. + - QPDFAnnotationObjectHelper::getPageContentForAppearance - + generate the content stream fragment to render an appearance + stream in a page's content stream as a form xobject. Called by + flattenAnnotations. + + * Add method QPDFObjectHandle::mergeResources(), which merges + resource dictionaries. See detailed description in + QPDFObjectHandle.hh. + + * Add QPDFObjectHandle::Matrix, similar to + QPDFObjectHandle::Rectangle, as a convenience class for + six-element arrays that are used as matrices. + +2018-12-23 Jay Berkenbilt + + * When specifying @arg on the command line, if the file "arg" does + not exist, just treat this is a normal argument. This makes it + easier to deal with files whose names start with the @ character. + Fixes #265. + + * Tweak completion so it works with zsh as well using + bashcompinit. + +2018-12-22 Jay Berkenbilt + + * Add new options --json, --json-key, and --json-object to + generate a json representation of the PDF file. This is described + in more depth in the manual. You can also run qpdf --json-help to + get a description of the json format. + +2018-12-21 Jay Berkenbilt + + * Allow --show-object=trailer for showing the document trailer. + + * You can now use eval $(qpdf --completion-bash) to enable bash + completion for qpdf. It's not perfect, but it works pretty well. + +2018-12-19 Jay Berkenbilt + + * When splitting pages using --split-pages, the outlines + dictionary and some supporting metadata are copied into the split + files. The result is that all bookmarks from the original file + appear, and those that point to pages that are preserved work + while those that point to pages that are not preserved don't do + anything. This is an interim step toward proper support for + bookmark preservation in split files. + + * Add QPDFOutlineDocumentHelper and QPDFOutlineObjectHelper for + handling outlines (bookmarks) including bidirectionally mapping + between bookmarks and pages. Initially there is no support for + modifying the outlines hierarchy. + +2018-12-18 Jay Berkenbilt + + * New method QPDFObjectHandle::getJSON() returns a JSON object + with a partial representation of the object. See + QPDFObjectHandle.hh for a detailed description. + + * Add a simple JSON serializer. This is not a complete or + general-purpose JSON library. It allows assembly and serialization + of JSON structures with some restrictions, which are described in + the header file. + + * Add QPDFNameTreeObjectHelper class. This class provides useful + methods for dealing with name trees, which are discussed in + section 7.9.6 of the PDF spec (ISO-32000). + + * Preserve page labels when merging and splitting files. Prior + versions of qpdf simply preserved the page label information from + the first file, which usually wouldn't make any sense in the + merged file. Now any page that had a page number in any original + file will have the same page number after merging or splitting. + + * Add QPDFPageLabelDocumentHelper class. This is a document helper + class that provides useful methods for dealing with page labels. + It abstracts the fact that they are stored as number trees and + deals with interpolating intermediate values that are not in the + tree. It also has helper functions used by the qpdf command line + tool to preserve page labels when merging and splitting files. + + * Add QPDFNumberTreeObjectHelper class. This class provides useful + methods for dealing with number trees, which are discussed in + section 7.9.7 of the PDF spec (ISO-32000). Page label dictionaries + are represented as number trees. + + * New method QPDFObjectHandle::wrapInArray returns the object + itself if it is an array. Otherwise, it returns an array + containing the object. This is useful for dealing with PDF data + that is sometimes expressed as a single element and sometimes + expressed as an array, which is a somewhat common PDF idiom. + +2018-10-11 Jay Berkenbilt + + * Files generated by autogen.sh are now committed so that it is + possible to build on platforms without autoconf directly from a + clean checkout of the repository. The configure script detects if + the files are out of date when it also determines that the tools + are present to regenerate them. + + * Add build in Azure Pipelines, now that it is free for open + source projects. + +2018-08-18 Jay Berkenbilt + + * 8.2.1: release + + * Add new option --keep-files-open=[yn] to control whether qpdf + keeps files open when merging. Prior to version 8.1.0, qpdf always + kept all files open, but this meant that the number of files that + could be merged was limited by the operating system's open file + limit. Version 8.1.0 opened files as they were referenced, but + this caused a major performance impact. Version 8.2.0 optimized + the performance but did so in a way that, for local file systems, + there was a small but unavoidable performance hit, but for + networked file systems, the performance impact could be very high. + Starting with version 8.2.1, the default behavior is that files + are kept open if no more than 200 files are specified, but that + the behavior can be explicitly overridden with the + --keep-files-open flag. If you are merging more than 200 files but + less than the operating system's max open files limit, you may + want to use --keep-files-open=y. If you are using a local file + system where the overhead is low and you might sometimes merge + more than the OS limit's number of files, you may want to specify + --keep-files-open=n. Fixes #237. + +2018-08-16 Jay Berkenbilt + + * 8.2.0: release + +2018-08-14 Jay Berkenbilt + + * For the mingw builds, change the name of the DLL import library + from libqpdf.a to libqpdf.dll.a to avoid confusing it with a + static library. This potentially clears the way for supporting a + static library in the future, though presently, the qpdf Windows + build only builds the DLL and executables. Fixes #225. + +2018-08-13 Jay Berkenbilt + + * Add new class QPDFSystemError, derived from std::runtime_error, + which is now thrown by QUtil::throw_system_error. This enables the + triggering errno value to be retrieved. Fixes #221. + +2018-08-12 Jay Berkenbilt + + * qpdf command line: add --no-warn option to suppress issuing + warning messages. If there are any conditions that would have + caused warnings to be issued, the exit status is still 3. + + * Rewrite the internals of Pl_Buffer to be much more efficient in + use of memory at a very slight performance cost. The old + implementation could cause memory usage to go out of control for + files with large images compressed using the TIFF predictor. + Fixes #228. + +2018-08-05 Jay Berkenbilt + + * Bug fix: end of line characters were not properly handled inside + strings in some cases. Fixes #226. + + * Bug fix: infinite loop on progress reporting for very small + files. Fixes #230. + +2018-08-04 Jay Berkenbilt + + * Performance fix: optimize page merging operation to avoid + unnecessary open/close calls on files being merged. Fixes #217. + + * Add ClosedFileInputSource::stayOpen method, enabling a + ClosedFileInputSource to stay open during manually indicated + periods of high activity, thus reducing the overhead of frequent + open/close operations. + +2018-06-23 Jay Berkenbilt + + * 8.1.0: release + +2018-06-22 Jay Berkenbilt + + * Bug fix: properly decrypt files with 40-bit keys that use + revision 3 of the security handler. Prior to this, qpdf was + reporting "invalid password" in this case. Fixes #212. + + * With --verbose, print information about each input file when + merging files. + + * Add progress reporting to QPDFWriter. Programmatically, you can + register a progress reporter with registerProgressReporter(). From + the command line, passing --progress will give progress indicators + in increments of no less than 1% as output files are written. + Fixes #200. + + * Add new method QPDF::getObjectCount(). This gives an approximate + (upper bound) account of objects in the QPDF object. + + * Don't leave files open when merging. This makes it possible + merge more files at once than the operating system's open file + limit. Fixes #154. + + * Add ClosedFileInputSource class, and input source that keeps its + input file closed when not reading it. At the expense of some + performance, this allows you to operate on many files without + opening too many files at the operating system level. + + * Add new option --preserve-unreferenced-resources, which + suppresses removal of unreferenced objects from page resource + dictionaries during page splitting operations. + +2018-06-21 Jay Berkenbilt + + * Add method QPDFPageObjectHelper::removeUnreferencedResources and + also QPDFPageDocumentHelper::removeUnreferencedResources that + calls the former on every page. This method removes any XObject or + Font references from the page's resource dictionary if they are + not referenced anywhere in any of the content streams. This + significantly reduces the size of split files whose pages + internally share resource dictionaries. Fixes #203. + + * The --rotate option to qpdf no longer requires an explicit page + range. You can now rotate all pages of a document with + qpdf --rotate=angle in.pdf out.pdf. Fixes #211. + + * Create examples/pdf-set-form-values.cc to illustrate use of + interactive form helpers. + + * Added methods QPDFAcroFormDocumentHelper::setNeedAppearances and + added methods to QPDFFormFieldObjectHelper to set a field's value, + optionally updating the document to indicate that appearance + streams need to be regenerated. + + * Added QPDFObject::newUnicodeString and QPDFObject::unparseBinary + to allow for more convenient creation of strings that are + explicitly encoded in UTF-16 BE. This is useful for creating + Unicode strings that appear outside of content streams, such as in + page labels, outlines, form field values, etc. + +2018-06-20 Jay Berkenbilt + + * Added new classes QPDFAcroFormDocumentHelper, + QPDFFormFieldObjectHelper, and QPDFAnnotationObjectHelper to + assist with working with interactive forms in PDF files. At + present, API methods for reading forms, form fields, and widget + annotations have been added. It is likely that some additional + methods for modifying forms will be added in the future. Note that + qpdf remains a library whose function is primarily focused around + document structure and metadata rather than content. As such, it + is not expected that qpdf will have higher level APIs for + generating form contents, but qpdf will hopefully gain the + capability to deal with the bookkeeping aspects of wiring up all + the objects, which could make it a useful library for other + software that works with PDF interactive forms. PDF forms are + complex, and the terminology around them is confusing. Please see + comments at the top of QPDFAcroFormDocumentHelper.hh for + additional discussion. + + * Added new classes QPDFPageDocumentHelper and QPDFPageObjectHelper + for page-level API functions. These classes introduce a new API + pattern of document helpers and object helpers in qpdf. The helper + classes provide a higher level API for working with certain types + of structural features of PDF while still staying true to qpdf's + philosophy of not isolating the user from the underlying + structure. Please see the chapter in the documentation entitled + "Design and Library Notes" for additional discussion. The examples + have also been updated to use QPDFPageDocumentHelper and + QPDFPageObjectHelper when performing page-level operations. + +2018-06-19 Jay Berkenbilt + + * New QPDFObject::Rectangle class will convert to and from arrays + of four numerical values. Rectangles are used in various places + within the PDF file format and are called out as a specific data + type in the PDF specification. + +2018-05-12 Jay Berkenbilt + + * In newline before endstream mode, an extra newline was not + inserted prior to the endstream that ends object streams. + Fixes #205. + +2018-04-15 Jay Berkenbilt + + * Arbitrarily limit the depth of data structures represented by + direct object. This is CVE-2018-9918. Fixes #202. + 2018-03-06 Jay Berkenbilt * 8.0.2: release @@ -22,7 +1256,7 @@ * Ignore zlib data check errors while uncompressing streams. This is consistent with behaviors of other readers and enables handling - of some incorrectly written zlib strems. Fixes #191. + of some incorrectly written zlib streams. Fixes #191. 2018-02-25 Jay Berkenbilt @@ -40,7 +1274,7 @@ * Major enhancements to handling of type errors within the qpdf library. This fix is intended to eliminate those annoying cases where qpdf would exit with a message like "operation for - dictionary object attemped on object of wrong type" without + dictionary object attempted on object of wrong type" without providing any context. Now qpdf keeps enough context to be able to issue a proper warning and to handle such conditions in a sensible way. This should greatly increase the number of bad files that @@ -156,7 +1390,7 @@ counting in length for better readability. Ordinarily this makes no difference, but in the rare case of a page's contents being split in the middle of a token, the old behavior could cause the - extra newline to be interprted as part of the token. This bug + extra newline to be interpreted as part of the token. This bug could only be triggered in qdf mode, which is a mode intended for manual inspection of PDF files' contents, so it is very unlikely to have caused any actual problems for people using qpdf for @@ -235,7 +1469,7 @@ QPDFObjectHandle::pipeStreamData, you don't need to worry about this at all. - * Provide heavily annoated examples/pdf-filter-tokens.cc example + * Provide heavily annotated examples/pdf-filter-tokens.cc example that illustrates use of some simple token filters. * When normalizing content streams, as in qdf mode, issue warning @@ -245,7 +1479,7 @@ either there's a bug in qpdf's lexer, that the file is damaged, or that the page's contents are split in a weird way. In any of those cases, qpdf could potentially damage the stream's contents by - replacing carrige returns with newlines or otherwise messing with + replacing carriage returns with newlines or otherwise messing with spaces. The mostly likely case of this would be an inline image's compressed data being divided across two streams and having the compressed data in the second stream contain a carriage return as @@ -286,7 +1520,7 @@ * 7.1.0: release - * Allow raw encryption key to be specified in libary and command + * Allow raw encryption key to be specified in library and command line with the QPDF::setPasswordIsHexKey method and --password-is-hex-key option. Allow encryption key to be displayed with --show-encryption-key option. Thanks to Didier Stevens @@ -664,7 +1898,7 @@ 2013-12-14 Jay Berkenbilt - * Allow anyspace rather than just newline to follow xref header. + * Allow any space rather than just newline to follow xref header. This allows qpdf to read a wider range of damaged files. 2013-11-30 Jay Berkenbilt @@ -823,7 +2057,7 @@ * Add QPDF::getCompressibleObjGens() and deprecate QPDF::getCompressibleObjects(), which had a flaw in its logic. - * Add new QPDFObjectHandle::getObjGen() method and indiciate in + * Add new QPDFObjectHandle::getObjGen() method and indicate in comments that its use is favored over getObjectID() and getGeneration() for most cases. @@ -870,7 +2104,7 @@ * Remove all calls to sprintf * New method QUtil::int_to_string_base to convert to octal or - hexademical (or decimal) strings without using sprintf + hexadecimal (or decimal) strings without using sprintf 2013-02-26 Jay Berkenbilt @@ -999,7 +2233,7 @@ QPDF::compute_data_key to take the R and V values from the encryption dictionary. There is no reason for any application code to call this method since handling of encryption is done - automatically by the qpdf libary. It is used internally by + automatically by the qpdf library. It is used internally by QPDFWriter. * Support reading and decryption of files whose main text is not @@ -1314,7 +2548,7 @@ * Add new array mutation routines to QPDFObjectHandle. Implemented by Tobias Hoffmann. - * Rework APIs that use size_t, off_t, and primative integer types + * Rework APIs that use size_t, off_t, and primitive integer types so that size_t is used for sizes of memory and off_t is used for file offsets. Also set _FILE_OFFSET_BITS so that large files can be supported on 32-bit UNIX/Linux platforms. The code assumes in @@ -1417,7 +2651,7 @@ uses the invalid object number 0 as a regular object. * libqpdf/QPDF_linearization.cc (isLinearized): use -1 rather than - 0 as a sentintel for not having found the first object in the + 0 as a sentinel for not having found the first object in the file. Since -1 can never match the regular expression, this prevents an infinite loop when checking a file that starts with (erroneous) 0 0 obj. (Fixes qpdf-Bugs-3159950.) @@ -1640,7 +2874,7 @@ with the required padding as specified by the PDF specification. This is seldom useful to users. This function has been replaced by QPDF::getPaddedUserPassword. Call the new - QPDF::getTrimmedUserPassword to retreive the user password in a + QPDF::getTrimmedUserPassword to retrieve the user password in a human-readable format. * qpdf/qpdf.cc (main): qpdf --check now prints the PDF version diff -Nru qpdf-8.0.2/completions/bash/qpdf qpdf-10.0.1/completions/bash/qpdf --- qpdf-8.0.2/completions/bash/qpdf 1970-01-01 00:00:00.000000000 +0000 +++ qpdf-10.0.1/completions/bash/qpdf 2020-04-09 15:48:26.000000000 +0000 @@ -0,0 +1 @@ +eval $(/usr/bin/qpdf --completion-bash) diff -Nru qpdf-8.0.2/completions/README.md qpdf-10.0.1/completions/README.md --- qpdf-8.0.2/completions/README.md 1970-01-01 00:00:00.000000000 +0000 +++ qpdf-10.0.1/completions/README.md 2020-04-09 15:48:26.000000000 +0000 @@ -0,0 +1,10 @@ +These completion files may be installed in your system's vendor completion area for bash and zsh. + +For example, on a debian-based system, you could install these as + +``` +cp bash/qpdf /usr/share/bash-completion/completions/ +cp zsh/_qpdf /usr/share/zsh/vendor-completions/ +``` + +Packagers are encouraged to install these in whatever locations appropriate for their systems. diff -Nru qpdf-8.0.2/completions/zsh/_qpdf qpdf-10.0.1/completions/zsh/_qpdf --- qpdf-8.0.2/completions/zsh/_qpdf 1970-01-01 00:00:00.000000000 +0000 +++ qpdf-10.0.1/completions/zsh/_qpdf 2020-04-09 15:48:26.000000000 +0000 @@ -0,0 +1,2 @@ +#compdef qpdf +eval $(/usr/bin/qpdf --completion-zsh) diff -Nru qpdf-8.0.2/config.guess qpdf-10.0.1/config.guess --- qpdf-8.0.2/config.guess 2018-03-06 16:34:07.000000000 +0000 +++ qpdf-10.0.1/config.guess 2020-04-09 15:48:26.000000000 +0000 @@ -1,14 +1,12 @@ #! /bin/sh # Attempt to guess a canonical system name. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, -# 2011, 2012 Free Software Foundation, Inc. +# Copyright 1992-2020 Free Software Foundation, Inc. -timestamp='2012-02-10' +timestamp='2020-01-01' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or +# the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but @@ -17,24 +15,22 @@ # General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, see . +# along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - - -# Originally written by Per Bothner. Please send patches (context -# diff format) to and include a ChangeLog -# entry. +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). # -# This script attempts to guess a canonical system name similar to -# config.sub. If it succeeds, it prints the system name on stdout, and -# exits with 0. Otherwise, it exits with 1. +# Originally written by Per Bothner; maintained since 2000 by Ben Elliston. # # You can get the latest version of this script from: -# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD +# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess +# +# Please send patches to . + me=`echo "$0" | sed -e 's,.*/,,'` @@ -43,7 +39,7 @@ Output the configuration name of the system \`$me' is run on. -Operation modes: +Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit @@ -54,9 +50,7 @@ GNU config.guess ($timestamp) Originally written by Per Bothner. -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, -2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 -Free Software Foundation, Inc. +Copyright 1992-2020 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -90,8 +84,6 @@ exit 1 fi -trap 'exit 1' 1 2 15 - # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a @@ -102,34 +94,40 @@ # Portable tmp directory creation inspired by the Autoconf team. -set_cc_for_build=' -trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; -trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; -: ${TMPDIR=/tmp} ; - { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || - { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || - { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || - { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; -dummy=$tmp/dummy ; -tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; -case $CC_FOR_BUILD,$HOST_CC,$CC in - ,,) echo "int x;" > $dummy.c ; - for c in cc gcc c89 c99 ; do - if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then - CC_FOR_BUILD="$c"; break ; - fi ; - done ; - if test x"$CC_FOR_BUILD" = x ; then - CC_FOR_BUILD=no_compiler_found ; - fi - ;; - ,,*) CC_FOR_BUILD=$CC ;; - ,*,*) CC_FOR_BUILD=$HOST_CC ;; -esac ; set_cc_for_build= ;' +tmp= +# shellcheck disable=SC2172 +trap 'test -z "$tmp" || rm -fr "$tmp"' 0 1 2 13 15 + +set_cc_for_build() { + # prevent multiple calls if $tmp is already set + test "$tmp" && return 0 + : "${TMPDIR=/tmp}" + # shellcheck disable=SC2039 + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } + dummy=$tmp/dummy + case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in + ,,) echo "int x;" > "$dummy.c" + for driver in cc gcc c89 c99 ; do + if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then + CC_FOR_BUILD="$driver" + break + fi + done + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; + esac +} # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) -if (test -f /.attbin/uname) >/dev/null 2>&1 ; then +if test -f /.attbin/uname ; then PATH=$PATH:/.attbin ; export PATH fi @@ -138,9 +136,37 @@ UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown +case "$UNAME_SYSTEM" in +Linux|GNU|GNU/*) + # If the system lacks a compiler, then just pick glibc. + # We could probably try harder. + LIBC=gnu + + set_cc_for_build + cat <<-EOF > "$dummy.c" + #include + #if defined(__UCLIBC__) + LIBC=uclibc + #elif defined(__dietlibc__) + LIBC=dietlibc + #else + LIBC=gnu + #endif + EOF + eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`" + + # If ldd exists, use it to detect musl libc. + if command -v ldd >/dev/null && \ + ldd --version 2>&1 | grep -q ^musl + then + LIBC=musl + fi + ;; +esac + # Note: order is significant - the case branches are not exclusive. -case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in +case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, @@ -153,21 +179,31 @@ # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" - UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ - /usr/sbin/$sysctl 2>/dev/null || echo unknown)` - case "${UNAME_MACHINE_ARCH}" in + UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ + "/sbin/$sysctl" 2>/dev/null || \ + "/usr/sbin/$sysctl" 2>/dev/null || \ + echo unknown)` + case "$UNAME_MACHINE_ARCH" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; - *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + earmv*) + arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'` + endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'` + machine="${arch}${endian}"-unknown + ;; + *) machine="$UNAME_MACHINE_ARCH"-unknown ;; esac # The Operating System including object format, if it has switched - # to ELF recently, or will in the future. - case "${UNAME_MACHINE_ARCH}" in + # to ELF recently (or will in the future) and ABI. + case "$UNAME_MACHINE_ARCH" in + earm*) + os=netbsdelf + ;; arm*|i386|m68k|ns32k|sh3*|sparc|vax) - eval $set_cc_for_build + set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then @@ -182,39 +218,72 @@ os=netbsd ;; esac + # Determine ABI tags. + case "$UNAME_MACHINE_ARCH" in + earm*) + expr='s/^earmv[0-9]/-eabi/;s/eb$//' + abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"` + ;; + esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. - case "${UNAME_VERSION}" in + case "$UNAME_VERSION" in Debian*) release='-gnu' ;; *) - release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. - echo "${machine}-${os}${release}" + echo "$machine-${os}${release}${abi-}" + exit ;; + *:Bitrig:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` + echo "$UNAME_MACHINE_ARCH"-unknown-bitrig"$UNAME_RELEASE" exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` - echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + echo "$UNAME_MACHINE_ARCH"-unknown-openbsd"$UNAME_RELEASE" + exit ;; + *:LibertyBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` + echo "$UNAME_MACHINE_ARCH"-unknown-libertybsd"$UNAME_RELEASE" + exit ;; + *:MidnightBSD:*:*) + echo "$UNAME_MACHINE"-unknown-midnightbsd"$UNAME_RELEASE" exit ;; *:ekkoBSD:*:*) - echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + echo "$UNAME_MACHINE"-unknown-ekkobsd"$UNAME_RELEASE" exit ;; *:SolidBSD:*:*) - echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + echo "$UNAME_MACHINE"-unknown-solidbsd"$UNAME_RELEASE" + exit ;; + *:OS108:*:*) + echo "$UNAME_MACHINE"-unknown-os108_"$UNAME_RELEASE" exit ;; macppc:MirBSD:*:*) - echo powerpc-unknown-mirbsd${UNAME_RELEASE} + echo powerpc-unknown-mirbsd"$UNAME_RELEASE" exit ;; *:MirBSD:*:*) - echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + echo "$UNAME_MACHINE"-unknown-mirbsd"$UNAME_RELEASE" + exit ;; + *:Sortix:*:*) + echo "$UNAME_MACHINE"-unknown-sortix + exit ;; + *:Twizzler:*:*) + echo "$UNAME_MACHINE"-unknown-twizzler + exit ;; + *:Redox:*:*) + echo "$UNAME_MACHINE"-unknown-redox + exit ;; + mips:OSF1:*.*) + echo mips-dec-osf1 exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in @@ -232,63 +301,54 @@ ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") - UNAME_MACHINE="alpha" ;; + UNAME_MACHINE=alpha ;; "EV4.5 (21064)") - UNAME_MACHINE="alpha" ;; + UNAME_MACHINE=alpha ;; "LCA4 (21066/21068)") - UNAME_MACHINE="alpha" ;; + UNAME_MACHINE=alpha ;; "EV5 (21164)") - UNAME_MACHINE="alphaev5" ;; + UNAME_MACHINE=alphaev5 ;; "EV5.6 (21164A)") - UNAME_MACHINE="alphaev56" ;; + UNAME_MACHINE=alphaev56 ;; "EV5.6 (21164PC)") - UNAME_MACHINE="alphapca56" ;; + UNAME_MACHINE=alphapca56 ;; "EV5.7 (21164PC)") - UNAME_MACHINE="alphapca57" ;; + UNAME_MACHINE=alphapca57 ;; "EV6 (21264)") - UNAME_MACHINE="alphaev6" ;; + UNAME_MACHINE=alphaev6 ;; "EV6.7 (21264A)") - UNAME_MACHINE="alphaev67" ;; + UNAME_MACHINE=alphaev67 ;; "EV6.8CB (21264C)") - UNAME_MACHINE="alphaev68" ;; + UNAME_MACHINE=alphaev68 ;; "EV6.8AL (21264B)") - UNAME_MACHINE="alphaev68" ;; + UNAME_MACHINE=alphaev68 ;; "EV6.8CX (21264D)") - UNAME_MACHINE="alphaev68" ;; + UNAME_MACHINE=alphaev68 ;; "EV6.9A (21264/EV69A)") - UNAME_MACHINE="alphaev69" ;; + UNAME_MACHINE=alphaev69 ;; "EV7 (21364)") - UNAME_MACHINE="alphaev7" ;; + UNAME_MACHINE=alphaev7 ;; "EV7.9 (21364A)") - UNAME_MACHINE="alphaev79" ;; + UNAME_MACHINE=alphaev79 ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. - echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + echo "$UNAME_MACHINE"-dec-osf"`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`" # Reset EXIT trap before exiting to avoid spurious non-zero exit code. exitcode=$? trap '' 0 exit $exitcode ;; - Alpha\ *:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # Should we change UNAME_MACHINE based on the output of uname instead - # of the specific Alpha model? - echo alpha-pc-interix - exit ;; - 21064:Windows_NT:50:3) - echo alpha-dec-winnt3.5 - exit ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-amigaos + echo "$UNAME_MACHINE"-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-morphos + echo "$UNAME_MACHINE"-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition @@ -300,9 +360,9 @@ echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) - echo arm-acorn-riscix${UNAME_RELEASE} + echo arm-acorn-riscix"$UNAME_RELEASE" exit ;; - arm:riscos:*:*|arm:RISCOS:*:*) + arm*:riscos:*:*|arm*:RISCOS:*:*) echo arm-unknown-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) @@ -327,38 +387,38 @@ sparc) echo sparc-icl-nx7; exit ;; esac ;; s390x:SunOS:*:*) - echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + echo "$UNAME_MACHINE"-ibm-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" exit ;; sun4H:SunOS:5.*:*) - echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + echo sparc-hal-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) - echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + echo sparc-sun-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" exit ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) - echo i386-pc-auroraux${UNAME_RELEASE} + echo i386-pc-auroraux"$UNAME_RELEASE" exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) - eval $set_cc_for_build - SUN_ARCH="i386" + set_cc_for_build + SUN_ARCH=i386 # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. - if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if [ "$CC_FOR_BUILD" != no_compiler_found ]; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then - SUN_ARCH="x86_64" + SUN_ARCH=x86_64 fi fi - echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + echo "$SUN_ARCH"-pc-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. - echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + echo sparc-sun-solaris3"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in @@ -367,25 +427,25 @@ ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. - echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + echo sparc-sun-sunos"`echo "$UNAME_RELEASE"|sed -e 's/-/_/'`" exit ;; sun3*:SunOS:*:*) - echo m68k-sun-sunos${UNAME_RELEASE} + echo m68k-sun-sunos"$UNAME_RELEASE" exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` - test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) - echo m68k-sun-sunos${UNAME_RELEASE} + echo m68k-sun-sunos"$UNAME_RELEASE" ;; sun4) - echo sparc-sun-sunos${UNAME_RELEASE} + echo sparc-sun-sunos"$UNAME_RELEASE" ;; esac exit ;; aushp:SunOS:*:*) - echo sparc-auspex-sunos${UNAME_RELEASE} + echo sparc-auspex-sunos"$UNAME_RELEASE" exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not @@ -396,44 +456,44 @@ # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} + echo m68k-atari-mint"$UNAME_RELEASE" exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} + echo m68k-atari-mint"$UNAME_RELEASE" exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} + echo m68k-atari-mint"$UNAME_RELEASE" exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) - echo m68k-milan-mint${UNAME_RELEASE} + echo m68k-milan-mint"$UNAME_RELEASE" exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) - echo m68k-hades-mint${UNAME_RELEASE} + echo m68k-hades-mint"$UNAME_RELEASE" exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) - echo m68k-unknown-mint${UNAME_RELEASE} + echo m68k-unknown-mint"$UNAME_RELEASE" exit ;; m68k:machten:*:*) - echo m68k-apple-machten${UNAME_RELEASE} + echo m68k-apple-machten"$UNAME_RELEASE" exit ;; powerpc:machten:*:*) - echo powerpc-apple-machten${UNAME_RELEASE} + echo powerpc-apple-machten"$UNAME_RELEASE" exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) - echo mips-dec-ultrix${UNAME_RELEASE} + echo mips-dec-ultrix"$UNAME_RELEASE" exit ;; VAX*:ULTRIX*:*:*) - echo vax-dec-ultrix${UNAME_RELEASE} + echo vax-dec-ultrix"$UNAME_RELEASE" exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) - echo clipper-intergraph-clix${UNAME_RELEASE} + echo clipper-intergraph-clix"$UNAME_RELEASE" exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { @@ -442,23 +502,23 @@ #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) - printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) - printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) - printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF - $CC_FOR_BUILD -o $dummy $dummy.c && - dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && - SYSTEM_NAME=`$dummy $dummyarg` && + $CC_FOR_BUILD -o "$dummy" "$dummy.c" && + dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`"$dummy" "$dummyarg"` && { echo "$SYSTEM_NAME"; exit; } - echo mips-mips-riscos${UNAME_RELEASE} + echo mips-mips-riscos"$UNAME_RELEASE" exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax @@ -484,17 +544,17 @@ AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` - if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + if [ "$UNAME_PROCESSOR" = mc88100 ] || [ "$UNAME_PROCESSOR" = mc88110 ] then - if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ - [ ${TARGET_BINARY_INTERFACE}x = x ] + if [ "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx ] || \ + [ "$TARGET_BINARY_INTERFACE"x = x ] then - echo m88k-dg-dgux${UNAME_RELEASE} + echo m88k-dg-dgux"$UNAME_RELEASE" else - echo m88k-dg-dguxbcs${UNAME_RELEASE} + echo m88k-dg-dguxbcs"$UNAME_RELEASE" fi else - echo i586-dg-dgux${UNAME_RELEASE} + echo i586-dg-dgux"$UNAME_RELEASE" fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) @@ -511,7 +571,7 @@ echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) - echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + echo mips-sgi-irix"`echo "$UNAME_RELEASE"|sed -e 's/-/_/g'`" exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id @@ -523,14 +583,14 @@ if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" fi - echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + echo "$UNAME_MACHINE"-ibm-aix"$IBM_REV" exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" #include main() @@ -541,7 +601,7 @@ exit(0); } EOF - if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` then echo "$SYSTEM_NAME" else @@ -555,26 +615,27 @@ exit ;; *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` - if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` + if [ -x /usr/bin/lslpp ] ; then + IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | + awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" fi - echo ${IBM_ARCH}-ibm-aix${IBM_REV} + echo "$IBM_ARCH"-ibm-aix"$IBM_REV" exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; - ibmrt:4.4BSD:*|romp-ibm:BSD:*) + ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and - echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + echo romp-ibm-bsd"$UNAME_RELEASE" # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx @@ -589,28 +650,28 @@ echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - case "${UNAME_MACHINE}" in - 9000/31? ) HP_ARCH=m68000 ;; - 9000/[34]?? ) HP_ARCH=m68k ;; + HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` + case "$UNAME_MACHINE" in + 9000/31?) HP_ARCH=m68000 ;; + 9000/[34]??) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` - case "${sc_cpu_version}" in - 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 - 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + case "$sc_cpu_version" in + 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 + 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 - case "${sc_kernel_bits}" in - 32) HP_ARCH="hppa2.0n" ;; - 64) HP_ARCH="hppa2.0w" ;; - '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + case "$sc_kernel_bits" in + 32) HP_ARCH=hppa2.0n ;; + 64) HP_ARCH=hppa2.0w ;; + '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 esac ;; esac fi - if [ "${HP_ARCH}" = "" ]; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + if [ "$HP_ARCH" = "" ]; then + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" #define _HPUX_SOURCE #include @@ -643,13 +704,13 @@ exit (0); } EOF - (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac - if [ ${HP_ARCH} = "hppa2.0w" ] + if [ "$HP_ARCH" = hppa2.0w ] then - eval $set_cc_for_build + set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler @@ -660,23 +721,23 @@ # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 - if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then - HP_ARCH="hppa2.0w" + HP_ARCH=hppa2.0w else - HP_ARCH="hppa64" + HP_ARCH=hppa64 fi fi - echo ${HP_ARCH}-hp-hpux${HPUX_REV} + echo "$HP_ARCH"-hp-hpux"$HPUX_REV" exit ;; ia64:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - echo ia64-hp-hpux${HPUX_REV} + HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux"$HPUX_REV" exit ;; 3050*:HI-UX:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" #include int main () @@ -701,11 +762,11 @@ exit (0); } EOF - $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; - 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) @@ -714,7 +775,7 @@ *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; - hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) @@ -722,9 +783,9 @@ exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then - echo ${UNAME_MACHINE}-unknown-osf1mk + echo "$UNAME_MACHINE"-unknown-osf1mk else - echo ${UNAME_MACHINE}-unknown-osf1 + echo "$UNAME_MACHINE"-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) @@ -749,127 +810,123 @@ echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) - echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + echo ymp-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) - echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) - echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + echo t90-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) - echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + echo alphaev5-cray-unicosmk"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) - echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + echo sv1-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) - echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + echo craynv-cray-unicosmp"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) - FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` + FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` + FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` + FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) - echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + echo "$UNAME_MACHINE"-pc-bsdi"$UNAME_RELEASE" exit ;; sparc*:BSD/OS:*:*) - echo sparc-unknown-bsdi${UNAME_RELEASE} + echo sparc-unknown-bsdi"$UNAME_RELEASE" exit ;; *:BSD/OS:*:*) - echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE" + exit ;; + arm:FreeBSD:*:*) + UNAME_PROCESSOR=`uname -p` + set_cc_for_build + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + echo "${UNAME_PROCESSOR}"-unknown-freebsd"`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`"-gnueabi + else + echo "${UNAME_PROCESSOR}"-unknown-freebsd"`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`"-gnueabihf + fi exit ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`/usr/bin/uname -p` - case ${UNAME_PROCESSOR} in + case "$UNAME_PROCESSOR" in amd64) - echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; - *) - echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + UNAME_PROCESSOR=x86_64 ;; + i386) + UNAME_PROCESSOR=i586 ;; esac + echo "$UNAME_PROCESSOR"-unknown-freebsd"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" exit ;; i*:CYGWIN*:*) - echo ${UNAME_MACHINE}-pc-cygwin + echo "$UNAME_MACHINE"-pc-cygwin exit ;; - *:MINGW*:*) - echo ${UNAME_MACHINE}-pc-mingw32 + *:MINGW64*:*) + echo "$UNAME_MACHINE"-pc-mingw64 exit ;; - i*:MSYS*:*) - echo ${UNAME_MACHINE}-pc-msys + *:MINGW*:*) + echo "$UNAME_MACHINE"-pc-mingw32 exit ;; - i*:windows32*:*) - # uname -m includes "-pc" on this system. - echo ${UNAME_MACHINE}-mingw32 + *:MSYS*:*) + echo "$UNAME_MACHINE"-pc-msys exit ;; i*:PW*:*) - echo ${UNAME_MACHINE}-pc-pw32 + echo "$UNAME_MACHINE"-pc-pw32 exit ;; *:Interix*:*) - case ${UNAME_MACHINE} in + case "$UNAME_MACHINE" in x86) - echo i586-pc-interix${UNAME_RELEASE} + echo i586-pc-interix"$UNAME_RELEASE" exit ;; authenticamd | genuineintel | EM64T) - echo x86_64-unknown-interix${UNAME_RELEASE} + echo x86_64-unknown-interix"$UNAME_RELEASE" exit ;; IA64) - echo ia64-unknown-interix${UNAME_RELEASE} + echo ia64-unknown-interix"$UNAME_RELEASE" exit ;; esac ;; - [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) - echo i${UNAME_MACHINE}-pc-mks - exit ;; - 8664:Windows_NT:*) - echo x86_64-pc-mks - exit ;; - i*:Windows_NT*:* | Pentium*:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we - # UNAME_MACHINE based on the output of uname instead of i386? - echo i586-pc-interix - exit ;; i*:UWIN*:*) - echo ${UNAME_MACHINE}-pc-uwin + echo "$UNAME_MACHINE"-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) - echo x86_64-unknown-cygwin - exit ;; - p*:CYGWIN*:*) - echo powerpcle-unknown-cygwin + echo x86_64-pc-cygwin exit ;; prep*:SunOS:5.*:*) - echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + echo powerpcle-unknown-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" exit ;; *:GNU:*:*) # the GNU system - echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + echo "`echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,'`-unknown-$LIBC`echo "$UNAME_RELEASE"|sed -e 's,/.*$,,'`" exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland - echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + echo "$UNAME_MACHINE-unknown-`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`-$LIBC" exit ;; - i*86:Minix:*:*) - echo ${UNAME_MACHINE}-pc-minix + *:Minix:*:*) + echo "$UNAME_MACHINE"-unknown-minix exit ;; aarch64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; alpha:Linux:*:*) - case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; @@ -879,125 +936,169 @@ EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 - if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi - echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + if test "$?" = 0 ; then LIBC=gnulibc1 ; fi + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + arc:Linux:*:* | arceb:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; arm*:Linux:*:*) - eval $set_cc_for_build + set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then - echo ${UNAME_MACHINE}-unknown-linux-gnueabi + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabi else - echo ${UNAME_MACHINE}-unknown-linux-gnueabihf + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabihf fi fi exit ;; avr32*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; cris:Linux:*:*) - echo ${UNAME_MACHINE}-axis-linux-gnu + echo "$UNAME_MACHINE"-axis-linux-"$LIBC" exit ;; crisv32:Linux:*:*) - echo ${UNAME_MACHINE}-axis-linux-gnu + echo "$UNAME_MACHINE"-axis-linux-"$LIBC" + exit ;; + e2k:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; frv:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; hexagon:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; i*86:Linux:*:*) - LIBC=gnu - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #ifdef __dietlibc__ - LIBC=dietlibc - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` - echo "${UNAME_MACHINE}-pc-linux-${LIBC}" + echo "$UNAME_MACHINE"-pc-linux-"$LIBC" exit ;; ia64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + k1om:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; m32r*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; m68*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; mips:Linux:*:* | mips64:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + set_cc_for_build + IS_GLIBC=0 + test x"${LIBC}" = xgnu && IS_GLIBC=1 + sed 's/^ //' << EOF > "$dummy.c" #undef CPU - #undef ${UNAME_MACHINE} - #undef ${UNAME_MACHINE}el + #undef mips + #undef mipsel + #undef mips64 + #undef mips64el + #if ${IS_GLIBC} && defined(_ABI64) + LIBCABI=gnuabi64 + #else + #if ${IS_GLIBC} && defined(_ABIN32) + LIBCABI=gnuabin32 + #else + LIBCABI=${LIBC} + #endif + #endif + + #if ${IS_GLIBC} && defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 + CPU=mipsisa64r6 + #else + #if ${IS_GLIBC} && !defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 + CPU=mipsisa32r6 + #else + #if defined(__mips64) + CPU=mips64 + #else + CPU=mips + #endif + #endif + #endif + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=${UNAME_MACHINE}el + MIPS_ENDIAN=el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=${UNAME_MACHINE} + MIPS_ENDIAN= #else - CPU= + MIPS_ENDIAN= #endif #endif EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI'`" + test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; } ;; - or32:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + mips64el:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + openrisc*:Linux:*:*) + echo or1k-unknown-linux-"$LIBC" + exit ;; + or32:Linux:*:* | or1k*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; padre:Linux:*:*) - echo sparc-unknown-linux-gnu + echo sparc-unknown-linux-"$LIBC" exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-unknown-linux-gnu + echo hppa64-unknown-linux-"$LIBC" exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in - PA7*) echo hppa1.1-unknown-linux-gnu ;; - PA8*) echo hppa2.0-unknown-linux-gnu ;; - *) echo hppa-unknown-linux-gnu ;; + PA7*) echo hppa1.1-unknown-linux-"$LIBC" ;; + PA8*) echo hppa2.0-unknown-linux-"$LIBC" ;; + *) echo hppa-unknown-linux-"$LIBC" ;; esac exit ;; ppc64:Linux:*:*) - echo powerpc64-unknown-linux-gnu + echo powerpc64-unknown-linux-"$LIBC" exit ;; ppc:Linux:*:*) - echo powerpc-unknown-linux-gnu + echo powerpc-unknown-linux-"$LIBC" + exit ;; + ppc64le:Linux:*:*) + echo powerpc64le-unknown-linux-"$LIBC" + exit ;; + ppcle:Linux:*:*) + echo powerpcle-unknown-linux-"$LIBC" + exit ;; + riscv32:Linux:*:* | riscv64:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; s390:Linux:*:* | s390x:Linux:*:*) - echo ${UNAME_MACHINE}-ibm-linux + echo "$UNAME_MACHINE"-ibm-linux-"$LIBC" exit ;; sh64*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; sh*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; tile*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; vax:Linux:*:*) - echo ${UNAME_MACHINE}-dec-linux-gnu + echo "$UNAME_MACHINE"-dec-linux-"$LIBC" exit ;; x86_64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo "$UNAME_MACHINE"-pc-linux-"$LIBC" exit ;; xtensa*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. @@ -1011,34 +1112,34 @@ # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. - echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + echo "$UNAME_MACHINE"-pc-sysv4.2uw"$UNAME_VERSION" exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. - echo ${UNAME_MACHINE}-pc-os2-emx + echo "$UNAME_MACHINE"-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) - echo ${UNAME_MACHINE}-unknown-stop + echo "$UNAME_MACHINE"-unknown-stop exit ;; i*86:atheos:*:*) - echo ${UNAME_MACHINE}-unknown-atheos + echo "$UNAME_MACHINE"-unknown-atheos exit ;; i*86:syllable:*:*) - echo ${UNAME_MACHINE}-pc-syllable + echo "$UNAME_MACHINE"-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) - echo i386-unknown-lynxos${UNAME_RELEASE} + echo i386-unknown-lynxos"$UNAME_RELEASE" exit ;; i*86:*DOS:*:*) - echo ${UNAME_MACHINE}-pc-msdosdjgpp + echo "$UNAME_MACHINE"-pc-msdosdjgpp exit ;; - i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) - UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + i*86:*:4.*:*) + UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then - echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + echo "$UNAME_MACHINE"-univel-sysv"$UNAME_REL" else - echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + echo "$UNAME_MACHINE"-pc-sysv"$UNAME_REL" fi exit ;; i*86:*:5:[678]*) @@ -1048,12 +1149,12 @@ *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac - echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + echo "$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}" exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 @@ -1063,9 +1164,9 @@ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 - echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + echo "$UNAME_MACHINE"-pc-sco"$UNAME_REL" else - echo ${UNAME_MACHINE}-pc-sysv32 + echo "$UNAME_MACHINE"-pc-sysv32 fi exit ;; pc:*:*:*) @@ -1073,7 +1174,7 @@ # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub - # prints for the "djgpp" host, or else GDB configury will decide that + # prints for the "djgpp" host, or else GDB configure will decide that # this is a cross-build. echo i586-pc-msdosdjgpp exit ;; @@ -1085,9 +1186,9 @@ exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then - echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + echo i860-stardent-sysv"$UNAME_RELEASE" # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. - echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + echo i860-unknown-sysv"$UNAME_RELEASE" # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) @@ -1107,9 +1208,9 @@ test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; @@ -1118,28 +1219,28 @@ test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) - echo m68k-unknown-lynxos${UNAME_RELEASE} + echo m68k-unknown-lynxos"$UNAME_RELEASE" exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) - echo sparc-unknown-lynxos${UNAME_RELEASE} + echo sparc-unknown-lynxos"$UNAME_RELEASE" exit ;; rs6000:LynxOS:2.*:*) - echo rs6000-unknown-lynxos${UNAME_RELEASE} + echo rs6000-unknown-lynxos"$UNAME_RELEASE" exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) - echo powerpc-unknown-lynxos${UNAME_RELEASE} + echo powerpc-unknown-lynxos"$UNAME_RELEASE" exit ;; SM[BE]S:UNIX_SV:*:*) - echo mips-dde-sysv${UNAME_RELEASE} + echo mips-dde-sysv"$UNAME_RELEASE" exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 @@ -1150,7 +1251,7 @@ *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` - echo ${UNAME_MACHINE}-sni-sysv4 + echo "$UNAME_MACHINE"-sni-sysv4 else echo ns32k-sni-sysv fi @@ -1170,23 +1271,23 @@ exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. - echo ${UNAME_MACHINE}-stratus-vos + echo "$UNAME_MACHINE"-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) - echo m68k-apple-aux${UNAME_RELEASE} + echo m68k-apple-aux"$UNAME_RELEASE" exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then - echo mips-nec-sysv${UNAME_RELEASE} + echo mips-nec-sysv"$UNAME_RELEASE" else - echo mips-unknown-sysv${UNAME_RELEASE} + echo mips-unknown-sysv"$UNAME_RELEASE" fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. @@ -1201,66 +1302,98 @@ BePC:Haiku:*:*) # Haiku running on Intel PC compatible. echo i586-pc-haiku exit ;; + x86_64:Haiku:*:*) + echo x86_64-unknown-haiku + exit ;; SX-4:SUPER-UX:*:*) - echo sx4-nec-superux${UNAME_RELEASE} + echo sx4-nec-superux"$UNAME_RELEASE" exit ;; SX-5:SUPER-UX:*:*) - echo sx5-nec-superux${UNAME_RELEASE} + echo sx5-nec-superux"$UNAME_RELEASE" exit ;; SX-6:SUPER-UX:*:*) - echo sx6-nec-superux${UNAME_RELEASE} + echo sx6-nec-superux"$UNAME_RELEASE" exit ;; SX-7:SUPER-UX:*:*) - echo sx7-nec-superux${UNAME_RELEASE} + echo sx7-nec-superux"$UNAME_RELEASE" exit ;; SX-8:SUPER-UX:*:*) - echo sx8-nec-superux${UNAME_RELEASE} + echo sx8-nec-superux"$UNAME_RELEASE" exit ;; SX-8R:SUPER-UX:*:*) - echo sx8r-nec-superux${UNAME_RELEASE} + echo sx8r-nec-superux"$UNAME_RELEASE" + exit ;; + SX-ACE:SUPER-UX:*:*) + echo sxace-nec-superux"$UNAME_RELEASE" exit ;; Power*:Rhapsody:*:*) - echo powerpc-apple-rhapsody${UNAME_RELEASE} + echo powerpc-apple-rhapsody"$UNAME_RELEASE" exit ;; *:Rhapsody:*:*) - echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + echo "$UNAME_MACHINE"-apple-rhapsody"$UNAME_RELEASE" exit ;; *:Darwin:*:*) - UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + UNAME_PROCESSOR=`uname -p` case $UNAME_PROCESSOR in - i386) - eval $set_cc_for_build - if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then - if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_64BIT_ARCH >/dev/null - then - UNAME_PROCESSOR="x86_64" - fi - fi ;; unknown) UNAME_PROCESSOR=powerpc ;; esac - echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + if command -v xcode-select > /dev/null 2> /dev/null && \ + ! xcode-select --print-path > /dev/null 2> /dev/null ; then + # Avoid executing cc if there is no toolchain installed as + # cc will be a stub that puts up a graphical alert + # prompting the user to install developer tools. + CC_FOR_BUILD=no_compiler_found + else + set_cc_for_build + fi + if [ "$CC_FOR_BUILD" != no_compiler_found ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + case $UNAME_PROCESSOR in + i386) UNAME_PROCESSOR=x86_64 ;; + powerpc) UNAME_PROCESSOR=powerpc64 ;; + esac + fi + # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc + if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_PPC >/dev/null + then + UNAME_PROCESSOR=powerpc + fi + elif test "$UNAME_PROCESSOR" = i386 ; then + # uname -m returns i386 or x86_64 + UNAME_PROCESSOR=$UNAME_MACHINE + fi + echo "$UNAME_PROCESSOR"-apple-darwin"$UNAME_RELEASE" exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` - if test "$UNAME_PROCESSOR" = "x86"; then + if test "$UNAME_PROCESSOR" = x86; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi - echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + echo "$UNAME_PROCESSOR"-"$UNAME_MACHINE"-nto-qnx"$UNAME_RELEASE" exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; - NEO-?:NONSTOP_KERNEL:*:*) - echo neo-tandem-nsk${UNAME_RELEASE} + NEO-*:NONSTOP_KERNEL:*:*) + echo neo-tandem-nsk"$UNAME_RELEASE" + exit ;; + NSE-*:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk"$UNAME_RELEASE" + exit ;; + NSR-*:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk"$UNAME_RELEASE" exit ;; - NSE-?:NONSTOP_KERNEL:*:*) - echo nse-tandem-nsk${UNAME_RELEASE} + NSV-*:NONSTOP_KERNEL:*:*) + echo nsv-tandem-nsk"$UNAME_RELEASE" exit ;; - NSR-?:NONSTOP_KERNEL:*:*) - echo nsr-tandem-nsk${UNAME_RELEASE} + NSX-*:NONSTOP_KERNEL:*:*) + echo nsx-tandem-nsk"$UNAME_RELEASE" exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux @@ -1269,18 +1402,19 @@ echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) - echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + echo "$UNAME_MACHINE"-"$UNAME_SYSTEM"-"$UNAME_RELEASE" exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. - if test "$cputype" = "386"; then + # shellcheck disable=SC2154 + if test "$cputype" = 386; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi - echo ${UNAME_MACHINE}-unknown-plan9 + echo "$UNAME_MACHINE"-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 @@ -1301,14 +1435,14 @@ echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) - echo mips-sei-seiux${UNAME_RELEASE} + echo mips-sei-seiux"$UNAME_RELEASE" exit ;; *:DragonFly:*:*) - echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + echo "$UNAME_MACHINE"-unknown-dragonfly"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` - case "${UNAME_MACHINE}" in + case "$UNAME_MACHINE" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; @@ -1317,27 +1451,39 @@ echo i386-pc-xenix exit ;; i*86:skyos:*:*) - echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + echo "$UNAME_MACHINE"-pc-skyos"`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'`" exit ;; i*86:rdos:*:*) - echo ${UNAME_MACHINE}-pc-rdos + echo "$UNAME_MACHINE"-pc-rdos exit ;; i*86:AROS:*:*) - echo ${UNAME_MACHINE}-pc-aros + echo "$UNAME_MACHINE"-pc-aros exit ;; x86_64:VMkernel:*:*) - echo ${UNAME_MACHINE}-unknown-esx + echo "$UNAME_MACHINE"-unknown-esx + exit ;; + amd64:Isilon\ OneFS:*:*) + echo x86_64-unknown-onefs + exit ;; + *:Unleashed:*:*) + echo "$UNAME_MACHINE"-unknown-unleashed"$UNAME_RELEASE" exit ;; esac -#echo '(No uname command or uname output not recognized.)' 1>&2 -#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 - -eval $set_cc_for_build -cat >$dummy.c < "$dummy.c" < -# include +#include +#include +#endif +#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) +#if defined (vax) || defined (__vax) || defined (__vax__) || defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) +#include +#if defined(_SIZE_T_) || defined(SIGLOST) +#include +#endif +#endif #endif main () { @@ -1350,20 +1496,12 @@ #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 - "4" + "4" #else - "" -#endif - ); exit (0); -#endif + "" #endif - -#if defined (__arm) && defined (__acorn) && defined (__unix) - printf ("arm-acorn-riscix\n"); exit (0); + ); exit (0); #endif - -#if defined (hp300) && !defined (hpux) - printf ("m68k-hp-bsd\n"); exit (0); #endif #if defined (NeXT) @@ -1405,39 +1543,54 @@ #endif #if defined (_SEQUENT_) - struct utsname un; - - uname(&un); - - if (strncmp(un.version, "V2", 2) == 0) { - printf ("i386-sequent-ptx2\n"); exit (0); - } - if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ - printf ("i386-sequent-ptx1\n"); exit (0); - } - printf ("i386-sequent-ptx\n"); exit (0); + struct utsname un; + uname(&un); + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) -# if !defined (ultrix) -# include -# if defined (BSD) -# if BSD == 43 - printf ("vax-dec-bsd4.3\n"); exit (0); -# else -# if BSD == 199006 - printf ("vax-dec-bsd4.3reno\n"); exit (0); -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# endif -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# else - printf ("vax-dec-ultrix\n"); exit (0); -# endif +#if !defined (ultrix) +#include +#if defined (BSD) +#if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +#else +#if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +#else + printf ("vax-dec-bsd\n"); exit (0); +#endif +#endif +#else + printf ("vax-dec-bsd\n"); exit (0); +#endif +#else +#if defined(_SIZE_T_) || defined(SIGLOST) + struct utsname un; + uname (&un); + printf ("vax-dec-ultrix%s\n", un.release); exit (0); +#else + printf ("vax-dec-ultrix\n"); exit (0); +#endif +#endif +#endif +#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) +#if defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) +#if defined(_SIZE_T_) || defined(SIGLOST) + struct utsname *un; + uname (&un); + printf ("mips-dec-ultrix%s\n", un.release); exit (0); +#else + printf ("mips-dec-ultrix\n"); exit (0); +#endif +#endif #endif #if defined (alliant) && defined (i860) @@ -1448,54 +1601,38 @@ } EOF -$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && +$CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } # Apollos put the system type in the environment. +test -d /usr/apollo && { echo "$ISP-apollo-$SYSTYPE"; exit; } -test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } +echo "$0: unable to guess system type" >&2 -# Convex versions that predate uname can use getsysinfo(1) +case "$UNAME_MACHINE:$UNAME_SYSTEM" in + mips:Linux | mips64:Linux) + # If we got here on MIPS GNU/Linux, output extra information. + cat >&2 <&2 < in order to provide the needed -information to handle your system. +If $0 has already been updated, send the following data and any +information you think might be pertinent to config-patches@gnu.org to +provide the necessary information to handle your system. config.guess timestamp = $timestamp @@ -1514,16 +1651,16 @@ /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` -UNAME_MACHINE = ${UNAME_MACHINE} -UNAME_RELEASE = ${UNAME_RELEASE} -UNAME_SYSTEM = ${UNAME_SYSTEM} -UNAME_VERSION = ${UNAME_VERSION} +UNAME_MACHINE = "$UNAME_MACHINE" +UNAME_RELEASE = "$UNAME_RELEASE" +UNAME_SYSTEM = "$UNAME_SYSTEM" +UNAME_VERSION = "$UNAME_VERSION" EOF exit 1 # Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" diff -Nru qpdf-8.0.2/config-mingw qpdf-10.0.1/config-mingw --- qpdf-8.0.2/config-mingw 2018-03-06 16:34:07.000000000 +0000 +++ qpdf-10.0.1/config-mingw 2020-04-09 15:48:26.000000000 +0000 @@ -6,4 +6,4 @@ else wordsize=32 fi -./configure --disable-test-compare-images --enable-external-libs --enable-werror --with-windows-wordsize=$wordsize --with-buildrules=mingw ${1+"$@"} +./configure --disable-test-compare-images --enable-external-libs --enable-werror --with-buildrules=mingw ${1+"$@"} diff -Nru qpdf-8.0.2/config-msvc qpdf-10.0.1/config-msvc --- qpdf-8.0.2/config-msvc 2018-03-06 16:34:07.000000000 +0000 +++ qpdf-10.0.1/config-msvc 2020-04-09 15:48:26.000000000 +0000 @@ -6,4 +6,4 @@ else wordsize=32 fi -CC=cl CXX="cl -TP -GR" ./configure --disable-test-compare-images --enable-external-libs --enable-werror --with-windows-wordsize=$wordsize --with-buildrules=msvc ${1+"$@"} +CC=cl CXX="cl -TP -GR" ./configure --disable-test-compare-images --enable-external-libs --enable-werror --with-buildrules=msvc ${1+"$@"} diff -Nru qpdf-8.0.2/config.sub qpdf-10.0.1/config.sub --- qpdf-8.0.2/config.sub 2018-03-06 16:34:07.000000000 +0000 +++ qpdf-10.0.1/config.sub 2020-04-09 15:48:26.000000000 +0000 @@ -1,36 +1,31 @@ #! /bin/sh # Configuration validation subroutine script. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, -# 2011, 2012 Free Software Foundation, Inc. - -timestamp='2012-02-10' - -# This file is (in principle) common to ALL GNU software. -# The presence of a machine in this file suggests that SOME GNU software -# can handle that machine. It does not imply ALL GNU software can. -# -# This file is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or +# Copyright 1992-2020 Free Software Foundation, Inc. + +timestamp='2020-01-01' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, see . +# along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). -# Please send patches to . Submit a context -# diff and a properly formatted GNU ChangeLog entry. +# Please send patches to . # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. @@ -38,7 +33,7 @@ # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: -# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD +# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases @@ -58,12 +53,11 @@ me=`echo "$0" | sed -e 's,.*/,,'` usage="\ -Usage: $0 [OPTION] CPU-MFR-OPSYS - $0 [OPTION] ALIAS +Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS Canonicalize a configuration name. -Operation modes: +Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit @@ -73,9 +67,7 @@ version="\ GNU config.sub ($timestamp) -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, -2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 -Free Software Foundation, Inc. +Copyright 1992-2020 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -97,12 +89,12 @@ - ) # Use stdin as input. break ;; -* ) - echo "$me: invalid option $1$help" + echo "$me: invalid option $1$help" >&2 exit 1 ;; *local*) # First pass through any local machine types. - echo $1 + echo "$1" exit ;; * ) @@ -118,1190 +110,1164 @@ exit 1;; esac -# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). -# Here we must recognize all the valid KERNEL-OS combinations. -maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` -case $maybe_os in - nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ - linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ - knetbsd*-gnu* | netbsd*-gnu* | \ - kopensolaris*-gnu* | \ - storm-chaos* | os2-emx* | rtmk-nova*) - os=-$maybe_os - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` - ;; - android-linux) - os=-linux-android - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown - ;; - *) - basic_machine=`echo $1 | sed 's/-[^-]*$//'` - if [ $basic_machine != $1 ] - then os=`echo $1 | sed 's/.*-/-/'` - else os=; fi - ;; -esac - -### Let's recognize common machines as not being operating systems so -### that things like config.sub decstation-3100 work. We also -### recognize some manufacturers as not being operating systems, so we -### can provide default operating systems below. -case $os in - -sun*os*) - # Prevent following clause from handling this invalid input. - ;; - -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ - -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ - -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ - -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ - -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ - -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ - -apple | -axis | -knuth | -cray | -microblaze) - os= - basic_machine=$1 - ;; - -bluegene*) - os=-cnk - ;; - -sim | -cisco | -oki | -wec | -winbond) - os= - basic_machine=$1 - ;; - -scout) - ;; - -wrs) - os=-vxworks - basic_machine=$1 - ;; - -chorusos*) - os=-chorusos - basic_machine=$1 - ;; - -chorusrdb) - os=-chorusrdb - basic_machine=$1 - ;; - -hiux*) - os=-hiuxwe2 - ;; - -sco6) - os=-sco5v6 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco5) - os=-sco3.2v5 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco4) - os=-sco3.2v4 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2.[4-9]*) - os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2v[4-9]*) - # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco5v6*) - # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco*) - os=-sco3.2v2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -udk*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -isc) - os=-isc2.2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -clix*) - basic_machine=clipper-intergraph - ;; - -isc*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -lynx*) - os=-lynxos +# Split fields of configuration type +# shellcheck disable=SC2162 +IFS="-" read field1 field2 field3 field4 <&2 + exit 1 ;; - -ptx*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + *-*-*-*) + basic_machine=$field1-$field2 + os=$field3-$field4 ;; - -windowsnt*) - os=`echo $os | sed -e 's/windowsnt/winnt/'` + *-*-*) + # Ambiguous whether COMPANY is present, or skipped and KERNEL-OS is two + # parts + maybe_os=$field2-$field3 + case $maybe_os in + nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc \ + | linux-newlib* | linux-musl* | linux-uclibc* | uclinux-uclibc* \ + | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \ + | netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \ + | storm-chaos* | os2-emx* | rtmk-nova*) + basic_machine=$field1 + os=$maybe_os + ;; + android-linux) + basic_machine=$field1-unknown + os=linux-android + ;; + *) + basic_machine=$field1-$field2 + os=$field3 + ;; + esac ;; - -psos*) - os=-psos + *-*) + # A lone config we happen to match not fitting any pattern + case $field1-$field2 in + decstation-3100) + basic_machine=mips-dec + os= + ;; + *-*) + # Second component is usually, but not always the OS + case $field2 in + # Prevent following clause from handling this valid os + sun*os*) + basic_machine=$field1 + os=$field2 + ;; + # Manufacturers + dec* | mips* | sequent* | encore* | pc533* | sgi* | sony* \ + | att* | 7300* | 3300* | delta* | motorola* | sun[234]* \ + | unicom* | ibm* | next | hp | isi* | apollo | altos* \ + | convergent* | ncr* | news | 32* | 3600* | 3100* \ + | hitachi* | c[123]* | convex* | sun | crds | omron* | dg \ + | ultra | tti* | harris | dolphin | highlevel | gould \ + | cbm | ns | masscomp | apple | axis | knuth | cray \ + | microblaze* | sim | cisco \ + | oki | wec | wrs | winbond) + basic_machine=$field1-$field2 + os= + ;; + *) + basic_machine=$field1 + os=$field2 + ;; + esac + ;; + esac ;; - -mint | -mint[0-9]*) - basic_machine=m68k-atari - os=-mint + *) + # Convert single-component short-hands not valid as part of + # multi-component configurations. + case $field1 in + 386bsd) + basic_machine=i386-pc + os=bsd + ;; + a29khif) + basic_machine=a29k-amd + os=udi + ;; + adobe68k) + basic_machine=m68010-adobe + os=scout + ;; + alliant) + basic_machine=fx80-alliant + os= + ;; + altos | altos3068) + basic_machine=m68k-altos + os= + ;; + am29k) + basic_machine=a29k-none + os=bsd + ;; + amdahl) + basic_machine=580-amdahl + os=sysv + ;; + amiga) + basic_machine=m68k-unknown + os= + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=bsd + ;; + aros) + basic_machine=i386-pc + os=aros + ;; + aux) + basic_machine=m68k-apple + os=aux + ;; + balance) + basic_machine=ns32k-sequent + os=dynix + ;; + blackfin) + basic_machine=bfin-unknown + os=linux + ;; + cegcc) + basic_machine=arm-unknown + os=cegcc + ;; + convex-c1) + basic_machine=c1-convex + os=bsd + ;; + convex-c2) + basic_machine=c2-convex + os=bsd + ;; + convex-c32) + basic_machine=c32-convex + os=bsd + ;; + convex-c34) + basic_machine=c34-convex + os=bsd + ;; + convex-c38) + basic_machine=c38-convex + os=bsd + ;; + cray) + basic_machine=j90-cray + os=unicos + ;; + crds | unos) + basic_machine=m68k-crds + os= + ;; + da30) + basic_machine=m68k-da30 + os= + ;; + decstation | pmax | pmin | dec3100 | decstatn) + basic_machine=mips-dec + os= + ;; + delta88) + basic_machine=m88k-motorola + os=sysv3 + ;; + dicos) + basic_machine=i686-pc + os=dicos + ;; + djgpp) + basic_machine=i586-pc + os=msdosdjgpp + ;; + ebmon29k) + basic_machine=a29k-amd + os=ebmon + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=ose + ;; + gmicro) + basic_machine=tron-gmicro + os=sysv + ;; + go32) + basic_machine=i386-pc + os=go32 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=hms + ;; + harris) + basic_machine=m88k-harris + os=sysv3 + ;; + hp300 | hp300hpux) + basic_machine=m68k-hp + os=hpux + ;; + hp300bsd) + basic_machine=m68k-hp + os=bsd + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=proelf + ;; + i386mach) + basic_machine=i386-mach + os=mach + ;; + isi68 | isi) + basic_machine=m68k-isi + os=sysv + ;; + m68knommu) + basic_machine=m68k-unknown + os=linux + ;; + magnum | m3230) + basic_machine=mips-mips + os=sysv + ;; + merlin) + basic_machine=ns32k-utek + os=sysv + ;; + mingw64) + basic_machine=x86_64-pc + os=mingw64 + ;; + mingw32) + basic_machine=i686-pc + os=mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=mingw32ce + ;; + monitor) + basic_machine=m68k-rom68k + os=coff + ;; + morphos) + basic_machine=powerpc-unknown + os=morphos + ;; + moxiebox) + basic_machine=moxie-unknown + os=moxiebox + ;; + msdos) + basic_machine=i386-pc + os=msdos + ;; + msys) + basic_machine=i686-pc + os=msys + ;; + mvs) + basic_machine=i370-ibm + os=mvs + ;; + nacl) + basic_machine=le32-unknown + os=nacl + ;; + ncr3000) + basic_machine=i486-ncr + os=sysv4 + ;; + netbsd386) + basic_machine=i386-pc + os=netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=newsos + ;; + news1000) + basic_machine=m68030-sony + os=newsos + ;; + necv70) + basic_machine=v70-nec + os=sysv + ;; + nh3000) + basic_machine=m68k-harris + os=cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=cxux + ;; + nindy960) + basic_machine=i960-intel + os=nindy + ;; + mon960) + basic_machine=i960-intel + os=mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=nonstopux + ;; + os400) + basic_machine=powerpc-ibm + os=os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=ose + ;; + os68k) + basic_machine=m68k-none + os=os68k + ;; + paragon) + basic_machine=i860-intel + os=osf + ;; + parisc) + basic_machine=hppa-unknown + os=linux + ;; + pw32) + basic_machine=i586-unknown + os=pw32 + ;; + rdos | rdos64) + basic_machine=x86_64-pc + os=rdos + ;; + rdos32) + basic_machine=i386-pc + os=rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=coff + ;; + sa29200) + basic_machine=a29k-amd + os=udi + ;; + sei) + basic_machine=mips-sei + os=seiux + ;; + sequent) + basic_machine=i386-sequent + os= + ;; + sps7) + basic_machine=m68k-bull + os=sysv2 + ;; + st2000) + basic_machine=m68k-tandem + os= + ;; + stratus) + basic_machine=i860-stratus + os=sysv4 + ;; + sun2) + basic_machine=m68000-sun + os= + ;; + sun2os3) + basic_machine=m68000-sun + os=sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=sunos4 + ;; + sun3) + basic_machine=m68k-sun + os= + ;; + sun3os3) + basic_machine=m68k-sun + os=sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=sunos4 + ;; + sun4) + basic_machine=sparc-sun + os= + ;; + sun4os3) + basic_machine=sparc-sun + os=sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=solaris2 + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + os= + ;; + sv1) + basic_machine=sv1-cray + os=unicos + ;; + symmetry) + basic_machine=i386-sequent + os=dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=unicos + ;; + t90) + basic_machine=t90-cray + os=unicos + ;; + toad1) + basic_machine=pdp10-xkl + os=tops20 + ;; + tpf) + basic_machine=s390x-ibm + os=tpf + ;; + udi29k) + basic_machine=a29k-amd + os=udi + ;; + ultra3) + basic_machine=a29k-nyu + os=sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=none + ;; + vaxv) + basic_machine=vax-dec + os=sysv + ;; + vms) + basic_machine=vax-dec + os=vms + ;; + vsta) + basic_machine=i386-pc + os=vsta + ;; + vxworks960) + basic_machine=i960-wrs + os=vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=vxworks + ;; + xbox) + basic_machine=i686-pc + os=mingw32 + ;; + ymp) + basic_machine=ymp-cray + os=unicos + ;; + *) + basic_machine=$1 + os= + ;; + esac ;; esac -# Decode aliases for certain CPU-COMPANY combinations. +# Decode 1-component or ad-hoc basic machines case $basic_machine in - # Recognize the basic CPU types without company name. - # Some are omitted here because they have special meanings below. - 1750a | 580 \ - | a29k \ - | aarch64 | aarch64_be \ - | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ - | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ - | am33_2.0 \ - | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ - | be32 | be64 \ - | bfin \ - | c4x | clipper \ - | d10v | d30v | dlx | dsp16xx \ - | epiphany \ - | fido | fr30 | frv \ - | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ - | hexagon \ - | i370 | i860 | i960 | ia64 \ - | ip2k | iq2000 \ - | le32 | le64 \ - | lm32 \ - | m32c | m32r | m32rle | m68000 | m68k | m88k \ - | maxq | mb | microblaze | mcore | mep | metag \ - | mips | mipsbe | mipseb | mipsel | mipsle \ - | mips16 \ - | mips64 | mips64el \ - | mips64octeon | mips64octeonel \ - | mips64orion | mips64orionel \ - | mips64r5900 | mips64r5900el \ - | mips64vr | mips64vrel \ - | mips64vr4100 | mips64vr4100el \ - | mips64vr4300 | mips64vr4300el \ - | mips64vr5000 | mips64vr5000el \ - | mips64vr5900 | mips64vr5900el \ - | mipsisa32 | mipsisa32el \ - | mipsisa32r2 | mipsisa32r2el \ - | mipsisa64 | mipsisa64el \ - | mipsisa64r2 | mipsisa64r2el \ - | mipsisa64sb1 | mipsisa64sb1el \ - | mipsisa64sr71k | mipsisa64sr71kel \ - | mipstx39 | mipstx39el \ - | mn10200 | mn10300 \ - | moxie \ - | mt \ - | msp430 \ - | nds32 | nds32le | nds32be \ - | nios | nios2 \ - | ns16k | ns32k \ - | open8 \ - | or32 \ - | pdp10 | pdp11 | pj | pjl \ - | powerpc | powerpc64 | powerpc64le | powerpcle \ - | pyramid \ - | rl78 | rx \ - | score \ - | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ - | sh64 | sh64le \ - | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ - | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ - | spu \ - | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ - | ubicom32 \ - | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ - | we32k \ - | x86 | xc16x | xstormy16 | xtensa \ - | z8k | z80) - basic_machine=$basic_machine-unknown - ;; - c54x) - basic_machine=tic54x-unknown - ;; - c55x) - basic_machine=tic55x-unknown - ;; - c6x) - basic_machine=tic6x-unknown - ;; - m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip) - basic_machine=$basic_machine-unknown - os=-none - ;; - m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) - ;; - ms1) - basic_machine=mt-unknown - ;; - - strongarm | thumb | xscale) - basic_machine=arm-unknown - ;; - xgate) - basic_machine=$basic_machine-unknown - os=-none + # Here we handle the default manufacturer of certain CPU types. It is in + # some cases the only manufacturer, in others, it is the most popular. + w89k) + cpu=hppa1.1 + vendor=winbond ;; - xscaleeb) - basic_machine=armeb-unknown + op50n) + cpu=hppa1.1 + vendor=oki ;; - - xscaleel) - basic_machine=armel-unknown + op60c) + cpu=hppa1.1 + vendor=oki ;; - - # We use `pc' rather than `unknown' - # because (1) that's what they normally are, and - # (2) the word "unknown" tends to confuse beginning users. - i*86 | x86_64) - basic_machine=$basic_machine-pc - ;; - # Object if more than one company name word. - *-*-*) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 - exit 1 + ibm*) + cpu=i370 + vendor=ibm + ;; + orion105) + cpu=clipper + vendor=highlevel ;; - # Recognize the basic CPU types with company name. - 580-* \ - | a29k-* \ - | aarch64-* | aarch64_be-* \ - | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ - | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ - | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ - | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ - | avr-* | avr32-* \ - | be32-* | be64-* \ - | bfin-* | bs2000-* \ - | c[123]* | c30-* | [cjt]90-* | c4x-* \ - | clipper-* | craynv-* | cydra-* \ - | d10v-* | d30v-* | dlx-* \ - | elxsi-* \ - | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ - | h8300-* | h8500-* \ - | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ - | hexagon-* \ - | i*86-* | i860-* | i960-* | ia64-* \ - | ip2k-* | iq2000-* \ - | le32-* | le64-* \ - | lm32-* \ - | m32c-* | m32r-* | m32rle-* \ - | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ - | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \ - | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ - | mips16-* \ - | mips64-* | mips64el-* \ - | mips64octeon-* | mips64octeonel-* \ - | mips64orion-* | mips64orionel-* \ - | mips64r5900-* | mips64r5900el-* \ - | mips64vr-* | mips64vrel-* \ - | mips64vr4100-* | mips64vr4100el-* \ - | mips64vr4300-* | mips64vr4300el-* \ - | mips64vr5000-* | mips64vr5000el-* \ - | mips64vr5900-* | mips64vr5900el-* \ - | mipsisa32-* | mipsisa32el-* \ - | mipsisa32r2-* | mipsisa32r2el-* \ - | mipsisa64-* | mipsisa64el-* \ - | mipsisa64r2-* | mipsisa64r2el-* \ - | mipsisa64sb1-* | mipsisa64sb1el-* \ - | mipsisa64sr71k-* | mipsisa64sr71kel-* \ - | mipstx39-* | mipstx39el-* \ - | mmix-* \ - | mt-* \ - | msp430-* \ - | nds32-* | nds32le-* | nds32be-* \ - | nios-* | nios2-* \ - | none-* | np1-* | ns16k-* | ns32k-* \ - | open8-* \ - | orion-* \ - | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ - | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ - | pyramid-* \ - | rl78-* | romp-* | rs6000-* | rx-* \ - | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ - | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ - | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ - | sparclite-* \ - | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ - | tahoe-* \ - | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ - | tile*-* \ - | tron-* \ - | ubicom32-* \ - | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ - | vax-* \ - | we32k-* \ - | x86-* | x86_64-* | xc16x-* | xps100-* \ - | xstormy16-* | xtensa*-* \ - | ymp-* \ - | z8k-* | z80-*) - ;; - # Recognize the basic CPU types without company name, with glob match. - xtensa*) - basic_machine=$basic_machine-unknown + mac | mpw | mac-mpw) + cpu=m68k + vendor=apple ;; + pmac | pmac-mpw) + cpu=powerpc + vendor=apple + ;; + # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. - 386bsd) - basic_machine=i386-unknown - os=-bsd - ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) - basic_machine=m68000-att + cpu=m68000 + vendor=att ;; 3b*) - basic_machine=we32k-att - ;; - a29khif) - basic_machine=a29k-amd - os=-udi - ;; - abacus) - basic_machine=abacus-unknown - ;; - adobe68k) - basic_machine=m68010-adobe - os=-scout - ;; - alliant | fx80) - basic_machine=fx80-alliant - ;; - altos | altos3068) - basic_machine=m68k-altos - ;; - am29k) - basic_machine=a29k-none - os=-bsd - ;; - amd64) - basic_machine=x86_64-pc - ;; - amd64-*) - basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - amdahl) - basic_machine=580-amdahl - os=-sysv - ;; - amiga | amiga-*) - basic_machine=m68k-unknown - ;; - amigaos | amigados) - basic_machine=m68k-unknown - os=-amigaos - ;; - amigaunix | amix) - basic_machine=m68k-unknown - os=-sysv4 - ;; - apollo68) - basic_machine=m68k-apollo - os=-sysv - ;; - apollo68bsd) - basic_machine=m68k-apollo - os=-bsd - ;; - aros) - basic_machine=i386-pc - os=-aros - ;; - aux) - basic_machine=m68k-apple - os=-aux - ;; - balance) - basic_machine=ns32k-sequent - os=-dynix - ;; - blackfin) - basic_machine=bfin-unknown - os=-linux - ;; - blackfin-*) - basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` - os=-linux + cpu=we32k + vendor=att ;; bluegene*) - basic_machine=powerpc-ibm - os=-cnk - ;; - c54x-*) - basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - c55x-*) - basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - c6x-*) - basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - c90) - basic_machine=c90-cray - os=-unicos - ;; - cegcc) - basic_machine=arm-unknown - os=-cegcc - ;; - convex-c1) - basic_machine=c1-convex - os=-bsd - ;; - convex-c2) - basic_machine=c2-convex - os=-bsd - ;; - convex-c32) - basic_machine=c32-convex - os=-bsd - ;; - convex-c34) - basic_machine=c34-convex - os=-bsd - ;; - convex-c38) - basic_machine=c38-convex - os=-bsd - ;; - cray | j90) - basic_machine=j90-cray - os=-unicos - ;; - craynv) - basic_machine=craynv-cray - os=-unicosmp - ;; - cr16 | cr16-*) - basic_machine=cr16-unknown - os=-elf - ;; - crds | unos) - basic_machine=m68k-crds - ;; - crisv32 | crisv32-* | etraxfs*) - basic_machine=crisv32-axis - ;; - cris | cris-* | etrax*) - basic_machine=cris-axis - ;; - crx) - basic_machine=crx-unknown - os=-elf - ;; - da30 | da30-*) - basic_machine=m68k-da30 - ;; - decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) - basic_machine=mips-dec + cpu=powerpc + vendor=ibm + os=cnk ;; decsystem10* | dec10*) - basic_machine=pdp10-dec - os=-tops10 + cpu=pdp10 + vendor=dec + os=tops10 ;; decsystem20* | dec20*) - basic_machine=pdp10-dec - os=-tops20 + cpu=pdp10 + vendor=dec + os=tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) - basic_machine=m68k-motorola - ;; - delta88) - basic_machine=m88k-motorola - os=-sysv3 - ;; - dicos) - basic_machine=i686-pc - os=-dicos - ;; - djgpp) - basic_machine=i586-pc - os=-msdosdjgpp - ;; - dpx20 | dpx20-*) - basic_machine=rs6000-bull - os=-bosx - ;; - dpx2* | dpx2*-bull) - basic_machine=m68k-bull - os=-sysv3 - ;; - ebmon29k) - basic_machine=a29k-amd - os=-ebmon + cpu=m68k + vendor=motorola ;; - elxsi) - basic_machine=elxsi-elxsi - os=-bsd + dpx2*) + cpu=m68k + vendor=bull + os=sysv3 ;; encore | umax | mmax) - basic_machine=ns32k-encore + cpu=ns32k + vendor=encore ;; - es1800 | OSE68k | ose68k | ose | OSE) - basic_machine=m68k-ericsson - os=-ose + elxsi) + cpu=elxsi + vendor=elxsi + os=${os:-bsd} ;; fx2800) - basic_machine=i860-alliant + cpu=i860 + vendor=alliant ;; genix) - basic_machine=ns32k-ns - ;; - gmicro) - basic_machine=tron-gmicro - os=-sysv - ;; - go32) - basic_machine=i386-pc - os=-go32 + cpu=ns32k + vendor=ns ;; h3050r* | hiux*) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - h8300hms) - basic_machine=h8300-hitachi - os=-hms - ;; - h8300xray) - basic_machine=h8300-hitachi - os=-xray - ;; - h8500hms) - basic_machine=h8500-hitachi - os=-hms - ;; - harris) - basic_machine=m88k-harris - os=-sysv3 - ;; - hp300-*) - basic_machine=m68k-hp - ;; - hp300bsd) - basic_machine=m68k-hp - os=-bsd - ;; - hp300hpux) - basic_machine=m68k-hp - os=-hpux + cpu=hppa1.1 + vendor=hitachi + os=hiuxwe2 ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) - basic_machine=hppa1.0-hp + cpu=hppa1.0 + vendor=hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) - basic_machine=m68000-hp + cpu=m68000 + vendor=hp ;; hp9k3[2-9][0-9]) - basic_machine=m68k-hp + cpu=m68k + vendor=hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) - basic_machine=hppa1.0-hp + cpu=hppa1.0 + vendor=hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) - basic_machine=hppa1.1-hp + cpu=hppa1.1 + vendor=hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp + cpu=hppa1.1 + vendor=hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp + cpu=hppa1.1 + vendor=hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) - basic_machine=hppa1.1-hp + cpu=hppa1.1 + vendor=hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hppa-next) - os=-nextstep3 - ;; - hppaosf) - basic_machine=hppa1.1-hp - os=-osf - ;; - hppro) - basic_machine=hppa1.1-hp - os=-proelf - ;; - i370-ibm* | ibm*) - basic_machine=i370-ibm + cpu=hppa1.0 + vendor=hp ;; i*86v32) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv32 + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + os=sysv32 ;; i*86v4*) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv4 + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + os=sysv4 ;; i*86v) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + os=sysv ;; i*86sol2) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-solaris2 - ;; - i386mach) - basic_machine=i386-mach - os=-mach - ;; - i386-vsta | vsta) - basic_machine=i386-unknown - os=-vsta + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + os=solaris2 + ;; + j90 | j90-cray) + cpu=j90 + vendor=cray + os=${os:-unicos} ;; iris | iris4d) - basic_machine=mips-sgi + cpu=mips + vendor=sgi case $os in - -irix*) + irix*) ;; *) - os=-irix4 + os=irix4 ;; esac ;; - isi68 | isi) - basic_machine=m68k-isi - os=-sysv - ;; - m68knommu) - basic_machine=m68k-unknown - os=-linux - ;; - m68knommu-*) - basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` - os=-linux - ;; - m88k-omron*) - basic_machine=m88k-omron - ;; - magnum | m3230) - basic_machine=mips-mips - os=-sysv - ;; - merlin) - basic_machine=ns32k-utek - os=-sysv - ;; - microblaze) - basic_machine=microblaze-xilinx - ;; - mingw32) - basic_machine=i386-pc - os=-mingw32 - ;; - mingw32ce) - basic_machine=arm-unknown - os=-mingw32ce - ;; miniframe) - basic_machine=m68000-convergent + cpu=m68000 + vendor=convergent ;; - *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) - basic_machine=m68k-atari - os=-mint - ;; - mips3*-*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` - ;; - mips3*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown - ;; - monitor) - basic_machine=m68k-rom68k - os=-coff - ;; - morphos) - basic_machine=powerpc-unknown - os=-morphos - ;; - msdos) - basic_machine=i386-pc - os=-msdos - ;; - ms1-*) - basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` - ;; - msys) - basic_machine=i386-pc - os=-msys - ;; - mvs) - basic_machine=i370-ibm - os=-mvs - ;; - nacl) - basic_machine=le32-unknown - os=-nacl - ;; - ncr3000) - basic_machine=i486-ncr - os=-sysv4 - ;; - netbsd386) - basic_machine=i386-unknown - os=-netbsd - ;; - netwinder) - basic_machine=armv4l-rebel - os=-linux - ;; - news | news700 | news800 | news900) - basic_machine=m68k-sony - os=-newsos - ;; - news1000) - basic_machine=m68030-sony - os=-newsos + *mint | mint[0-9]* | *MiNT | *MiNT[0-9]*) + cpu=m68k + vendor=atari + os=mint ;; news-3600 | risc-news) - basic_machine=mips-sony - os=-newsos - ;; - necv70) - basic_machine=v70-nec - os=-sysv - ;; - next | m*-next ) - basic_machine=m68k-next + cpu=mips + vendor=sony + os=newsos + ;; + next | m*-next) + cpu=m68k + vendor=next case $os in - -nextstep* ) + openstep*) + ;; + nextstep*) ;; - -ns2*) - os=-nextstep2 + ns2*) + os=nextstep2 ;; *) - os=-nextstep3 + os=nextstep3 ;; esac ;; - nh3000) - basic_machine=m68k-harris - os=-cxux - ;; - nh[45]000) - basic_machine=m88k-harris - os=-cxux - ;; - nindy960) - basic_machine=i960-intel - os=-nindy - ;; - mon960) - basic_machine=i960-intel - os=-mon960 - ;; - nonstopux) - basic_machine=mips-compaq - os=-nonstopux - ;; np1) - basic_machine=np1-gould - ;; - neo-tandem) - basic_machine=neo-tandem - ;; - nse-tandem) - basic_machine=nse-tandem - ;; - nsr-tandem) - basic_machine=nsr-tandem + cpu=np1 + vendor=gould ;; op50n-* | op60c-*) - basic_machine=hppa1.1-oki - os=-proelf - ;; - openrisc | openrisc-*) - basic_machine=or32-unknown - ;; - os400) - basic_machine=powerpc-ibm - os=-os400 - ;; - OSE68000 | ose68000) - basic_machine=m68000-ericsson - os=-ose - ;; - os68k) - basic_machine=m68k-none - os=-os68k + cpu=hppa1.1 + vendor=oki + os=proelf ;; pa-hitachi) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - paragon) - basic_machine=i860-intel - os=-osf - ;; - parisc) - basic_machine=hppa-unknown - os=-linux - ;; - parisc-*) - basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` - os=-linux + cpu=hppa1.1 + vendor=hitachi + os=hiuxwe2 ;; pbd) - basic_machine=sparc-tti + cpu=sparc + vendor=tti ;; pbb) - basic_machine=m68k-tti + cpu=m68k + vendor=tti ;; - pc532 | pc532-*) - basic_machine=ns32k-pc532 - ;; - pc98) - basic_machine=i386-pc - ;; - pc98-*) - basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentium | p5 | k5 | k6 | nexgen | viac3) - basic_machine=i586-pc - ;; - pentiumpro | p6 | 6x86 | athlon | athlon_*) - basic_machine=i686-pc - ;; - pentiumii | pentium2 | pentiumiii | pentium3) - basic_machine=i686-pc - ;; - pentium4) - basic_machine=i786-pc - ;; - pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) - basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumpro-* | p6-* | 6x86-* | athlon-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentium4-*) - basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + pc532) + cpu=ns32k + vendor=pc532 ;; pn) - basic_machine=pn-gould - ;; - power) basic_machine=power-ibm - ;; - ppc | ppcbe) basic_machine=powerpc-unknown - ;; - ppc-* | ppcbe-*) - basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + cpu=pn + vendor=gould ;; - ppcle | powerpclittle | ppc-le | powerpc-little) - basic_machine=powerpcle-unknown - ;; - ppcle-* | powerpclittle-*) - basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppc64) basic_machine=powerpc64-unknown - ;; - ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppc64le | powerpc64little | ppc64-le | powerpc64-little) - basic_machine=powerpc64le-unknown - ;; - ppc64le-* | powerpc64little-*) - basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + power) + cpu=power + vendor=ibm ;; ps2) - basic_machine=i386-ibm - ;; - pw32) - basic_machine=i586-unknown - os=-pw32 - ;; - rdos) - basic_machine=i386-pc - os=-rdos - ;; - rom68k) - basic_machine=m68k-rom68k - os=-coff + cpu=i386 + vendor=ibm ;; rm[46]00) - basic_machine=mips-siemens + cpu=mips + vendor=siemens ;; rtpc | rtpc-*) - basic_machine=romp-ibm + cpu=romp + vendor=ibm ;; - s390 | s390-*) - basic_machine=s390-ibm + sde) + cpu=mipsisa32 + vendor=sde + os=${os:-elf} + ;; + simso-wrs) + cpu=sparclite + vendor=wrs + os=vxworks ;; - s390x | s390x-*) - basic_machine=s390x-ibm + tower | tower-32) + cpu=m68k + vendor=ncr ;; - sa29200) - basic_machine=a29k-amd - os=-udi + vpp*|vx|vx-*) + cpu=f301 + vendor=fujitsu ;; - sb1) - basic_machine=mipsisa64sb1-unknown + w65) + cpu=w65 + vendor=wdc ;; - sb1el) - basic_machine=mipsisa64sb1el-unknown + w89k-*) + cpu=hppa1.1 + vendor=winbond + os=proelf ;; - sde) - basic_machine=mipsisa32-sde - os=-elf + none) + cpu=none + vendor=none ;; - sei) - basic_machine=mips-sei - os=-seiux + leon|leon[3-9]) + cpu=sparc + vendor=$basic_machine + ;; + leon-*|leon[3-9]-*) + cpu=sparc + vendor=`echo "$basic_machine" | sed 's/-.*//'` + ;; + + *-*) + # shellcheck disable=SC2162 + IFS="-" read cpu vendor <&2 - exit 1 + # Recognize the canonical CPU types that are allowed with any + # company name. + case $cpu in + 1750a | 580 \ + | a29k \ + | aarch64 | aarch64_be \ + | abacus \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] \ + | alphapca5[67] | alpha64pca5[67] \ + | am33_2.0 \ + | amdgcn \ + | arc | arceb \ + | arm | arm[lb]e | arme[lb] | armv* \ + | avr | avr32 \ + | asmjs \ + | ba \ + | be32 | be64 \ + | bfin | bpf | bs2000 \ + | c[123]* | c30 | [cjt]90 | c4x \ + | c8051 | clipper | craynv | csky | cydra \ + | d10v | d30v | dlx | dsp16xx \ + | e2k | elxsi | epiphany \ + | f30[01] | f700 | fido | fr30 | frv | ft32 | fx80 \ + | h8300 | h8500 \ + | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | hexagon \ + | i370 | i*86 | i860 | i960 | ia16 | ia64 \ + | ip2k | iq2000 \ + | k1om \ + | le32 | le64 \ + | lm32 \ + | m32c | m32r | m32rle \ + | m5200 | m68000 | m680[012346]0 | m68360 | m683?2 | m68k \ + | m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x \ + | m88110 | m88k | maxq | mb | mcore | mep | metag \ + | microblaze | microblazeel \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64eb | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa32r6 | mipsisa32r6el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64r6 | mipsisa64r6el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipsr5900 | mipsr5900el \ + | mipstx39 | mipstx39el \ + | mmix \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nds32 | nds32le | nds32be \ + | nfp \ + | nios | nios2 | nios2eb | nios2el \ + | none | np1 | ns16k | ns32k | nvptx \ + | open8 \ + | or1k* \ + | or32 \ + | orion \ + | picochip \ + | pdp10 | pdp11 | pj | pjl | pn | power \ + | powerpc | powerpc64 | powerpc64le | powerpcle | powerpcspe \ + | pru \ + | pyramid \ + | riscv | riscv32 | riscv64 \ + | rl78 | romp | rs6000 | rx \ + | score \ + | sh | shl \ + | sh[1234] | sh[24]a | sh[24]ae[lb] | sh[23]e | she[lb] | sh[lb]e \ + | sh[1234]e[lb] | sh[12345][lb]e | sh[23]ele | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet \ + | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v | sv1 | sx* \ + | spu \ + | tahoe \ + | tic30 | tic4x | tic54x | tic55x | tic6x | tic80 \ + | tron \ + | ubicom32 \ + | v70 | v850 | v850e | v850e1 | v850es | v850e2 | v850e2v3 \ + | vax \ + | visium \ + | w65 \ + | wasm32 | wasm64 \ + | we32k \ + | x86 | x86_64 | xc16x | xgate | xps100 \ + | xstormy16 | xtensa* \ + | ymp \ + | z8k | z80) + ;; + + *) + echo Invalid configuration \`"$1"\': machine \`"$cpu-$vendor"\' not recognized 1>&2 + exit 1 + ;; + esac ;; esac # Here we canonicalize certain aliases for manufacturers. -case $basic_machine in - *-digital*) - basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` +case $vendor in + digital*) + vendor=dec ;; - *-commodore*) - basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + commodore*) + vendor=cbm ;; *) ;; @@ -1309,200 +1275,244 @@ # Decode manufacturer-specific aliases for certain operating systems. -if [ x"$os" != x"" ] +if [ x$os != x ] then case $os in - # First match some system type aliases - # that might get confused with valid system types. - # -solaris* is a basic system type, with this one exception. - -auroraux) - os=-auroraux + # First match some system type aliases that might get confused + # with valid system types. + # solaris* is a basic system type, with this one exception. + auroraux) + os=auroraux ;; - -solaris1 | -solaris1.*) - os=`echo $os | sed -e 's|solaris1|sunos4|'` + bluegene*) + os=cnk ;; - -solaris) - os=-solaris2 + solaris1 | solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; - -svr4*) - os=-sysv4 + solaris) + os=solaris2 ;; - -unixware*) - os=-sysv4.2uw + unixware*) + os=sysv4.2uw ;; - -gnu/linux*) + gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; - # First accept the basic system types. + # es1800 is here to avoid being matched by es* (a different OS) + es1800*) + os=ose + ;; + # Some version numbers need modification + chorusos*) + os=chorusos + ;; + isc) + os=isc2.2 + ;; + sco6) + os=sco5v6 + ;; + sco5) + os=sco3.2v5 + ;; + sco4) + os=sco3.2v4 + ;; + sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + ;; + sco3.2v[4-9]* | sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + ;; + scout) + # Don't match below + ;; + sco*) + os=sco3.2v2 + ;; + psos*) + os=psos + ;; + # Now accept the basic system types. # The portable systems comes first. - # Each alternative MUST END IN A *, to match a version number. - # -sysv* is not here because it comes later, after sysvr4. - -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ - | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ - | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ - | -sym* | -kopensolaris* \ - | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ - | -aos* | -aros* \ - | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ - | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ - | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ - | -openbsd* | -solidbsd* \ - | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ - | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ - | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ - | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ - | -chorusos* | -chorusrdb* | -cegcc* \ - | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ - | -mingw32* | -linux-gnu* | -linux-android* \ - | -linux-newlib* | -linux-uclibc* \ - | -uxpv* | -beos* | -mpeix* | -udk* \ - | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ - | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ - | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ - | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ - | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ - | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ - | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) + # Each alternative MUST end in a * to match a version number. + # sysv* is not here because it comes later, after sysvr4. + gnu* | bsd* | mach* | minix* | genix* | ultrix* | irix* \ + | *vms* | esix* | aix* | cnk* | sunos | sunos[34]*\ + | hpux* | unos* | osf* | luna* | dgux* | auroraux* | solaris* \ + | sym* | kopensolaris* | plan9* \ + | amigaos* | amigados* | msdos* | newsos* | unicos* | aof* \ + | aos* | aros* | cloudabi* | sortix* | twizzler* \ + | nindy* | vxsim* | vxworks* | ebmon* | hms* | mvs* \ + | clix* | riscos* | uniplus* | iris* | isc* | rtu* | xenix* \ + | knetbsd* | mirbsd* | netbsd* \ + | bitrig* | openbsd* | solidbsd* | libertybsd* | os108* \ + | ekkobsd* | kfreebsd* | freebsd* | riscix* | lynxos* \ + | bosx* | nextstep* | cxux* | aout* | elf* | oabi* \ + | ptx* | coff* | ecoff* | winnt* | domain* | vsta* \ + | udi* | eabi* | lites* | ieee* | go32* | aux* | hcos* \ + | chorusrdb* | cegcc* | glidix* \ + | cygwin* | msys* | pe* | moss* | proelf* | rtems* \ + | midipix* | mingw32* | mingw64* | linux-gnu* | linux-android* \ + | linux-newlib* | linux-musl* | linux-uclibc* \ + | uxpv* | beos* | mpeix* | udk* | moxiebox* \ + | interix* | uwin* | mks* | rhapsody* | darwin* \ + | openstep* | oskit* | conix* | pw32* | nonstopux* \ + | storm-chaos* | tops10* | tenex* | tops20* | its* \ + | os2* | vos* | palmos* | uclinux* | nucleus* \ + | morphos* | superux* | rtmk* | windiss* \ + | powermax* | dnix* | nx6 | nx7 | sei* | dragonfly* \ + | skyos* | haiku* | rdos* | toppers* | drops* | es* \ + | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \ + | midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \ + | nsk* | powerunix) # Remember, each alternative MUST END IN *, to match a version number. ;; - -qnx*) - case $basic_machine in - x86-* | i*86-*) + qnx*) + case $cpu in + x86 | i*86) ;; *) - os=-nto$os + os=nto-$os ;; esac ;; - -nto-qnx*) + hiux*) + os=hiuxwe2 ;; - -nto*) - os=`echo $os | sed -e 's|nto|nto-qnx|'` + nto-qnx*) ;; - -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ - | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ - | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; - -mac*) - os=`echo $os | sed -e 's|mac|macos|'` + sim | xray | os68k* | v88r* \ + | windows* | osx | abug | netware* | os9* \ + | macos* | mpw* | magic* | mmixware* | mon960* | lnews*) ;; - -linux-dietlibc) - os=-linux-dietlibc + linux-dietlibc) + os=linux-dietlibc ;; - -linux*) + linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; - -sunos5*) - os=`echo $os | sed -e 's|sunos5|solaris2|'` + lynx*178) + os=lynxos178 ;; - -sunos6*) - os=`echo $os | sed -e 's|sunos6|solaris3|'` + lynx*5) + os=lynxos5 ;; - -opened*) - os=-openedition + lynx*) + os=lynxos ;; - -os400*) - os=-os400 + mac*) + os=`echo "$os" | sed -e 's|mac|macos|'` ;; - -wince*) - os=-wince + opened*) + os=openedition ;; - -osfrose*) - os=-osfrose + os400*) + os=os400 ;; - -osf*) - os=-osf + sunos5*) + os=`echo "$os" | sed -e 's|sunos5|solaris2|'` ;; - -utek*) - os=-bsd + sunos6*) + os=`echo "$os" | sed -e 's|sunos6|solaris3|'` ;; - -dynix*) - os=-bsd + wince*) + os=wince ;; - -acis*) - os=-aos + utek*) + os=bsd ;; - -atheos*) - os=-atheos + dynix*) + os=bsd ;; - -syllable*) - os=-syllable + acis*) + os=aos ;; - -386bsd) - os=-bsd + atheos*) + os=atheos ;; - -ctix* | -uts*) - os=-sysv + syllable*) + os=syllable + ;; + 386bsd) + os=bsd ;; - -nova*) - os=-rtmk-nova + ctix* | uts*) + os=sysv ;; - -ns2 ) - os=-nextstep2 + nova*) + os=rtmk-nova ;; - -nsk*) - os=-nsk + ns2) + os=nextstep2 ;; # Preserve the version number of sinix5. - -sinix5.*) + sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; - -sinix*) - os=-sysv4 + sinix*) + os=sysv4 ;; - -tpf*) - os=-tpf + tpf*) + os=tpf ;; - -triton*) - os=-sysv3 + triton*) + os=sysv3 ;; - -oss*) - os=-sysv3 + oss*) + os=sysv3 ;; - -svr4) - os=-sysv4 + svr4*) + os=sysv4 ;; - -svr3) - os=-sysv3 + svr3) + os=sysv3 ;; - -sysvr4) - os=-sysv4 + sysvr4) + os=sysv4 ;; - # This must come after -sysvr4. - -sysv*) + # This must come after sysvr4. + sysv*) ;; - -ose*) - os=-ose + ose*) + os=ose ;; - -es1800*) - os=-ose + *mint | mint[0-9]* | *MiNT | MiNT[0-9]*) + os=mint ;; - -xenix) - os=-xenix + zvmoe) + os=zvmoe ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) - os=-mint + dicos*) + os=dicos ;; - -aros*) - os=-aros - ;; - -kaos*) - os=-kaos + pikeos*) + # Until real need of OS specific support for + # particular features comes up, bare metal + # configurations are quite functional. + case $cpu in + arm*) + os=eabi + ;; + *) + os=elf + ;; + esac ;; - -zvmoe) - os=-zvmoe + nacl*) ;; - -dicos*) - os=-dicos + ios) ;; - -nacl*) + none) ;; - -none) + *-eabi) ;; *) - # Get rid of the `-' at the beginning of $os. - os=`echo $os | sed 's/[^-]*-//'` - echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + echo Invalid configuration \`"$1"\': system \`"$os"\' not recognized 1>&2 exit 1 ;; esac @@ -1518,255 +1528,265 @@ # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. -case $basic_machine in +case $cpu-$vendor in score-*) - os=-elf + os=elf ;; spu-*) - os=-elf + os=elf ;; *-acorn) - os=-riscix1.2 + os=riscix1.2 ;; arm*-rebel) - os=-linux + os=linux ;; arm*-semi) - os=-aout + os=aout ;; c4x-* | tic4x-*) - os=-coff + os=coff + ;; + c8051-*) + os=elf + ;; + clipper-intergraph) + os=clix + ;; + hexagon-*) + os=elf ;; tic54x-*) - os=-coff + os=coff ;; tic55x-*) - os=-coff + os=coff ;; tic6x-*) - os=-coff + os=coff ;; # This must come before the *-dec entry. pdp10-*) - os=-tops20 + os=tops20 ;; pdp11-*) - os=-none + os=none ;; *-dec | vax-*) - os=-ultrix4.2 + os=ultrix4.2 ;; m68*-apollo) - os=-domain + os=domain ;; i386-sun) - os=-sunos4.0.2 + os=sunos4.0.2 ;; m68000-sun) - os=-sunos3 + os=sunos3 ;; m68*-cisco) - os=-aout + os=aout ;; mep-*) - os=-elf + os=elf ;; mips*-cisco) - os=-elf + os=elf ;; mips*-*) - os=-elf + os=elf ;; or32-*) - os=-coff + os=coff ;; *-tti) # must be before sparc entry or we get the wrong os. - os=-sysv3 + os=sysv3 ;; sparc-* | *-sun) - os=-sunos4.1.1 + os=sunos4.1.1 ;; - *-be) - os=-beos + pru-*) + os=elf ;; - *-haiku) - os=-haiku + *-be) + os=beos ;; *-ibm) - os=-aix + os=aix ;; *-knuth) - os=-mmixware + os=mmixware ;; *-wec) - os=-proelf + os=proelf ;; *-winbond) - os=-proelf + os=proelf ;; *-oki) - os=-proelf + os=proelf ;; *-hp) - os=-hpux + os=hpux ;; *-hitachi) - os=-hiux + os=hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) - os=-sysv + os=sysv ;; *-cbm) - os=-amigaos + os=amigaos ;; *-dg) - os=-dgux + os=dgux ;; *-dolphin) - os=-sysv3 + os=sysv3 ;; m68k-ccur) - os=-rtu + os=rtu ;; m88k-omron*) - os=-luna + os=luna ;; - *-next ) - os=-nextstep + *-next) + os=nextstep ;; *-sequent) - os=-ptx + os=ptx ;; *-crds) - os=-unos + os=unos ;; *-ns) - os=-genix + os=genix ;; i370-*) - os=-mvs - ;; - *-next) - os=-nextstep3 + os=mvs ;; *-gould) - os=-sysv + os=sysv ;; *-highlevel) - os=-bsd + os=bsd ;; *-encore) - os=-bsd + os=bsd ;; *-sgi) - os=-irix + os=irix ;; *-siemens) - os=-sysv4 + os=sysv4 ;; *-masscomp) - os=-rtu + os=rtu ;; f30[01]-fujitsu | f700-fujitsu) - os=-uxpv + os=uxpv ;; *-rom68k) - os=-coff + os=coff ;; *-*bug) - os=-coff + os=coff ;; *-apple) - os=-macos + os=macos ;; *-atari*) - os=-mint + os=mint + ;; + *-wrs) + os=vxworks ;; *) - os=-none + os=none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. -vendor=unknown -case $basic_machine in - *-unknown) +case $vendor in + unknown) case $os in - -riscix*) + riscix*) vendor=acorn ;; - -sunos*) + sunos*) vendor=sun ;; - -cnk*|-aix*) + cnk*|-aix*) vendor=ibm ;; - -beos*) + beos*) vendor=be ;; - -hpux*) + hpux*) vendor=hp ;; - -mpeix*) + mpeix*) vendor=hp ;; - -hiux*) + hiux*) vendor=hitachi ;; - -unos*) + unos*) vendor=crds ;; - -dgux*) + dgux*) vendor=dg ;; - -luna*) + luna*) vendor=omron ;; - -genix*) + genix*) vendor=ns ;; - -mvs* | -opened*) + clix*) + vendor=intergraph + ;; + mvs* | opened*) vendor=ibm ;; - -os400*) + os400*) vendor=ibm ;; - -ptx*) + ptx*) vendor=sequent ;; - -tpf*) + tpf*) vendor=ibm ;; - -vxsim* | -vxworks* | -windiss*) + vxsim* | vxworks* | windiss*) vendor=wrs ;; - -aux*) + aux*) vendor=apple ;; - -hms*) + hms*) vendor=hitachi ;; - -mpw* | -macos*) + mpw* | macos*) vendor=apple ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + *mint | mint[0-9]* | *MiNT | MiNT[0-9]*) vendor=atari ;; - -vos*) + vos*) vendor=stratus ;; esac - basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac -echo $basic_machine$os +echo "$cpu-$vendor-$os" exit # Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" diff -Nru qpdf-8.0.2/configure qpdf-10.0.1/configure --- qpdf-8.0.2/configure 2018-03-06 16:46:16.000000000 +0000 +++ qpdf-10.0.1/configure 2020-04-09 15:48:26.000000000 +0000 @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for qpdf 8.0.2. +# Generated by GNU Autoconf 2.69 for qpdf 10.0.1. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. @@ -587,8 +587,8 @@ # Identity of this package. PACKAGE_NAME='qpdf' PACKAGE_TARNAME='qpdf' -PACKAGE_VERSION='8.0.2' -PACKAGE_STRING='qpdf 8.0.2' +PACKAGE_VERSION='10.0.1' +PACKAGE_STRING='qpdf 10.0.1' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -630,6 +630,7 @@ ac_subst_vars='LTLIBOBJS LIBOBJS +OSS_FUZZ VALIDATE_DOC BUILD_PDF BUILD_HTML @@ -641,13 +642,33 @@ DOCBOOK_XHTML SHOW_FAILED_TEST_OUTPUT QPDF_SKIP_TEST_COMPARE_IMAGES +DEFAULT_CRYPTO +USE_CRYPTO_GNUTLS +pc_gnutls_LIBS +pc_gnutls_CFLAGS +USE_CRYPTO_OPENSSL +pc_openssl_LIBS +pc_openssl_CFLAGS +USE_CRYPTO_NATIVE +WINDOWS_MAIN_XLINK_FLAGS +WINDOWS_WMAIN_XLINK_FLAGS CXXWFLAGS WFLAGS BUILDRULES GENDEPS HAVE_LD_VERSION_SCRIPT QPDF_LARGE_FILE_TEST_PATH +WINDOWS_WMAIN_LINK +WINDOWS_WMAIN_COMPILE +pc_libjpeg_LIBS +pc_libjpeg_CFLAGS +pc_zlib_LIBS +pc_zlib_CFLAGS +PKG_CONFIG_LIBDIR +PKG_CONFIG_PATH +PKG_CONFIG WINDOWS_WORDSIZE +IS_32BIT RANDOM_DEVICE LT_SONAME LT_AGE @@ -688,6 +709,7 @@ EGREP GREP CPP +HAVE_CXX11 ac_ct_CXX CXXFLAGS CXX @@ -698,6 +720,10 @@ LDFLAGS CFLAGS CC +SHA256SUM +ACLOCAL +AUTOHEADER +AUTOCONF target_alias host_alias build_alias @@ -740,6 +766,7 @@ ac_subst_files='' ac_user_opts=' enable_option_checking +enable_check_autofiles enable_shared enable_static with_pic @@ -751,13 +778,19 @@ enable_insecure_random enable_os_secure_random with_random +enable_avoid_windows_handle enable_external_libs -with_windows_wordsize with_large_file_test_path enable_largefile enable_ld_version_script with_buildrules enable_werror +enable_int_warnings +enable_implicit_crypto +enable_crypto_native +enable_crypto_openssl +enable_crypto_gnutls +with_default_crypto enable_test_compare_images enable_show_failed_test_output with_docbook_xsl @@ -766,6 +799,7 @@ enable_html_doc enable_pdf_doc enable_validate_doc +enable_oss_fuzz ' ac_precious_vars='build_alias host_alias @@ -780,7 +814,18 @@ CCC CPP LT_SYS_LIBRARY_PATH -CXXCPP' +CXXCPP +PKG_CONFIG +PKG_CONFIG_PATH +PKG_CONFIG_LIBDIR +pc_zlib_CFLAGS +pc_zlib_LIBS +pc_libjpeg_CFLAGS +pc_libjpeg_LIBS +pc_openssl_CFLAGS +pc_openssl_LIBS +pc_gnutls_CFLAGS +pc_gnutls_LIBS' # Initialize some variables set by options. @@ -1331,7 +1376,7 @@ # 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 8.0.2 to adapt to many kinds of systems. +\`configure' configures qpdf 10.0.1 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1397,7 +1442,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of qpdf 8.0.2:";; + short | recursive ) echo "Configuration of qpdf 10.0.1:";; esac cat <<\_ACEOF @@ -1405,6 +1450,10 @@ --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-check-autofiles + if specified, verify checksums on automatically + generated files (default=yes); package maintainers + may want to disable this --enable-shared[=PKGS] build shared libraries [default=yes] --enable-static[=PKGS] build static libraries [default=yes] --enable-fast-install[=PKGS] @@ -1416,11 +1465,25 @@ --enable-os-secure-random whether to try to use OS-provided secure random numbers (default is yes) + --enable-avoid-windows-handle + whether to avoid use of HANDLE, useful for some + embedded Windows builds (default is no) --enable-external-libs whether to use external libraries distribution --disable-largefile omit support for large files --enable-ld-version-script enable linker version script (default is enabled) --enable-werror whether to treat warnings as errors (default is no) + --enable-int-warnings whether to turn on integer type warnings (default is + yes) + --enable-implicit-crypto + whether to enable available crypto providers that + are not explicitly requested; true by default + --enable-crypto-native whether to include support for native crypto + provider + --enable-crypto-openssl whether to include support for the BoringSSL crypto + provider + --enable-crypto-gnutls whether to include support for gnutls crypto + provider --enable-test-compare-images whether to compare images in test suite; disabled by default, enabling requires ghostscript and tiffcmp @@ -1434,6 +1497,7 @@ --enable-html-doc whether to build HTML documents --enable-pdf-doc whether to build PDF documents --enable-validate-doc whether to validate xml document source + --enable-oss-fuzz if set, build static fuzzers for oss-fuzz Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] @@ -1447,9 +1511,6 @@ --with-sysroot[=DIR] Search for dependent libraries within DIR (or the compiler's sysroot if not specified). --with-random=FILE Use FILE as random number seed [auto-detected] - --with-windows-wordsize={32,64} - Windows only: whether this is a 32-bit or 64-bit - build; required if external-libs are enabled --with-large-file-test-path=path To enable testing of files > 4GB, give the path to a directory with at least 11 GB free. The test suite @@ -1458,6 +1519,9 @@ QPDF_LARGE_FILE_TEST_PATH environment variable to the path before running the test suite. --with-buildrules=rules which build rules to use; see README.md + --with-default-crypto=provider + which crypto provider to use by default; see + README.md --with-docbook-xsl=DIR location of docbook 4.x xml stylesheets --with-docbookx-dtd=FILE location of docbook 4.x xml DTD @@ -1476,6 +1540,27 @@ LT_SYS_LIBRARY_PATH User-defined run-time library search path. CXXCPP C++ preprocessor + PKG_CONFIG path to pkg-config utility + PKG_CONFIG_PATH + directories to add to pkg-config's search path + PKG_CONFIG_LIBDIR + path overriding pkg-config's built-in search path + pc_zlib_CFLAGS + C compiler flags for pc_zlib, overriding pkg-config + pc_zlib_LIBS + linker flags for pc_zlib, overriding pkg-config + pc_libjpeg_CFLAGS + C compiler flags for pc_libjpeg, overriding pkg-config + pc_libjpeg_LIBS + linker flags for pc_libjpeg, overriding pkg-config + pc_openssl_CFLAGS + C compiler flags for pc_openssl, overriding pkg-config + pc_openssl_LIBS + linker flags for pc_openssl, overriding pkg-config + pc_gnutls_CFLAGS + C compiler flags for pc_gnutls, overriding pkg-config + pc_gnutls_LIBS + linker flags for pc_gnutls, overriding pkg-config Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. @@ -1543,7 +1628,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -qpdf configure 8.0.2 +qpdf configure 10.0.1 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1939,6 +2024,189 @@ } # ac_fn_cxx_try_link +# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES +# -------------------------------------------- +# Tries to find the compile-time value of EXPR in a program that includes +# INCLUDES, setting VAR accordingly. Returns whether the value could be +# computed +ac_fn_c_compute_int () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if test "$cross_compiling" = yes; then + # Depending upon the size, compute the lo and hi bounds. +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) >= 0)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_lo=0 ac_mid=0 + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) <= $ac_mid)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_hi=$ac_mid; break +else + as_fn_arith $ac_mid + 1 && ac_lo=$as_val + if test $ac_lo -le $ac_mid; then + ac_lo= ac_hi= + break + fi + as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) < 0)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_hi=-1 ac_mid=-1 + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) >= $ac_mid)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_lo=$ac_mid; break +else + as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val + if test $ac_mid -le $ac_hi; then + ac_lo= ac_hi= + break + fi + as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + ac_lo= ac_hi= +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +# Binary search between lo and hi bounds. +while test "x$ac_lo" != "x$ac_hi"; do + as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) <= $ac_mid)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_hi=$ac_mid +else + as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +done +case $ac_lo in #(( +?*) eval "$3=\$ac_lo"; ac_retval=0 ;; +'') ac_retval=1 ;; +esac + else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +static long int longval () { return $2; } +static unsigned long int ulongval () { return $2; } +#include +#include +int +main () +{ + + FILE *f = fopen ("conftest.val", "w"); + if (! f) + return 1; + if (($2) < 0) + { + long int i = longval (); + if (i != ($2)) + return 1; + fprintf (f, "%ld", i); + } + else + { + unsigned long int i = ulongval (); + if (i != ($2)) + return 1; + fprintf (f, "%lu", i); + } + /* Do not output a trailing newline, as this causes \r\n confusion + on some platforms. */ + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + echo >>conftest.val; read $3 &5 -$as_echo_n "checking for uint$2_t... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - eval "$3=no" - # Order is important - never check a type that is potentially smaller - # than half of the expected target width. - for ac_type in uint$2_t 'unsigned int' 'unsigned long int' \ - 'unsigned long long int' 'unsigned short int' 'unsigned char'; do - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ -static int test_array [1 - 2 * !((($ac_type) -1 >> ($2 / 2 - 1)) >> ($2 / 2 - 1) == 3)]; -test_array [0] = 0; -return test_array [0]; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - case $ac_type in #( - uint$2_t) : - eval "$3=yes" ;; #( - *) : - eval "$3=\$ac_type" ;; -esac -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - if eval test \"x\$"$3"\" = x"no"; then : - -else - break -fi - done -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_find_uintX_t 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 8.0.2, which was +It was created by qpdf $as_me 10.0.1, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2444,21 +2658,29 @@ ac_config_headers="$ac_config_headers libqpdf/qpdf/qpdf-config.h" -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. -set dummy ${ac_tool_prefix}gcc; ac_word=$2 +# Check whether --enable-check-autofiles was given. +if test "${enable_check_autofiles+set}" = set; then : + enableval=$enable_check_autofiles; if test "$enableval" = "no"; then + CHECK_AUTOFILES=0 + else + CHECK_AUTOFILES=1 + fi +else + CHECK_AUTOFILES=1 +fi + + +# Check to see if automatically generated files are outdated and if we +# can update them. +# Extract the first word of "autoconf", so it can be a program name with args. +set dummy autoconf; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : +if ${ac_cv_prog_AUTOCONF+:} false; then : $as_echo_n "(cached) " >&6 else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. + if test -n "$AUTOCONF"; then + ac_cv_prog_AUTOCONF="$AUTOCONF" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH @@ -2467,7 +2689,7 @@ test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="${ac_tool_prefix}gcc" + ac_cv_prog_AUTOCONF="1" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi @@ -2475,30 +2697,28 @@ done IFS=$as_save_IFS + test -z "$ac_cv_prog_AUTOCONF" && ac_cv_prog_AUTOCONF="0" fi fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } +AUTOCONF=$ac_cv_prog_AUTOCONF +if test -n "$AUTOCONF"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AUTOCONF" >&5 +$as_echo "$AUTOCONF" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi -fi -if test -z "$ac_cv_prog_CC"; then - ac_ct_CC=$CC - # Extract the first word of "gcc", so it can be a program name with args. -set dummy gcc; ac_word=$2 +# Extract the first word of "autoheader", so it can be a program name with args. +set dummy autoheader; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_CC+:} false; then : +if ${ac_cv_prog_AUTOHEADER+:} false; then : $as_echo_n "(cached) " >&6 else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. + if test -n "$AUTOHEADER"; then + ac_cv_prog_AUTOHEADER="$AUTOHEADER" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH @@ -2507,7 +2727,7 @@ test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="gcc" + ac_cv_prog_AUTOHEADER="1" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi @@ -2515,43 +2735,28 @@ done IFS=$as_save_IFS + test -z "$ac_cv_prog_AUTOHEADER" && ac_cv_prog_AUTOHEADER="0" fi fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 -$as_echo "$ac_ct_CC" >&6; } +AUTOHEADER=$ac_cv_prog_AUTOHEADER +if test -n "$AUTOHEADER"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AUTOHEADER" >&5 +$as_echo "$AUTOHEADER" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -else - CC="$ac_cv_prog_CC" -fi -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. -set dummy ${ac_tool_prefix}cc; ac_word=$2 +# Extract the first word of "aclocal", so it can be a program name with args. +set dummy aclocal; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : +if ${ac_cv_prog_ACLOCAL+:} false; then : $as_echo_n "(cached) " >&6 else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. + if test -n "$ACLOCAL"; then + ac_cv_prog_ACLOCAL="$ACLOCAL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH @@ -2560,7 +2765,7 @@ test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="${ac_tool_prefix}cc" + ac_cv_prog_ACLOCAL="1" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi @@ -2568,32 +2773,29 @@ done IFS=$as_save_IFS + test -z "$ac_cv_prog_ACLOCAL" && ac_cv_prog_ACLOCAL="0" fi fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } +ACLOCAL=$ac_cv_prog_ACLOCAL +if test -n "$ACLOCAL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ACLOCAL" >&5 +$as_echo "$ACLOCAL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi - fi -fi -if test -z "$CC"; then - # Extract the first word of "cc", so it can be a program name with args. -set dummy cc; ac_word=$2 +# Extract the first word of "sha256sum", so it can be a program name with args. +set dummy sha256sum; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : +if ${ac_cv_prog_SHA256SUM+:} false; then : $as_echo_n "(cached) " >&6 else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. + if test -n "$SHA256SUM"; then + ac_cv_prog_SHA256SUM="$SHA256SUM" # Let the user override the test. else - ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do @@ -2601,11 +2803,7 @@ test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then - ac_prog_rejected=yes - continue - fi - ac_cv_prog_CC="cc" + ac_cv_prog_SHA256SUM="1" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi @@ -2613,35 +2811,223 @@ done IFS=$as_save_IFS -if test $ac_prog_rejected = yes; then - # We found a bogon in the path, so make sure we never use it. - set dummy $ac_cv_prog_CC - shift - if test $# != 0; then - # We chose a different compiler from the bogus one. - # However, it has the same basename, so the bogon will be chosen - # first if we set CC to just the basename; use the full file name. - shift - ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" - fi + test -z "$ac_cv_prog_SHA256SUM" && ac_cv_prog_SHA256SUM="0" fi fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } +SHA256SUM=$ac_cv_prog_SHA256SUM +if test -n "$SHA256SUM"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SHA256SUM" >&5 +$as_echo "$SHA256SUM" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi +if test "$CHECK_AUTOFILES$AUTOCONF$AUTOHEADER$ACLOCAL$SHA256SUM" = "11111"; then + if ! sha256sum -c autofiles.sums; then + as_fn_error $? "autofiles are outdated; rerun autogen.sh" "$LINENO" 5 + fi fi -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - for ac_prog in cl.exe - do + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 @@ -3668,53 +4054,414 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 -$as_echo_n "checking how to run the C preprocessor... " >&6; } -# On Suns, sometimes $CPP names a directory. -if test -n "$CPP" && test -d "$CPP"; then - CPP= -fi -if test -z "$CPP"; then - if ${ac_cv_prog_CPP+:} false; then : + ax_cxx_compile_alternatives="11 0x" ax_cxx_compile_cxx11_required=true + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + ac_success=no + + + + if test x$ac_success = xno; then + for alternative in ${ax_cxx_compile_alternatives}; do + for switch in "" -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do + cachevar=`$as_echo "ax_cv_cxx_compile_cxx11_$switch" | $as_tr_sh` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++11 features with $switch" >&5 +$as_echo_n "checking whether $CXX supports C++11 features with $switch... " >&6; } +if eval \${$cachevar+:} false; then : $as_echo_n "(cached) " >&6 else - # Double quotes because CPP needs to be expanded - for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" - do - ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer to if __STDC__ is defined, since - # exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + ac_save_CXX="$CXX" + CXX="$CXX $switch" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#ifdef __STDC__ -# include + + +// If the compiler admits that it is not ready for C++11, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201103L && ! defined(_MSC_VER) + +#error "This is not a C++11 compiler" + #else -# include -#endif - Syntax error -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : -else - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.i conftest.$ac_ext +namespace cxx11 +{ - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + namespace test_static_assert + { + + template + struct check + { + static_assert(sizeof(int) <= sizeof(T), "not big enough"); + }; + + } + + namespace test_final_override + { + + struct Base + { + virtual ~Base() {} + virtual void f() {} + }; + + struct Derived : public Base + { + virtual ~Derived() override {} + virtual void f() override {} + }; + + } + + namespace test_double_right_angle_brackets + { + + template < typename T > + struct check {}; + + typedef check single_type; + typedef check> double_type; + typedef check>> triple_type; + typedef check>>> quadruple_type; + + } + + namespace test_decltype + { + + int + f() + { + int a = 1; + decltype(a) b = 2; + return a + b; + } + + } + + namespace test_type_deduction + { + + template < typename T1, typename T2 > + struct is_same + { + static const bool value = false; + }; + + template < typename T > + struct is_same + { + static const bool value = true; + }; + + template < typename T1, typename T2 > + auto + add(T1 a1, T2 a2) -> decltype(a1 + a2) + { + return a1 + a2; + } + + int + test(const int c, volatile int v) + { + static_assert(is_same::value == true, ""); + static_assert(is_same::value == false, ""); + static_assert(is_same::value == false, ""); + auto ac = c; + auto av = v; + auto sumi = ac + av + 'x'; + auto sumf = ac + av + 1.0; + static_assert(is_same::value == true, ""); + static_assert(is_same::value == true, ""); + static_assert(is_same::value == true, ""); + static_assert(is_same::value == false, ""); + static_assert(is_same::value == true, ""); + return (sumf > 0.0) ? sumi : add(c, v); + } + + } + + namespace test_noexcept + { + + int f() { return 0; } + int g() noexcept { return 0; } + + static_assert(noexcept(f()) == false, ""); + static_assert(noexcept(g()) == true, ""); + + } + + namespace test_constexpr + { + + template < typename CharT > + unsigned long constexpr + strlen_c_r(const CharT *const s, const unsigned long acc) noexcept + { + return *s ? strlen_c_r(s + 1, acc + 1) : acc; + } + + template < typename CharT > + unsigned long constexpr + strlen_c(const CharT *const s) noexcept + { + return strlen_c_r(s, 0UL); + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("1") == 1UL, ""); + static_assert(strlen_c("example") == 7UL, ""); + static_assert(strlen_c("another\0example") == 7UL, ""); + + } + + namespace test_rvalue_references + { + + template < int N > + struct answer + { + static constexpr int value = N; + }; + + answer<1> f(int&) { return answer<1>(); } + answer<2> f(const int&) { return answer<2>(); } + answer<3> f(int&&) { return answer<3>(); } + + void + test() + { + int i = 0; + const int c = 0; + static_assert(decltype(f(i))::value == 1, ""); + static_assert(decltype(f(c))::value == 2, ""); + static_assert(decltype(f(0))::value == 3, ""); + } + + } + + namespace test_uniform_initialization + { + + struct test + { + static const int zero {}; + static const int one {1}; + }; + + static_assert(test::zero == 0, ""); + static_assert(test::one == 1, ""); + + } + + namespace test_lambdas + { + + void + test1() + { + auto lambda1 = [](){}; + auto lambda2 = lambda1; + lambda1(); + lambda2(); + } + + int + test2() + { + auto a = [](int i, int j){ return i + j; }(1, 2); + auto b = []() -> int { return '0'; }(); + auto c = [=](){ return a + b; }(); + auto d = [&](){ return c; }(); + auto e = [a, &b](int x) mutable { + const auto identity = [](int y){ return y; }; + for (auto i = 0; i < a; ++i) + a += b--; + return x + identity(a + b); + }(0); + return a + b + c + d + e; + } + + int + test3() + { + const auto nullary = [](){ return 0; }; + const auto unary = [](int x){ return x; }; + using nullary_t = decltype(nullary); + using unary_t = decltype(unary); + const auto higher1st = [](nullary_t f){ return f(); }; + const auto higher2nd = [unary](nullary_t f1){ + return [unary, f1](unary_t f2){ return f2(unary(f1())); }; + }; + return higher1st(nullary) + higher2nd(nullary)(unary); + } + + } + + namespace test_variadic_templates + { + + template + struct sum; + + template + struct sum + { + static constexpr auto value = N0 + sum::value; + }; + + template <> + struct sum<> + { + static constexpr auto value = 0; + }; + + static_assert(sum<>::value == 0, ""); + static_assert(sum<1>::value == 1, ""); + static_assert(sum<23>::value == 23, ""); + static_assert(sum<1, 2>::value == 3, ""); + static_assert(sum<5, 5, 11>::value == 21, ""); + static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); + + } + + // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae + // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function + // because of this. + namespace test_template_alias_sfinae + { + + struct foo {}; + + template + using member = typename T::member_type; + + template + void func(...) {} + + template + void func(member*) {} + + void test(); + + void test() { func(0); } + + } + +} // namespace cxx11 + +#endif // __cplusplus >= 201103L + + + +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + eval $cachevar=yes +else + eval $cachevar=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CXX="$ac_save_CXX" +fi +eval ac_res=\$$cachevar + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + if eval test x\$$cachevar = xyes; then + CXX="$CXX $switch" + if test -n "$CXXCPP" ; then + CXXCPP="$CXXCPP $switch" + fi + ac_success=yes + break + fi + done + if test x$ac_success = xyes; then + break + fi + done + fi + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + if test x$ax_cxx_compile_cxx11_required = xtrue; then + if test x$ac_success = xno; then + as_fn_error $? "*** A compiler with support for C++11 language features is required." "$LINENO" 5 + fi + fi + if test x$ac_success = xno; then + HAVE_CXX11=0 + { $as_echo "$as_me:${as_lineno-$LINENO}: No compiler with C++11 support was found" >&5 +$as_echo "$as_me: No compiler with C++11 support was found" >&6;} + else + HAVE_CXX11=1 + +$as_echo "#define HAVE_CXX11 1" >>confdefs.h + + fi + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if ${ac_cv_prog_CPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF @@ -6155,11 +6902,8 @@ test $ac_status = 0; }; then # Now try to grab the symbols. nlist=conftest.nm - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 - (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && test -s "$nlist"; then + $ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&5 + if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&5 && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" @@ -7503,7 +8247,6 @@ - func_stripname_cnf () { case $2 in @@ -8567,6 +9310,12 @@ lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-static' ;; + # flang / f18. f95 an alias for gfortran or flang on Debian + flang* | f18* | f95*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) @@ -12509,7 +13258,7 @@ # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' else GXX=no @@ -13001,7 +13750,7 @@ # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then @@ -13066,7 +13815,7 @@ # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then @@ -13405,7 +14154,7 @@ # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' else # FIXME: insert proper C++ library support @@ -13489,7 +14238,7 @@ # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' else # g++ 2.7 appears to require '-G' NOT '-shared' on this # platform. @@ -13500,7 +14249,7 @@ # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. - output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' fi hardcode_libdir_flag_spec_CXX='$wl-R $wl$libdir' @@ -15458,15 +16207,70 @@ # * Otherwise, increment LT_REVISION # LT = libtool -LT_CURRENT=21 +LT_CURRENT=28 LT_AGE=0 -LT_REVISION=2 +LT_REVISION=1 LT_SONAME=$(expr $LT_CURRENT - $LT_AGE) +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -fvisibility=hidden" >&5 +$as_echo_n "checking for -fvisibility=hidden... " >&6; } +try_flags=-fvisibility=hidden +oCXXFLAGS=$CXXFLAGS +CXXFLAGS="$CXXFLAGS $try_flags" +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +class X +{ + public: + __attribute__ ((visibility ("default"))) + X() {} + __attribute__ ((visibility ("default"))) + void f() {} +}; + +int +main () +{ +X x; x.f(); + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + qpdf_VISIBILITY_HIDDEN=1 +else + qpdf_VISIBILITY_HIDDEN=0 +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +if test "$qpdf_VISIBILITY_HIDDEN" = "0"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + CXXFLAGS=$oCXXFLAGS +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + CFLAGS="$CFLAGS $try_flags" +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use insecure random numbers" >&5 +$as_echo_n "checking whether to use insecure random numbers... " >&6; } # Check whether --enable-insecure-random was given. if test "${enable_insecure_random+set}" = set; then : enableval=$enable_insecure_random; if test "$enableval" = "yes"; then @@ -15489,6 +16293,8 @@ $as_echo "no" >&6; } fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use OS-provided secure random numbers" >&5 +$as_echo_n "checking whether to use OS-provided secure random numbers... " >&6; } # Check whether --enable-os-secure-random was given. if test "${enable_os_secure_random+set}" = set; then : enableval=$enable_os_secure_random; if test "$enableval" = "yes"; then @@ -15599,6 +16405,30 @@ fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to avoid Windows HANDLE type" >&5 +$as_echo_n "checking whether to avoid Windows HANDLE type... " >&6; } +# Check whether --enable-avoid-windows-handle was given. +if test "${enable_avoid_windows_handle+set}" = set; then : + enableval=$enable_avoid_windows_handle; if test "$enableval" = "yes"; then + qpdf_AVOID_HANDLE=1; + else + qpdf_AVOID_HANDLE=0; + fi +else + qpdf_AVOID_HANDLE=0 +fi + +if test "$qpdf_AVOID_HANDLE" = "1"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define AVOID_WINDOWS_HANDLE 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + USE_EXTERNAL_LIBS=0 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for whether to use external libraries distribution" >&5 $as_echo_n "checking for whether to use external libraries distribution... " >&6; } @@ -15621,28 +16451,322 @@ $as_echo "yes" >&6; } fi -WINDOWS_WORDSIZE= - +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of size_t" >&5 +$as_echo_n "checking size of size_t... " >&6; } +if ${ac_cv_sizeof_size_t+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (size_t))" "ac_cv_sizeof_size_t" "$ac_includes_default"; then : -# Check whether --with-windows-wordsize was given. -if test "${with_windows_wordsize+set}" = set; then : - withval=$with_windows_wordsize; WINDOWS_WORDSIZE=$withval else - WINDOWS_WORDSIZE=none + if test "$ac_cv_type_size_t" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (size_t) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_size_t=0 + fi fi -if test "$USE_EXTERNAL_LIBS" = "1"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for windows wordsize" >&5 -$as_echo_n "checking for windows wordsize... " >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $WINDOWS_WORDSIZE" >&5 -$as_echo "$WINDOWS_WORDSIZE" >&6; } - if ! test "$WINDOWS_WORDSIZE" = "32" -o "$WINDOWS_WORDSIZE" = "64"; then - as_fn_error $? "Windows wordsize of 32 or 64 must be specified if external libs are being used." "$LINENO" 5 - fi fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_size_t" >&5 +$as_echo "$ac_cv_sizeof_size_t" >&6; } + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_SIZE_T $ac_cv_sizeof_size_t +_ACEOF + + +if test "$ac_cv_sizeof_size_t" = "4"; then + IS_32BIT=1 + WINDOWS_WORDSIZE=32 +else + IS_32BIT=0 + WINDOWS_WORDSIZE=64 +fi + + + + + + + + + + +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. +set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_PKG_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +PKG_CONFIG=$ac_cv_path_PKG_CONFIG +if test -n "$PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 +$as_echo "$PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_path_PKG_CONFIG"; then + ac_pt_PKG_CONFIG=$PKG_CONFIG + # Extract the first word of "pkg-config", so it can be a program name with args. +set dummy pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $ac_pt_PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG +if test -n "$ac_pt_PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 +$as_echo "$ac_pt_PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_pt_PKG_CONFIG" = x; then + PKG_CONFIG="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + PKG_CONFIG=$ac_pt_PKG_CONFIG + fi +else + PKG_CONFIG="$ac_cv_path_PKG_CONFIG" +fi + +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=0.9.0 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 +$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + PKG_CONFIG="" + fi +fi if test "$BUILD_INTERNAL_LIBS" = "0"; then - ac_fn_c_check_header_mongrel "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default" + if test "$PKG_CONFIG" != ""; then + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pc_zlib" >&5 +$as_echo_n "checking for pc_zlib... " >&6; } + +if test -n "$pc_zlib_CFLAGS"; then + pkg_cv_pc_zlib_CFLAGS="$pc_zlib_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"zlib\""; } >&5 + ($PKG_CONFIG --exists --print-errors "zlib") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_pc_zlib_CFLAGS=`$PKG_CONFIG --cflags "zlib" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$pc_zlib_LIBS"; then + pkg_cv_pc_zlib_LIBS="$pc_zlib_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"zlib\""; } >&5 + ($PKG_CONFIG --exists --print-errors "zlib") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_pc_zlib_LIBS=`$PKG_CONFIG --libs "zlib" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + pc_zlib_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "zlib" 2>&1` + else + pc_zlib_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "zlib" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$pc_zlib_PKG_ERRORS" >&5 + + : +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + : +else + pc_zlib_CFLAGS=$pkg_cv_pc_zlib_CFLAGS + pc_zlib_LIBS=$pkg_cv_pc_zlib_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + CFLAGS="$CFLAGS $pc_zlib_CFLAGS" + CXXFLAGS="$CXXFLAGS $pc_zlib_CXXFLAGS" + LIBS="$LIBS $pc_zlib_LIBS" + +fi + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pc_libjpeg" >&5 +$as_echo_n "checking for pc_libjpeg... " >&6; } + +if test -n "$pc_libjpeg_CFLAGS"; then + pkg_cv_pc_libjpeg_CFLAGS="$pc_libjpeg_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libjpeg\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libjpeg") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_pc_libjpeg_CFLAGS=`$PKG_CONFIG --cflags "libjpeg" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$pc_libjpeg_LIBS"; then + pkg_cv_pc_libjpeg_LIBS="$pc_libjpeg_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libjpeg\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libjpeg") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_pc_libjpeg_LIBS=`$PKG_CONFIG --libs "libjpeg" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + pc_libjpeg_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libjpeg" 2>&1` + else + pc_libjpeg_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libjpeg" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$pc_libjpeg_PKG_ERRORS" >&5 + + : +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + : +else + pc_libjpeg_CFLAGS=$pkg_cv_pc_libjpeg_CFLAGS + pc_libjpeg_LIBS=$pkg_cv_pc_libjpeg_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + CFLAGS="$CFLAGS $pc_libjpeg_CFLAGS" + CXXFLAGS="$CXXFLAGS $pc_libjpeg_CXXFLAGS" + LIBS="$LIBS $pc_libjpeg_LIBS" + +fi + fi + if test "$pc_zlib_LIBS" = ""; then + ac_fn_c_check_header_mongrel "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default" if test "x$ac_cv_header_zlib_h" = xyes; then : else @@ -15650,7 +16774,7 @@ fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing deflate" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing deflate" >&5 $as_echo_n "checking for library containing deflate... " >&6; } if ${ac_cv_search_deflate+:} false; then : $as_echo_n "(cached) " >&6 @@ -15708,7 +16832,9 @@ MISSING_ZLIB=1; MISSING_ANY=1 fi - ac_fn_c_check_header_mongrel "$LINENO" "jpeglib.h" "ac_cv_header_jpeglib_h" "$ac_includes_default" + fi + if test "$pc_libjpeg_LIBS" = ""; then + ac_fn_c_check_header_mongrel "$LINENO" "jpeglib.h" "ac_cv_header_jpeglib_h" "$ac_includes_default" if test "x$ac_cv_header_jpeglib_h" = xyes; then : else @@ -15716,7 +16842,7 @@ fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing jpeg_destroy" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing jpeg_destroy" >&5 $as_echo_n "checking for library containing jpeg_destroy... " >&6; } if ${ac_cv_search_jpeg_destroy+:} false; then : $as_echo_n "(cached) " >&6 @@ -15774,8 +16900,81 @@ MISSING_JPEG=1; MISSING_ANY=1 fi + fi + if test "$LIBS" != ""; then + nLIBS="" + for x in $LIBS; do + if echo $x | grep -q '^-L'; then + LDFLAGS="$LDFLAGS $x" + else + nLIBS="$nLIBS $x" + fi + LIBS=$nLIBS + done + fi fi +qpdf_USE_WMAIN=0 +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + + +for i in 0 1; do + if test "$qpdf_USE_WMAIN" = "0"; then + oLDFLAGS="$LDFLAGS" + if test "$i" = "1"; then + nLDFLAGS="-municode" + LDFLAGS="$LDFLAGS $nLDFLAGS" + msg="checking for wmain with $nLDFLAGS" + else + nLDFLAGS= + msg="checking for wmain" + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking $msg" >&5 +$as_echo_n "checking $msg... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #include + #include + extern "C" + int wmain(int argc, wchar_t* argv[]) + { + size_t x = wcslen(argv[0]); + return 0; + } + +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + qpdf_USE_WMAIN=1 +else + qpdf_USE_WMAIN=0 +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$oLDFLAGS" + if test "$qpdf_USE_WMAIN" = "1"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + WINDOWS_WMAIN_COMPILE="-DWINDOWS_WMAIN $nLDFLAGS" + WINDOWS_WMAIN_LINK="$nLDFLAGS" + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + fi +done +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + if test "x$qpdf_OS_SECURE_RANDOM" = "x1"; then OLIBS=$LIBS LIBS="$LIBS Advapi32.lib" @@ -16099,32 +17298,6 @@ fi done -ac_fn_c_find_uintX_t "$LINENO" "16" "ac_cv_c_uint16_t" -case $ac_cv_c_uint16_t in #( - no|yes) ;; #( - *) - - -cat >>confdefs.h <<_ACEOF -#define uint16_t $ac_cv_c_uint16_t -_ACEOF -;; - esac - -ac_fn_c_find_uintX_t "$LINENO" "32" "ac_cv_c_uint32_t" -case $ac_cv_c_uint32_t in #( - no|yes) ;; #( - *) - -$as_echo "#define _UINT32_T 1" >>confdefs.h - - -cat >>confdefs.h <<_ACEOF -#define uint32_t $ac_cv_c_uint32_t -_ACEOF -;; - esac - for ac_func in random do : @@ -16410,6 +17583,496 @@ $as_echo "no" >&6; } fi +if test "$BUILDRULES" = "msvc"; then + try_flags="-W3" +else + try_flags="-Wconversion -Wsign-conversion" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for whether to use $try_flags" >&5 +$as_echo_n "checking for whether to use $try_flags... " >&6; } +# Check whether --enable-int-warnings was given. +if test "${enable_int_warnings+set}" = set; then : + enableval=$enable_int_warnings; if test "$enableval" = "yes"; then + qpdf_INT_WARNINGS=1; + else + qpdf_INT_WARNINGS=0; + fi +else + qpdf_INT_WARNINGS=1 +fi + +if test "$qpdf_INT_WARNINGS" = "1"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + WFLAGS="$WFLAGS $try_flags" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + +if test "$BUILDRULES" = "msvc"; then + WINDOWS_WMAIN_XLINK_FLAGS="-link wsetargv.obj" + WINDOWS_MAIN_XLINK_FLAGS="-link setargv.obj" +fi + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for whether to use implicit crypto" >&5 +$as_echo_n "checking for whether to use implicit crypto... " >&6; } +# Check whether --enable-implicit-crypto was given. +if test "${enable_implicit_crypto+set}" = set; then : + enableval=$enable_implicit_crypto; if test "$enableval" = "yes"; then + IMPLICIT_CRYPTO=1 + else + IMPLICIT_CRYPTO=0 + fi +else + IMPLICIT_CRYPTO=1 +fi + +if test "$IMPLICIT_CRYPTO" = "1"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + +# Check whether --enable-crypto-native was given. +if test "${enable_crypto_native+set}" = set; then : + enableval=$enable_crypto_native; if test "$enableval" = "yes"; then + USE_CRYPTO_NATIVE=1 + else + USE_CRYPTO_NATIVE=0 + fi +else + USE_CRYPTO_NATIVE=$IMPLICIT_CRYPTO +fi + +if test "$USE_CRYPTO_NATIVE" = "1"; then + +$as_echo "#define USE_CRYPTO_NATIVE 1" >>confdefs.h + + DEFAULT_CRYPTO=native +fi + + + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pc_openssl" >&5 +$as_echo_n "checking for pc_openssl... " >&6; } + +if test -n "$pc_openssl_CFLAGS"; then + pkg_cv_pc_openssl_CFLAGS="$pc_openssl_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"openssl\""; } >&5 + ($PKG_CONFIG --exists --print-errors "openssl") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_pc_openssl_CFLAGS=`$PKG_CONFIG --cflags "openssl" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$pc_openssl_LIBS"; then + pkg_cv_pc_openssl_LIBS="$pc_openssl_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"openssl\""; } >&5 + ($PKG_CONFIG --exists --print-errors "openssl") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_pc_openssl_LIBS=`$PKG_CONFIG --libs "openssl" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + pc_openssl_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "openssl" 2>&1` + else + pc_openssl_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "openssl" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$pc_openssl_PKG_ERRORS" >&5 + + OPENSSL_FOUND=0 +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + OPENSSL_FOUND=0 +else + pc_openssl_CFLAGS=$pkg_cv_pc_openssl_CFLAGS + pc_openssl_LIBS=$pkg_cv_pc_openssl_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + OPENSSL_FOUND=1 +fi +if test "$OPENSSL_FOUND" = "0"; then + ac_fn_c_check_header_mongrel "$LINENO" "openssl/evp.h" "ac_cv_header_openssl_evp_h" "$ac_includes_default" +if test "x$ac_cv_header_openssl_evp_h" = xyes; then : + OPENSSL_FOUND=1 +else + OPENSSL_FOUND=0 +fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing EVP_DigestInit_ex" >&5 +$as_echo_n "checking for library containing EVP_DigestInit_ex... " >&6; } +if ${ac_cv_search_EVP_DigestInit_ex+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char EVP_DigestInit_ex (); +int +main () +{ +return EVP_DigestInit_ex (); + ; + return 0; +} +_ACEOF +for ac_lib in '' openssl; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_EVP_DigestInit_ex=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_EVP_DigestInit_ex+:} false; then : + break +fi +done +if ${ac_cv_search_EVP_DigestInit_ex+:} false; then : + +else + ac_cv_search_EVP_DigestInit_ex=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_EVP_DigestInit_ex" >&5 +$as_echo "$ac_cv_search_EVP_DigestInit_ex" >&6; } +ac_res=$ac_cv_search_EVP_DigestInit_ex +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + OPENSSL_FOUND=1 +else + OPENSSL_FOUND=0 +fi + +fi + +IMPLICIT_OPENSSL=0 +USE_CRYPTO_OPENSSL=0 + +# Check whether --enable-crypto-openssl was given. +if test "${enable_crypto_openssl+set}" = set; then : + enableval=$enable_crypto_openssl; if test "$enableval" = "yes"; then + USE_CRYPTO_OPENSSL=1 + else + USE_CRYPTO_OPENSSL=0 + fi +else + IMPLICIT_OPENSSL=$IMPLICIT_CRYPTO +fi + + +if test "$IMPLICIT_OPENSSL" = "1"; then + USE_CRYPTO_OPENSSL=$OPENSSL_FOUND + if test "$USE_CRYPTO_OPENSSL" = "1"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: enabling openssl crypto provider since openssl is available" >&5 +$as_echo "$as_me: enabling openssl crypto provider since openssl is available" >&6;} + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not enabling openssl crypto provider since openssl was not found" >&5 +$as_echo "$as_me: not enabling openssl crypto provider since openssl was not found" >&6;} + fi +fi + +if test "$USE_CRYPTO_OPENSSL" = "1" -a "$OPENSSL_FOUND" = "0"; then + as_fn_error $? "unable to use requested openssl crypto provider without openssl" "$LINENO" 5 +fi + +if test "$USE_CRYPTO_OPENSSL" = "1"; then + CFLAGS="$CFLAGS $pc_openssl_CFLAGS" + CXXFLAGS="$CXXFLAGS $pc_openssl_CXXFLAGS" + LIBS="$LIBS $pc_openssl_LIBS" + +$as_echo "#define USE_CRYPTO_OPENSSL 1" >>confdefs.h + + DEFAULT_CRYPTO=openssl +elif test "$OPENSSL_FOUND" = "1"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: not linking with openssl even though it is available" >&5 +$as_echo "$as_me: not linking with openssl even though it is available" >&6;} +fi + + + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pc_gnutls" >&5 +$as_echo_n "checking for pc_gnutls... " >&6; } + +if test -n "$pc_gnutls_CFLAGS"; then + pkg_cv_pc_gnutls_CFLAGS="$pc_gnutls_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gnutls\""; } >&5 + ($PKG_CONFIG --exists --print-errors "gnutls") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_pc_gnutls_CFLAGS=`$PKG_CONFIG --cflags "gnutls" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$pc_gnutls_LIBS"; then + pkg_cv_pc_gnutls_LIBS="$pc_gnutls_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gnutls\""; } >&5 + ($PKG_CONFIG --exists --print-errors "gnutls") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_pc_gnutls_LIBS=`$PKG_CONFIG --libs "gnutls" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + pc_gnutls_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "gnutls" 2>&1` + else + pc_gnutls_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "gnutls" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$pc_gnutls_PKG_ERRORS" >&5 + + GNUTLS_FOUND=0 +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + GNUTLS_FOUND=0 +else + pc_gnutls_CFLAGS=$pkg_cv_pc_gnutls_CFLAGS + pc_gnutls_LIBS=$pkg_cv_pc_gnutls_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + GNUTLS_FOUND=1 +fi +if test "$GNUTLS_FOUND" = "0"; then + ac_fn_c_check_header_mongrel "$LINENO" "gnutls/gnutls.h" "ac_cv_header_gnutls_gnutls_h" "$ac_includes_default" +if test "x$ac_cv_header_gnutls_gnutls_h" = xyes; then : + GNUTLS_FOUND=1 +else + GNUTLS_FOUND=0 +fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing gnutls_hash_init" >&5 +$as_echo_n "checking for library containing gnutls_hash_init... " >&6; } +if ${ac_cv_search_gnutls_hash_init+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char gnutls_hash_init (); +int +main () +{ +return gnutls_hash_init (); + ; + return 0; +} +_ACEOF +for ac_lib in '' gnutls; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_gnutls_hash_init=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_gnutls_hash_init+:} false; then : + break +fi +done +if ${ac_cv_search_gnutls_hash_init+:} false; then : + +else + ac_cv_search_gnutls_hash_init=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_gnutls_hash_init" >&5 +$as_echo "$ac_cv_search_gnutls_hash_init" >&6; } +ac_res=$ac_cv_search_gnutls_hash_init +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + GNUTLS_FOUND=1 +else + GNUTLS_FOUND=0 +fi + +fi + +IMPLICIT_GNUTLS=0 +USE_CRYPTO_GNUTLS=0 + +# Check whether --enable-crypto-gnutls was given. +if test "${enable_crypto_gnutls+set}" = set; then : + enableval=$enable_crypto_gnutls; if test "$enableval" = "yes"; then + USE_CRYPTO_GNUTLS=1 + else + USE_CRYPTO_GNUTLS=0 + fi +else + IMPLICIT_GNUTLS=$IMPLICIT_CRYPTO +fi + + +if test "$IMPLICIT_GNUTLS" = "1"; then + USE_CRYPTO_GNUTLS=$GNUTLS_FOUND + if test "$USE_CRYPTO_GNUTLS" = "1"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: enabling gnutls crypto provider since gnutls is available" >&5 +$as_echo "$as_me: enabling gnutls crypto provider since gnutls is available" >&6;} + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not enabling gnutls crypto provider since gnutls was not found" >&5 +$as_echo "$as_me: not enabling gnutls crypto provider since gnutls was not found" >&6;} + fi +fi + +if test "$USE_CRYPTO_GNUTLS" = "1" -a "$GNUTLS_FOUND" = "0"; then + as_fn_error $? "unable to use requested gnutls crypto provider without gnutls" "$LINENO" 5 +fi + +if test "$USE_CRYPTO_GNUTLS" = "1"; then + CFLAGS="$CFLAGS $pc_gnutls_CFLAGS" + CXXFLAGS="$CXXFLAGS $pc_gnutls_CXXFLAGS" + LIBS="$LIBS $pc_gnutls_LIBS" + +$as_echo "#define USE_CRYPTO_GNUTLS 1" >>confdefs.h + + DEFAULT_CRYPTO=gnutls +elif test "$GNUTLS_FOUND" = "1"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: not linking with gnutls even though it is available" >&5 +$as_echo "$as_me: not linking with gnutls even though it is available" >&6;} +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking which crypto to use by default" >&5 +$as_echo_n "checking which crypto to use by default... " >&6; } + + +# Check whether --with-default-crypto was given. +if test "${with_default_crypto+set}" = set; then : + withval=$with_default_crypto; DEFAULT_CRYPTO=$withval +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $DEFAULT_CRYPTO" >&5 +$as_echo "$DEFAULT_CRYPTO" >&6; } + +cat >>confdefs.h <<_ACEOF +#define DEFAULT_CRYPTO "$DEFAULT_CRYPTO" +_ACEOF + + + +bad_crypto=0 +case "$DEFAULT_CRYPTO" in + "native") + if test "$USE_CRYPTO_NATIVE" != "1"; then + bad_crypto=1 + fi + ;; + "openssl") + if test "$USE_CRYPTO_OPENSSL" != "1"; then + bad_crypto=1 + fi + ;; + "gnutls") + if test "$USE_CRYPTO_GNUTLS" != "1"; then + bad_crypto=1 + fi + ;; + *) + bad_crypto=1 + ;; +esac +if test "$bad_crypto" = "1"; then + as_fn_error $? "Unsupported default crypto: $DEFAULT_CRYPTO" "$LINENO" 5 +fi + + # Check whether --enable-test-compare-images was given. if test "${enable_test_compare_images+set}" = set; then : @@ -16654,6 +18317,19 @@ fi + +# Check whether --enable-oss-fuzz was given. +if test "${enable_oss_fuzz+set}" = set; then : + enableval=$enable_oss_fuzz; if test "$enableval" = "yes"; then + OSS_FUZZ=1; + else + OSS_FUZZ=0; + fi +else + OSS_FUZZ=0 +fi + + if test "$VALIDATE_DOC" = "1"; then if test "$XMLLINT" = ""; then MISSING_XMLLINT=1 @@ -17269,7 +18945,7 @@ # 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 8.0.2, which was +This file was extended by qpdf $as_me 10.0.1, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -17335,7 +19011,7 @@ 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 8.0.2 +qpdf config.status 10.0.1 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff -Nru qpdf-8.0.2/configure.ac qpdf-10.0.1/configure.ac --- qpdf-8.0.2/configure.ac 2018-03-06 16:34:07.000000000 +0000 +++ qpdf-10.0.1/configure.ac 2020-04-09 15:48:26.000000000 +0000 @@ -2,7 +2,7 @@ dnl This config.in requires autoconf 2.5 or greater. AC_PREREQ([2.68]) -AC_INIT([qpdf],[8.0.2]) +AC_INIT([qpdf],[10.0.1]) AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_FILES([autoconf.mk]) @@ -11,9 +11,32 @@ AC_CONFIG_FILES([libqpdf.map]) AC_CONFIG_HEADERS([libqpdf/qpdf/qpdf-config.h]) +AC_ARG_ENABLE(check-autofiles, + AS_HELP_STRING([--enable-check-autofiles], + [if specified, verify checksums on automatically generated files (default=yes); package maintainers may want to disable this]), + [if test "$enableval" = "no"; then + CHECK_AUTOFILES=0 + else + CHECK_AUTOFILES=1 + fi], + [CHECK_AUTOFILES=1]) + +# Check to see if automatically generated files are outdated and if we +# can update them. +AC_CHECK_PROG(AUTOCONF,autoconf,1,0) +AC_CHECK_PROG(AUTOHEADER,autoheader,1,0) +AC_CHECK_PROG(ACLOCAL,aclocal,1,0) +AC_CHECK_PROG(SHA256SUM,sha256sum,1,0) +if test "$CHECK_AUTOFILES$AUTOCONF$AUTOHEADER$ACLOCAL$SHA256SUM" = "11111"; then + if ! sha256sum -c autofiles.sums; then + AC_MSG_ERROR(autofiles are outdated; rerun autogen.sh) + fi +fi + AC_PROG_CC AC_PROG_CC_C99 AC_PROG_CXX +AX_CXX_COMPILE_STDCXX([11], [noext], [mandatory]) AC_HEADER_STDC LT_INIT([win32-dll]) @@ -29,15 +52,42 @@ # * Otherwise, increment LT_REVISION # LT = libtool -LT_CURRENT=21 +LT_CURRENT=28 LT_AGE=0 -LT_REVISION=2 +LT_REVISION=1 AC_SUBST(LT_CURRENT) AC_SUBST(LT_REVISION) AC_SUBST(LT_AGE) LT_SONAME=$(expr $LT_CURRENT - $LT_AGE) AC_SUBST(LT_SONAME) +AC_MSG_CHECKING(for -fvisibility=hidden) +try_flags=-fvisibility=hidden +oCXXFLAGS=$CXXFLAGS +CXXFLAGS="$CXXFLAGS $try_flags" +AC_LANG_PUSH([C++]) +AC_LINK_IFELSE([AC_LANG_PROGRAM( + [[class X +{ + public: + __attribute__ ((visibility ("default"))) + X() {} + __attribute__ ((visibility ("default"))) + void f() {} +}; + ]],[[X x; x.f();]])], + [qpdf_VISIBILITY_HIDDEN=1], + [qpdf_VISIBILITY_HIDDEN=0]) +AC_LANG_POP +if test "$qpdf_VISIBILITY_HIDDEN" = "0"; then + AC_MSG_RESULT(no) + CXXFLAGS=$oCXXFLAGS +else + AC_MSG_RESULT(yes) + CFLAGS="$CFLAGS $try_flags" +fi + +AC_MSG_CHECKING(whether to use insecure random numbers) AC_ARG_ENABLE(insecure-random, AS_HELP_STRING([--enable-insecure-random], [whether to use stdlib's random number generator (default is no)]), @@ -53,6 +103,7 @@ AC_MSG_RESULT(no) fi +AC_MSG_CHECKING(whether to use OS-provided secure random numbers) AC_ARG_ENABLE(os-secure-random, AS_HELP_STRING([--enable-os-secure-random], [whether to try to use OS-provided secure random numbers (default is yes)]), @@ -65,11 +116,27 @@ AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) - AC_DEFINE([SKIP_OS_SECURE_RANDOM], [1], [Whether to suppres use of OS-provided secure random numbers]) + AC_DEFINE([SKIP_OS_SECURE_RANDOM], [1], [Whether to suppress use of OS-provided secure random numbers]) fi AX_RANDOM_DEVICE +AC_MSG_CHECKING(whether to avoid Windows HANDLE type) +AC_ARG_ENABLE(avoid-windows-handle, + AS_HELP_STRING([--enable-avoid-windows-handle], + [whether to avoid use of HANDLE, useful for some embedded Windows builds (default is no)]), + [if test "$enableval" = "yes"; then + qpdf_AVOID_HANDLE=1; + else + qpdf_AVOID_HANDLE=0; + fi], [qpdf_AVOID_HANDLE=0]) +if test "$qpdf_AVOID_HANDLE" = "1"; then + AC_MSG_RESULT(yes) + AC_DEFINE([AVOID_WINDOWS_HANDLE], [1], [Whether to avoid use of HANDLE in Windows]) +else + AC_MSG_RESULT(no) +fi + USE_EXTERNAL_LIBS=0 AC_MSG_CHECKING(for whether to use external libraries distribution) AC_ARG_ENABLE(external-libs, @@ -86,28 +153,93 @@ AC_MSG_RESULT(yes) fi -WINDOWS_WORDSIZE= -AC_SUBST(WINDOWS_WORDSIZE) -AC_ARG_WITH(windows-wordsize, - AS_HELP_STRING([--with-windows-wordsize={32,64}], - [Windows only: whether this is a 32-bit or 64-bit build; required if external-libs are enabled]), - [WINDOWS_WORDSIZE=$withval], - [WINDOWS_WORDSIZE=none]) -if test "$USE_EXTERNAL_LIBS" = "1"; then - AC_MSG_CHECKING(for windows wordsize) - AC_MSG_RESULT($WINDOWS_WORDSIZE) - if ! test "$WINDOWS_WORDSIZE" = "32" -o "$WINDOWS_WORDSIZE" = "64"; then - AC_MSG_ERROR(Windows wordsize of 32 or 64 must be specified if external libs are being used.) - fi +AC_CHECK_SIZEOF([size_t]) +if test "$ac_cv_sizeof_size_t" = "4"; then + IS_32BIT=1 + WINDOWS_WORDSIZE=32 +else + IS_32BIT=0 + WINDOWS_WORDSIZE=64 fi +AC_SUBST(IS_32BIT) +AC_SUBST(WINDOWS_WORDSIZE) +PKG_PROG_PKG_CONFIG if test "$BUILD_INTERNAL_LIBS" = "0"; then - AC_CHECK_HEADER(zlib.h,,[MISSING_ZLIB_H=1; MISSING_ANY=1]) - AC_SEARCH_LIBS(deflate,z zlib,,[MISSING_ZLIB=1; MISSING_ANY=1]) - AC_CHECK_HEADER(jpeglib.h,,[MISSING_JPEG_H=1; MISSING_ANY=1]) - AC_SEARCH_LIBS(jpeg_destroy,jpeg,,[MISSING_JPEG=1; MISSING_ANY=1]) + if test "$PKG_CONFIG" != ""; then + PKG_CHECK_MODULES([pc_zlib], [zlib], + [CFLAGS="$CFLAGS $pc_zlib_CFLAGS" + CXXFLAGS="$CXXFLAGS $pc_zlib_CXXFLAGS" + LIBS="$LIBS $pc_zlib_LIBS" + ], [:]) + PKG_CHECK_MODULES([pc_libjpeg], [libjpeg], + [CFLAGS="$CFLAGS $pc_libjpeg_CFLAGS" + CXXFLAGS="$CXXFLAGS $pc_libjpeg_CXXFLAGS" + LIBS="$LIBS $pc_libjpeg_LIBS" + ],[:]) + fi + if test "$pc_zlib_LIBS" = ""; then + AC_CHECK_HEADER(zlib.h,,[MISSING_ZLIB_H=1; MISSING_ANY=1]) + AC_SEARCH_LIBS(deflate,z zlib,,[MISSING_ZLIB=1; MISSING_ANY=1]) + fi + if test "$pc_libjpeg_LIBS" = ""; then + AC_CHECK_HEADER(jpeglib.h,,[MISSING_JPEG_H=1; MISSING_ANY=1]) + AC_SEARCH_LIBS(jpeg_destroy,jpeg,,[MISSING_JPEG=1; MISSING_ANY=1]) + fi + if test "$LIBS" != ""; then + nLIBS="" + for x in $LIBS; do + if echo $x | grep -q '^-L'; then + LDFLAGS="$LDFLAGS $x" + else + nLIBS="$nLIBS $x" + fi + LIBS=$nLIBS + done + fi fi +qpdf_USE_WMAIN=0 +AC_LANG_PUSH([C++]) +AC_SUBST(WINDOWS_WMAIN_COMPILE) +AC_SUBST(WINDOWS_WMAIN_LINK) +for i in 0 1; do + if test "$qpdf_USE_WMAIN" = "0"; then + oLDFLAGS="$LDFLAGS" + if test "$i" = "1"; then + nLDFLAGS="-municode" + LDFLAGS="$LDFLAGS $nLDFLAGS" + msg="checking for wmain with $nLDFLAGS" + else + nLDFLAGS= + msg="checking for wmain" + fi + AC_MSG_CHECKING($msg) + AC_LINK_IFELSE([AC_LANG_SOURCE( + [[#include + #include + #include + extern "C" + int wmain(int argc, wchar_t* argv[]) + { + size_t x = wcslen(argv[0]); + return 0; + } + ]])], + [qpdf_USE_WMAIN=1], + [qpdf_USE_WMAIN=0]) + LDFLAGS="$oLDFLAGS" + if test "$qpdf_USE_WMAIN" = "1"; then + AC_MSG_RESULT(yes) + WINDOWS_WMAIN_COMPILE="-DWINDOWS_WMAIN $nLDFLAGS" + WINDOWS_WMAIN_LINK="$nLDFLAGS" + else + AC_MSG_RESULT(no) + fi + fi +done +AC_LANG_POP + if test "x$qpdf_OS_SECURE_RANDOM" = "x1"; then OLIBS=$LIBS LIBS="$LIBS Advapi32.lib" @@ -136,8 +268,6 @@ AC_SYS_LARGEFILE AC_FUNC_FSEEKO AC_CHECK_FUNCS([fseeko64]) -AC_TYPE_UINT16_T -AC_TYPE_UINT32_T AC_CHECK_FUNCS(random) @@ -314,6 +444,210 @@ AC_MSG_RESULT(no) fi +if test "$BUILDRULES" = "msvc"; then + try_flags="-W3" +else + try_flags="-Wconversion -Wsign-conversion" +fi +AC_MSG_CHECKING(for whether to use $try_flags) +AC_ARG_ENABLE(int-warnings, + AS_HELP_STRING([--enable-int-warnings], + [whether to turn on integer type warnings (default is yes)]), + [if test "$enableval" = "yes"; then + qpdf_INT_WARNINGS=1; + else + qpdf_INT_WARNINGS=0; + fi], [qpdf_INT_WARNINGS=1]) +if test "$qpdf_INT_WARNINGS" = "1"; then + AC_MSG_RESULT(yes) + WFLAGS="$WFLAGS $try_flags" +else + AC_MSG_RESULT(no) +fi + +AC_SUBST(WINDOWS_WMAIN_XLINK_FLAGS) +AC_SUBST(WINDOWS_MAIN_XLINK_FLAGS) +if test "$BUILDRULES" = "msvc"; then + WINDOWS_WMAIN_XLINK_FLAGS="-link wsetargv.obj" + WINDOWS_MAIN_XLINK_FLAGS="-link setargv.obj" +fi + +dnl BEGIN CRYPTO + +dnl By default, we build in support for every crypto provider that we +dnl can. If implicit crypto is disabled, we don't build support for +dnl any crypto that is not explicitly enabled. Test for various crypto +dnl providers in increasing order of priority. The last one found +dnl becomes the default unless a default is explicitly specified. + +AC_MSG_CHECKING(for whether to use implicit crypto) +AC_ARG_ENABLE(implicit-crypto, + AS_HELP_STRING([--enable-implicit-crypto], + [whether to enable available crypto providers that are not explicitly requested; true by default]), + [if test "$enableval" = "yes"; then + IMPLICIT_CRYPTO=1 + else + IMPLICIT_CRYPTO=0 + fi], + [IMPLICIT_CRYPTO=1]) +if test "$IMPLICIT_CRYPTO" = "1"; then + AC_MSG_RESULT(yes) +else + AC_MSG_RESULT(no) +fi + +dnl Native crypto is always available unless explicitly disabled. + +AC_SUBST(USE_CRYPTO_NATIVE) +AC_ARG_ENABLE(crypto-native, + AS_HELP_STRING([--enable-crypto-native], + [whether to include support for native crypto provider]), + [if test "$enableval" = "yes"; then + USE_CRYPTO_NATIVE=1 + else + USE_CRYPTO_NATIVE=0 + fi], + [USE_CRYPTO_NATIVE=$IMPLICIT_CRYPTO]) +if test "$USE_CRYPTO_NATIVE" = "1"; then + AC_DEFINE([USE_CRYPTO_NATIVE], 1, [Whether to use the native crypto provider]) + DEFAULT_CRYPTO=native +fi + +dnl If the openssl/BoringSSL provider is explicitly requested, require openssl +dnl If the openssl provider is not explicitly disabled, enable it if +dnl openssl is available. If the openssl provider is explicitly +dnl disabled, do not link with openssl even if present. + +PKG_CHECK_MODULES([pc_openssl], [openssl], [OPENSSL_FOUND=1], [OPENSSL_FOUND=0]) +if test "$OPENSSL_FOUND" = "0"; then + AC_CHECK_HEADER([openssl/evp.h],[OPENSSL_FOUND=1],[OPENSSL_FOUND=0]) + AC_SEARCH_LIBS(EVP_DigestInit_ex,openssl,[OPENSSL_FOUND=1],[OPENSSL_FOUND=0]) +fi + +IMPLICIT_OPENSSL=0 +USE_CRYPTO_OPENSSL=0 +AC_SUBST(USE_CRYPTO_OPENSSL) +AC_ARG_ENABLE(crypto-openssl, + AS_HELP_STRING([--enable-crypto-openssl], + [whether to include support for the BoringSSL crypto provider]), + [if test "$enableval" = "yes"; then + USE_CRYPTO_OPENSSL=1 + else + USE_CRYPTO_OPENSSL=0 + fi], + [IMPLICIT_OPENSSL=$IMPLICIT_CRYPTO]) + +if test "$IMPLICIT_OPENSSL" = "1"; then + USE_CRYPTO_OPENSSL=$OPENSSL_FOUND + if test "$USE_CRYPTO_OPENSSL" = "1"; then + AC_MSG_NOTICE(enabling openssl crypto provider since openssl is available) + else + AC_MSG_NOTICE(not enabling openssl crypto provider since openssl was not found) + fi +fi + +if test "$USE_CRYPTO_OPENSSL" = "1" -a "$OPENSSL_FOUND" = "0"; then + AC_MSG_ERROR(unable to use requested openssl crypto provider without openssl) +fi + +if test "$USE_CRYPTO_OPENSSL" = "1"; then + CFLAGS="$CFLAGS $pc_openssl_CFLAGS" + CXXFLAGS="$CXXFLAGS $pc_openssl_CXXFLAGS" + LIBS="$LIBS $pc_openssl_LIBS" + AC_DEFINE([USE_CRYPTO_OPENSSL], 1, [Whether to use the openssl crypto provider]) + DEFAULT_CRYPTO=openssl +elif test "$OPENSSL_FOUND" = "1"; then + AC_MSG_NOTICE(not linking with openssl even though it is available) +fi + +dnl If the gnutls provider is explicitly requested, require gnutls. If +dnl the gnutls provider is not explicitly disabled, enable it if +dnl gnutls is available. If the gnutls provider is explicitly +dnl disabled, do not link with gnutls even if present. + +PKG_CHECK_MODULES([pc_gnutls], [gnutls], [GNUTLS_FOUND=1], [GNUTLS_FOUND=0]) +if test "$GNUTLS_FOUND" = "0"; then + AC_CHECK_HEADER(gnutls/gnutls.h,[GNUTLS_FOUND=1],[GNUTLS_FOUND=0]) + AC_SEARCH_LIBS(gnutls_hash_init,gnutls,[GNUTLS_FOUND=1],[GNUTLS_FOUND=0]) +fi + +IMPLICIT_GNUTLS=0 +USE_CRYPTO_GNUTLS=0 +AC_SUBST(USE_CRYPTO_GNUTLS) +AC_ARG_ENABLE(crypto-gnutls, + AS_HELP_STRING([--enable-crypto-gnutls], + [whether to include support for gnutls crypto provider]), + [if test "$enableval" = "yes"; then + USE_CRYPTO_GNUTLS=1 + else + USE_CRYPTO_GNUTLS=0 + fi], + [IMPLICIT_GNUTLS=$IMPLICIT_CRYPTO]) + +if test "$IMPLICIT_GNUTLS" = "1"; then + USE_CRYPTO_GNUTLS=$GNUTLS_FOUND + if test "$USE_CRYPTO_GNUTLS" = "1"; then + AC_MSG_NOTICE(enabling gnutls crypto provider since gnutls is available) + else + AC_MSG_NOTICE(not enabling gnutls crypto provider since gnutls was not found) + fi +fi + +if test "$USE_CRYPTO_GNUTLS" = "1" -a "$GNUTLS_FOUND" = "0"; then + AC_MSG_ERROR(unable to use requested gnutls crypto provider without gnutls) +fi + +if test "$USE_CRYPTO_GNUTLS" = "1"; then + CFLAGS="$CFLAGS $pc_gnutls_CFLAGS" + CXXFLAGS="$CXXFLAGS $pc_gnutls_CXXFLAGS" + LIBS="$LIBS $pc_gnutls_LIBS" + AC_DEFINE([USE_CRYPTO_GNUTLS], 1, [Whether to use the gnutls crypto provider]) + DEFAULT_CRYPTO=gnutls +elif test "$GNUTLS_FOUND" = "1"; then + AC_MSG_NOTICE(not linking with gnutls even though it is available) +fi + +dnl Allow the default crypto provider to be specified explicitly. + +AC_MSG_CHECKING(which crypto to use by default) +AC_SUBST(DEFAULT_CRYPTO) +AC_ARG_WITH(default-crypto, + AS_HELP_STRING([--with-default-crypto=provider], + [which crypto provider to use by default; see README.md]), + [DEFAULT_CRYPTO=$withval], + []) +AC_MSG_RESULT($DEFAULT_CRYPTO) +AC_DEFINE_UNQUOTED([DEFAULT_CRYPTO], "$DEFAULT_CRYPTO", [Default crypto provider]) + +dnl Make sure the default crypto provider is actually being built. + +bad_crypto=0 +case "$DEFAULT_CRYPTO" in + "native") + if test "$USE_CRYPTO_NATIVE" != "1"; then + bad_crypto=1 + fi + ;; + "openssl") + if test "$USE_CRYPTO_OPENSSL" != "1"; then + bad_crypto=1 + fi + ;; + "gnutls") + if test "$USE_CRYPTO_GNUTLS" != "1"; then + bad_crypto=1 + fi + ;; + *) + bad_crypto=1 + ;; +esac +if test "$bad_crypto" = "1"; then + AC_MSG_ERROR(Unsupported default crypto: $DEFAULT_CRYPTO) +fi + +dnl END CRYPTO + AC_SUBST(QPDF_SKIP_TEST_COMPARE_IMAGES) AC_ARG_ENABLE(test-compare-images, AS_HELP_STRING([--enable-test-compare-images], @@ -423,6 +757,17 @@ fi], [VALIDATE_DOC=$doc_default]) +AC_SUBST(OSS_FUZZ) +AC_ARG_ENABLE(oss-fuzz, + AS_HELP_STRING([--enable-oss-fuzz], + [if set, build static fuzzers for oss-fuzz]), + [if test "$enableval" = "yes"; then + OSS_FUZZ=1; + else + OSS_FUZZ=0; + fi], + [OSS_FUZZ=0]) + if test "$VALIDATE_DOC" = "1"; then if test "$XMLLINT" = ""; then MISSING_XMLLINT=1 diff -Nru qpdf-8.0.2/debian/bash-completion qpdf-10.0.1/debian/bash-completion --- qpdf-8.0.2/debian/bash-completion 1970-01-01 00:00:00.000000000 +0000 +++ qpdf-10.0.1/debian/bash-completion 2020-04-10 17:39:17.000000000 +0000 @@ -0,0 +1 @@ +eval $(/usr/bin/qpdf --completion-bash) diff -Nru qpdf-8.0.2/debian/changelog qpdf-10.0.1/debian/changelog --- qpdf-8.0.2/debian/changelog 2018-04-15 20:24:12.000000000 +0000 +++ qpdf-10.0.1/debian/changelog 2020-06-07 17:42:10.000000000 +0000 @@ -1,3 +1,140 @@ +qpdf (10.0.1-3) bionic; urgency=medium + + * Repackaged for bionic + + -- REMnux Distribution Sun, 07 Jun 2020 13:42:10 -0400 + +qpdf (10.0.1-2) unstable; urgency=medium + + * Apply patch to link with -latomic if needed. (Closes: #902642) + + -- Jay Berkenbilt Fri, 10 Apr 2020 13:39:17 -0400 + +qpdf (10.0.1-1) unstable; urgency=medium + + * New upstream release. + + -- Jay Berkenbilt Thu, 09 Apr 2020 17:16:38 -0400 + +qpdf (10.0.0-1) experimental; urgency=medium + + * New upstream release. + + -- Jay Berkenbilt Mon, 06 Apr 2020 13:02:11 -0400 + +qpdf (9.1.1-1) unstable; urgency=medium + + * New upstream release. + * Update standards to 4.5.0. No changes required. + + -- Jay Berkenbilt Sun, 26 Jan 2020 21:08:43 -0500 + +qpdf (9.1.0-1) unstable; urgency=medium + + * New upstream release. + + -- Jay Berkenbilt Sun, 17 Nov 2019 08:24:01 -0500 + +qpdf (9.1~rc1-1) experimental; urgency=medium + + * New upstream release. + * Includes build dependency on gnutls to use gnutls crypto provider + instead of qpdf's native crypto. + + -- Jay Berkenbilt Sun, 10 Nov 2019 21:38:01 -0500 + +qpdf (9.0.2-1) unstable; urgency=medium + + * New upstream release. + + -- Jay Berkenbilt Sun, 13 Oct 2019 20:42:32 -0400 + +qpdf (9.0.1-1) unstable; urgency=medium + + * New upstream release. + * Upstream release includes detection of duplicated dictionary keys. + (Closes: #933397) + + -- Jay Berkenbilt Fri, 20 Sep 2019 09:35:45 -0400 + +qpdf (9.0.0-2) unstable; urgency=medium + + * Patch for integer conversion warnings on big-endian systems and to fix + a test failure (from a bad test, not a coding error) for systems where + char is unsigned. + + -- Jay Berkenbilt Tue, 17 Sep 2019 19:18:59 -0400 + +qpdf (9.0.0-1) unstable; urgency=medium + + * Use https on download address in copyright file. (Closes: #933401) + * Update standards to 4.4.0. No changes required. + * New upstream release. + + -- Jay Berkenbilt Sat, 31 Aug 2019 21:45:41 -0400 + +qpdf (8.4.2-1) unstable; urgency=medium + + * Update standards to 4.3.0. No changes required. + * New upstream release. + + -- Jay Berkenbilt Sat, 18 May 2019 09:55:37 -0400 + +qpdf (8.4.1-1) unstable; urgency=medium + + * New upstream release. + + -- Jay Berkenbilt Sat, 27 Apr 2019 22:13:00 -0400 + +qpdf (8.4.0-2) unstable; urgency=medium + + * Stop having library packages recommend binary packages. I'm not sure + this was ever done or why it took so long to notice. (Closes: #921722) + + -- Jay Berkenbilt Fri, 08 Feb 2019 17:43:33 -0500 + +qpdf (8.4.0-1) unstable; urgency=medium + + * New upstream release. + + -- Jay Berkenbilt Sat, 02 Feb 2019 09:42:59 -0500 + +qpdf (8.3.0-2) unstable; urgency=medium + + * Fix potential data loss. The change is already in master. Details in + https://github.com/qpdf/qpdf/issues/276 + + -- Jay Berkenbilt Thu, 17 Jan 2019 10:52:00 -0500 + +qpdf (8.3.0-1) unstable; urgency=medium + + * New upstream release. + * Install bash and zsh completion files. + + -- Jay Berkenbilt Mon, 07 Jan 2019 18:47:47 -0500 + +qpdf (8.2.1-1) unstable; urgency=medium + + * New upstream release. + * Change interpreter path for fix-qdf to not use /usr/bin/env + * Update standards version to 4.2.0 + + -- Jay Berkenbilt Sat, 18 Aug 2018 11:21:48 -0400 + +qpdf (8.2.0-1) unstable; urgency=medium + + * New upstream release. + * Includes documentation fixes reported as debian bug. (Closes: #902642) + + -- Jay Berkenbilt Fri, 17 Aug 2018 21:32:53 -0400 + +qpdf (8.1.0-1) unstable; urgency=medium + + * New upstream release. + * Includes fix for CVE-2018-9918 + + -- Jay Berkenbilt Sat, 23 Jun 2018 09:17:28 -0400 + qpdf (8.0.2-3) unstable; urgency=medium * Add patch for CVE-2018-9918 from upstream commit diff -Nru qpdf-8.0.2/debian/control qpdf-10.0.1/debian/control --- qpdf-8.0.2/debian/control 2018-04-15 20:24:12.000000000 +0000 +++ qpdf-10.0.1/debian/control 2020-04-10 17:39:17.000000000 +0000 @@ -1,18 +1,17 @@ Source: qpdf Section: libs Priority: optional -Build-Depends: debhelper (>> 10.3~), libjpeg-dev, zlib1g-dev +Build-Depends: debhelper (>> 10.3~), libjpeg-dev, zlib1g-dev, libgnutls28-dev Maintainer: Jay Berkenbilt -Standards-Version: 4.1.3 +Standards-Version: 4.5.0 Homepage: http://qpdf.sourceforge.net -Package: libqpdf21 +Package: libqpdf28 Section: libs Architecture: any Multi-Arch: same Pre-Depends: ${misc:Pre-Depends} Depends: ${misc:Depends}, ${shlibs:Depends} -Recommends: qpdf Description: runtime library for PDF transformation/inspection software QPDF is a program that can be used to linearize (web-optimize), encrypt (password-protect), decrypt, and inspect PDF files from the @@ -39,8 +38,7 @@ Architecture: any Multi-Arch: same Pre-Depends: ${misc:Pre-Depends} -Depends: ${misc:Depends}, libqpdf21 (= ${binary:Version}), libjpeg-dev, zlib1g-dev -Recommends: qpdf +Depends: ${misc:Depends}, libqpdf28 (= ${binary:Version}), libjpeg-dev, zlib1g-dev Description: development files for PDF transformation/inspection library QPDF is a program that can be used to linearize (web-optimize), encrypt (password-protect), decrypt, and inspect PDF files from the diff -Nru qpdf-8.0.2/debian/copyright qpdf-10.0.1/debian/copyright --- qpdf-8.0.2/debian/copyright 2018-04-15 20:24:12.000000000 +0000 +++ qpdf-10.0.1/debian/copyright 2020-04-10 17:39:17.000000000 +0000 @@ -1,12 +1,12 @@ This package was debianized by Jay Berkenbilt on April 26, 2008. -It was downloaded from http://github.com/qpdf/qpdf/releases +It can be downloaded from https://github.com/qpdf/qpdf/releases Upstream Maintainers: Jay Berkenbilt -For these files: +For these files, which are no longer built in the debian package: libqpdf/sph/sph_sha2.h libqpdf/sph/sph_types.h @@ -39,7 +39,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------- -For the file libqpdf/MD5.cc, the following copyright applies: +For the file libqpdf/MD5_native.cc, which is no longer built in the +debian package, the following copyright applies: ---------------------------------------------------------------------- Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All diff -Nru qpdf-8.0.2/debian/libqpdf21.install qpdf-10.0.1/debian/libqpdf21.install --- qpdf-8.0.2/debian/libqpdf21.install 2018-04-15 20:24:12.000000000 +0000 +++ qpdf-10.0.1/debian/libqpdf21.install 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -debian/tmp/usr/lib/*/libqpdf.so.* diff -Nru qpdf-8.0.2/debian/libqpdf21.shlibs qpdf-10.0.1/debian/libqpdf21.shlibs --- qpdf-8.0.2/debian/libqpdf21.shlibs 2018-04-15 20:24:12.000000000 +0000 +++ qpdf-10.0.1/debian/libqpdf21.shlibs 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -libqpdf 21 libqpdf21 (>> 8.0~) diff -Nru qpdf-8.0.2/debian/libqpdf28.install qpdf-10.0.1/debian/libqpdf28.install --- qpdf-8.0.2/debian/libqpdf28.install 1970-01-01 00:00:00.000000000 +0000 +++ qpdf-10.0.1/debian/libqpdf28.install 2020-04-10 17:39:17.000000000 +0000 @@ -0,0 +1 @@ +debian/tmp/usr/lib/*/libqpdf.so.* diff -Nru qpdf-8.0.2/debian/libqpdf28.shlibs qpdf-10.0.1/debian/libqpdf28.shlibs --- qpdf-8.0.2/debian/libqpdf28.shlibs 1970-01-01 00:00:00.000000000 +0000 +++ qpdf-10.0.1/debian/libqpdf28.shlibs 2020-04-10 17:39:17.000000000 +0000 @@ -0,0 +1 @@ +libqpdf 28 libqpdf28 (>> 10.0~) diff -Nru qpdf-8.0.2/debian/patches/atomic qpdf-10.0.1/debian/patches/atomic --- qpdf-8.0.2/debian/patches/atomic 1970-01-01 00:00:00.000000000 +0000 +++ qpdf-10.0.1/debian/patches/atomic 2020-04-10 17:39:17.000000000 +0000 @@ -0,0 +1,111 @@ +Description: link with -latomic if needed +Origin: upstream, https://github.com/qpdf/qpdf/commit/66198f447f45a87718b6457756976baa8defb2fd +Bug-Debian: http://bugs.debian.org/956400 + +commit 66198f447f45a87718b6457756976baa8defb2fd +Author: Jay Berkenbilt +Date: Fri Apr 10 13:30:00 2020 -0400 + + Use -latomic if needed with gcc + +Index: qpdf/autofiles.sums +=================================================================== +--- qpdf.orig/autofiles.sums ++++ qpdf/autofiles.sums +@@ -1,4 +1,4 @@ +-e764290be37a921ecba94755b6da22dd9e9b98644b8fdfdd0fa7f1331ce56a05 configure.ac ++c9b8555013e70c93572e0be5f5c7c03c6b7e0680de4870010945357a02909eaa configure.ac + d3f9ee6f6f0846888d9a10fd3dad2e4b1258be84205426cf04d7cef02d61dad7 aclocal.m4 + b0ce6d1dba8effa47d25154b2bb56eddafc997254a0f3f903cf9b6abffc03616 libqpdf/qpdf/qpdf-config.h.in + 5297971a0ef90bcd5563eb3f7127a032bb76d3ae2af7258bf13479caf8983a60 m4/ax_cxx_compile_stdcxx.m4 +Index: qpdf/configure +=================================================================== +--- qpdf.orig/configure ++++ qpdf/configure +@@ -16975,6 +16975,49 @@ ac_link='$CC -o conftest$ac_exeext $CFLA + ac_compiler_gnu=$ac_cv_c_compiler_gnu + + ++ac_ext=cpp ++ac_cpp='$CXXCPP $CPPFLAGS' ++ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use -latomic" >&5 ++$as_echo_n "checking whether to use -latomic... " >&6; } ++oLDFLAGS="$LDFLAGS" ++LDFLAGS="$LDFLAGS -Wl,--as-needed -latomic" ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++#include ++ int main() ++ { ++ static std::atomic a{0}; ++ a = a.fetch_add(1); ++ return 0; ++ } ++ ++_ACEOF ++if ac_fn_cxx_try_link "$LINENO"; then : ++ qpdf_USE_ATOMIC=1 ++else ++ qpdf_USE_ATOMIC=0 ++fi ++rm -f core conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++if test "$qpdf_USE_ATOMIC" = "1"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 ++$as_echo "yes" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++ LDFLAGS="$oLDFLAGS" ++fi ++ac_ext=c ++ac_cpp='$CPP $CPPFLAGS' ++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_c_compiler_gnu ++ ++ + if test "x$qpdf_OS_SECURE_RANDOM" = "x1"; then + OLIBS=$LIBS + LIBS="$LIBS Advapi32.lib" +Index: qpdf/configure.ac +=================================================================== +--- qpdf.orig/configure.ac ++++ qpdf/configure.ac +@@ -240,6 +240,32 @@ for i in 0 1; do + done + AC_LANG_POP + ++AC_LANG_PUSH([C++]) ++AC_MSG_CHECKING(whether to use -latomic) ++dnl On some platforms with some versions of gcc, you have to link with ++dnl -latomic in order for std::atomic to work. Passing --as-needed ++dnl prevents unnecessary linking with -latomic. ++oLDFLAGS="$LDFLAGS" ++LDFLAGS="$LDFLAGS -Wl,--as-needed -latomic" ++AC_LINK_IFELSE([AC_LANG_SOURCE( ++ [[#include ++ int main() ++ { ++ static std::atomic a{0}; ++ a = a.fetch_add(1); ++ return 0; ++ } ++ ]])], ++ [qpdf_USE_ATOMIC=1], ++ [qpdf_USE_ATOMIC=0]) ++if test "$qpdf_USE_ATOMIC" = "1"; then ++ AC_MSG_RESULT(yes) ++else ++ AC_MSG_RESULT(no) ++ LDFLAGS="$oLDFLAGS" ++fi ++AC_LANG_POP ++ + if test "x$qpdf_OS_SECURE_RANDOM" = "x1"; then + OLIBS=$LIBS + LIBS="$LIBS Advapi32.lib" diff -Nru qpdf-8.0.2/debian/patches/CVE-2018-9918.patch qpdf-10.0.1/debian/patches/CVE-2018-9918.patch --- qpdf-8.0.2/debian/patches/CVE-2018-9918.patch 2018-04-15 20:24:12.000000000 +0000 +++ qpdf-10.0.1/debian/patches/CVE-2018-9918.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,72 +0,0 @@ -Index: qpdf/ChangeLog -=================================================================== ---- qpdf.orig/ChangeLog -+++ qpdf/ChangeLog -@@ -1,3 +1,8 @@ -+2018-04-15 Jay Berkenbilt -+ -+ * Arbitrarily limit the depth of data structures represented by -+ direct object. This is CVE-2018-9918. Fixes #202. -+ - 2018-03-06 Jay Berkenbilt - - * 8.0.2: release -Index: qpdf/libqpdf/QPDFObjectHandle.cc -=================================================================== ---- qpdf.orig/libqpdf/QPDFObjectHandle.cc -+++ qpdf/libqpdf/QPDFObjectHandle.cc -@@ -1487,12 +1487,26 @@ QPDFObjectHandle::parseInternal(PointerH - - case QPDFTokenizer::tt_array_open: - case QPDFTokenizer::tt_dict_open: -- olist_stack.push_back(std::vector()); -- state = st_start; -- offset_stack.push_back(input->tell()); -- state_stack.push_back( -- (token.getType() == QPDFTokenizer::tt_array_open) ? -- st_array : st_dictionary); -+ if (olist_stack.size() > 500) -+ { -+ QTC::TC("qpdf", "QPDFObjectHandle too deep"); -+ warn(context, -+ QPDFExc(qpdf_e_damaged_pdf, input->getName(), -+ object_description, -+ input->getLastOffset(), -+ "ignoring excessively deeply nested data structure")); -+ object = newNull(); -+ state = st_top; -+ } -+ else -+ { -+ olist_stack.push_back(std::vector()); -+ state = st_start; -+ offset_stack.push_back(input->tell()); -+ state_stack.push_back( -+ (token.getType() == QPDFTokenizer::tt_array_open) ? -+ st_array : st_dictionary); -+ } - break; - - case QPDFTokenizer::tt_bool: -Index: qpdf/qpdf/qpdf.testcov -=================================================================== ---- qpdf.orig/qpdf/qpdf.testcov -+++ qpdf/qpdf/qpdf.testcov -@@ -335,3 +335,4 @@ QPDFObjectHandle numeric non-numeric 0 - QPDFObjectHandle erase array bounds 0 - qpdf-c called qpdf_check_pdf 0 - QPDF xref loop 0 -+QPDFObjectHandle too deep 0 -Index: qpdf/qpdf/qtest/qpdf/issue-146.out -=================================================================== ---- qpdf.orig/qpdf/qtest/qpdf/issue-146.out -+++ qpdf/qpdf/qtest/qpdf/issue-146.out -@@ -1,7 +1,5 @@ - WARNING: issue-146.pdf: file is damaged - WARNING: issue-146.pdf: can't find startxref - WARNING: issue-146.pdf: Attempting to reconstruct cross-reference table --WARNING: issue-146.pdf (trailer, offset 20728): unknown token while reading object; treating as string --WARNING: issue-146.pdf (trailer, offset 20732): unexpected EOF --WARNING: issue-146.pdf (trailer, offset 20732): parse error while reading object -+WARNING: issue-146.pdf (trailer, offset 695): ignoring excessively deeply nested data structure - issue-146.pdf: unable to find trailer dictionary while recovering damaged file diff -Nru qpdf-8.0.2/debian/patches/series qpdf-10.0.1/debian/patches/series --- qpdf-8.0.2/debian/patches/series 2018-04-15 20:24:12.000000000 +0000 +++ qpdf-10.0.1/debian/patches/series 2020-04-10 17:39:17.000000000 +0000 @@ -1 +1 @@ -CVE-2018-9918.patch +atomic diff -Nru qpdf-8.0.2/debian/rules qpdf-10.0.1/debian/rules --- qpdf-8.0.2/debian/rules 2018-04-15 20:24:12.000000000 +0000 +++ qpdf-10.0.1/debian/rules 2020-04-10 17:39:17.000000000 +0000 @@ -19,7 +19,8 @@ override_dh_auto_configure: dh_auto_configure -- \ --libdir="\$${prefix}/lib/$(DEB_HOST_MULTIARCH)" \ - --enable-show-failed-test-output + --enable-crypto-gnutls --disable-implicit-crypto \ + --enable-show-failed-test-output --disable-check-autofiles override_dh_install: dh_install @@ -27,4 +28,10 @@ cp -p examples/*.cc examples/*.c \ debian/libqpdf-dev/usr/share/doc/libqpdf-dev/examples cp -p README.md debian/libqpdf-dev/usr/share/doc/libqpdf-dev/README.md + mkdir -p debian/qpdf/usr/share/bash-completion/completions + cp completions/bash/qpdf \ + debian/qpdf/usr/share/bash-completion/completions/qpdf + mkdir -p debian/qpdf/usr/share/zsh/vendor-completions + cp completions/zsh/_qpdf \ + debian/qpdf/usr/share/zsh/vendor-completions/_qpdf dh_missing --list-missing -X.la diff -Nru qpdf-8.0.2/debian/zsh-completion qpdf-10.0.1/debian/zsh-completion --- qpdf-8.0.2/debian/zsh-completion 1970-01-01 00:00:00.000000000 +0000 +++ qpdf-10.0.1/debian/zsh-completion 2020-04-10 17:39:17.000000000 +0000 @@ -0,0 +1,2 @@ +#compdef qpdf +eval $(/usr/bin/qpdf --completion-zsh) diff -Nru qpdf-8.0.2/doc/qpdf-manual.html qpdf-10.0.1/doc/qpdf-manual.html --- qpdf-8.0.2/doc/qpdf-manual.html 2018-03-06 16:46:49.000000000 +0000 +++ qpdf-10.0.1/doc/qpdf-manual.html 2020-04-09 16:09:10.000000000 +0000 @@ -1,5 +1,5 @@ -QPDF Manual

QPDF Manual

For QPDF Version 8.0.2, March 6, 2018

Jay Berkenbilt


General Information

+QPDF Manual

QPDF Manual

For QPDF Version 10.0.1, April 9, 2020

Jay Berkenbilt


Table of Contents

General Information
1. What is QPDF?
2. Building and Installing QPDF
2.1. System Requirements
2.2. Build Instructions
2.3. Crypto Providers
2.3.1. Build Support For Crypto Providers
2.3.2. Runtime Crypto Provider Selection
2.3.3. Crypto Provider Information for Developers
2.3.4. Crypto Provider Design Notes
2.4. Notes for Packagers
3. Running QPDF
3.1. Basic Invocation
3.2. Shell Completion
3.3. Basic Options
3.4. Encryption Options
3.5. Page Selection Options
3.6. Overlay and Underlay Options
3.7. Advanced Parsing Options
3.8. Advanced Transformation Options
3.9. Testing, Inspection, and Debugging Options
3.10. Unicode Passwords
4. QDF Mode
5. Using the QPDF Library
5.1. Using QPDF from C++
5.2. Using QPDF from other languages
5.3. A Note About Unicode File Names
6. QPDF JSON
6.1. Overview
6.2. JSON Guarantees
6.3. Limitations of JSON Representation
6.4. JSON: Special Considerations
7. Design and Library Notes
7.1. Introduction
7.2. Design Goals
7.3. Helper Classes
7.4. Implementation Notes
7.5. Casting Policy
7.6. Encryption
7.7. Random Number Generation
7.8. Adding and Removing Pages
7.9. Reserving Object Numbers
7.10. Copying Objects From Other PDF Files
7.11. Writing PDF Files
7.12. Filtered Streams
8. Linearization
8.1. Basic Strategy for Linearization
8.2. Preparing For Linearization
8.3. Optimization
8.4. Writing Linearized Files
8.5. Calculating Linearization Data
8.6. Known Issues with Linearization
8.7. Debugging Note
9. Object and Cross-Reference Streams
9.1. Object Streams
9.2. Cross-Reference Streams
9.2.1. Cross-Reference Stream Data
9.3. Implications for Linearized Files
9.4. Implementation Notes
A. Release Notes
B. Upgrading from 2.0 to 2.1
C. Upgrading to 3.0
D. Upgrading to 4.0

General Information

QPDF is a program that does structural, content-preserving transformations on PDF files. QPDF's website is located at http://qpdf.sourceforge.net/. QPDF's source code is hosted on github at https://github.com/qpdf/qpdf. @@ -64,7 +64,7 @@ your original PDF creation can't handle. For example, many programs generate simple PDF files but can't password-protect them, web-optimize them, or perform other transformations of that type. -

Chapter 2. Building and Installing QPDF

+

Chapter 2. Building and Installing QPDF

This chapter describes how to build and install qpdf. Please see also the README.md and INSTALL files in the source distribution. @@ -72,26 +72,31 @@ The qpdf package has few external dependencies. In order to build qpdf, the following packages are required:

  • + A C++ compiler that supports C++-11. +

  • zlib: http://www.zlib.net/

  • jpeg: http://www.ijg.org/files/ or https://libjpeg-turbo.org/

  • + Recommended but not required: gnutls: + https://www.gnutls.org/ + to be able to use the gnutls crypto provider, and/or openssl: + https://openssl.org/ + to be able to use the openssl crypto provider. +

  • gnu make 3.81 or newer: http://www.gnu.org/software/make

  • perl version 5.8 or newer: http://www.perl.org/; - required for fix-qdf and the test suite. + required for running the test suite. Starting with qpdf version + 9.1.1, perl is no longer required at runtime.

  • GNU diffutils (any version): http://www.gnu.org/software/diffutils/ is required to run the test suite. Note that this is the version of diff present on virtually all GNU/Linux systems. This is required because the test suite uses diff -u. -

  • - A C++ compiler that works well with STL and has the long - long type. Most modern C++ compilers should fit the bill - fine. QPDF is tested with gcc, clang, and Microsoft Visual C++.

Part of qpdf's test suite does comparisons of the contents PDF @@ -120,14 +125,6 @@ If you do not enable this, then you do not need to have tiff and ghostscript.

- If Adobe Reader is installed as acroread, some - additional test cases will be enabled. These test cases simply - verify that Adobe Reader can open the files that qpdf creates. - They require version 8.0 or newer to pass. However, in order to - avoid having qpdf depend on non-free (as in liberty) software, the - test suite will still pass without Adobe reader, and the test - suite still exercises the full functionality of the software. -

Pre-built documentation is distributed with qpdf, so you should generally not need to rebuild the documentation. In order to build the documentation from its docbook sources, you need the @@ -158,13 +155,242 @@ Jian Ma. This is also discussed in more detail in README-windows.md.

+ While wchar_t is part of the C++ standard, qpdf uses + it in only one place in the public API, and it's just in a helper + function. It is possible to build qpdf on a system that doesn't + have wchar_t, and it's also possible to compile a + program that uses qpdf on a system without wchar_t as + long as you don't call that one method. This is a very unusual + situation. For a detailed discussion, please see the top-level + README.md file in qpdf's source distribution. +

There are some other things you can do with the build. Although qpdf uses autoconf, it does not use automake but instead uses a hand-crafted non-recursive Makefile that requires gnu make. If you're really interested, please read the comments in the top-level Makefile. -

2.3. Crypto Providers

+ Starting with qpdf 9.1.0, the qpdf library can be built with + multiple implementations of providers of cryptographic functions, + which we refer to as “crypto providers.†At the time + of writing, a crypto implementation must provide MD5 and SHA2 + (256, 384, and 512-bit) hashes and RC4 and AES256 with and without + CBC encryption. In the future, if digital signature is added to + qpdf, there may be additional requirements beyond this. +

+ Starting with qpdf version 9.1.0, the available implementations + are native and gnutls. In + qpdf 10.0.0, openssl was added. Additional + implementations may be added if needed. It is also possible for a + developer to provide their own implementation without modifying + the qpdf library. +

2.3.1. Build Support For Crypto Providers

+ When building with qpdf's build system, crypto providers can be + enabled at build time using various + ./configure options. The default behavior is + for ./configure to discover which crypto + providers can be supported based on available external libraries, + to build all available crypto providers, and to use an external + provider as the default over the native one. This behavior can be + changed with the following flags to + ./configure: +

  • + --enable-crypto-x + (where x is a supported crypto + provider): enable the x crypto + provider, requiring any external dependencies it needs +

  • + --disable-crypto-x: + disable the x provider, and do not + link against its dependencies even if they are available +

  • + --with-default-crypto=x: + make x the default provider even if + a higher priority one is available +

  • + --disable-implicit-crypto: only build crypto + providers that are explicitly requested with an + --enable-crypto-x + option +

+

+ For example, if you want to guarantee that the gnutls crypto + provider is used and that the native provider is not built, you + could run ./configure --enable-crypto-gnutls + --disable-implicit-crypto. +

+ If you build qpdf using your own build system, in order for qpdf + to work at all, you need to enable at least one crypto provider. + The file libqpdf/qpdf/qpdf-config.h.in + provides macros DEFAULT_CRYPTO, whose value + must be a string naming the default crypto provider, and various + symbols starting with USE_CRYPTO_, at least + one of which has to be enabled. Additionally, you must compile + the source files that implement a crypto provider. To get a list + of those files, look at libqpdf/build.mk. If + you want to omit a particular crypto provider, as long as its + USE_CRYPTO_ symbol is undefined, you can + completely ignore the source files that belong to a particular + crypto provider. Additionally, crypto providers may have their + own external dependencies that can be omitted if the crypto + provider is not used. For example, if you are building qpdf + yourself and are using an environment that does not support + gnutls or openssl, you can ensure that + USE_CRYPTO_NATIVE is defined, + USE_CRYPTO_GNUTLS is not defined, and + DEFAULT_CRYPTO is defined to + "native". Then you must include the source + files used in the native implementation, some of which were added + or renamed from earlier versions, to your build, and you can + ignore QPDFCrypto_gnutls.cc. Always consult + libqpdf/build.mk to get the list of source + files you need to build. +

2.3.2. Runtime Crypto Provider Selection

+ You can use the --show-crypto option to + qpdf to get a list of available crypto + providers. The default provider is always listed first, and the + rest are listed in lexical order. Each crypto provider is listed + on a line by itself with no other text, enabling the output of + this command to be used easily in scripts. +

+ You can override which crypto provider is used by setting the + QPDF_CRYPTO_PROVIDER environment variable. + There are few reasons to ever do this, but you might want to do + it if you were explicitly trying to compare behavior of two + different crypto providers while testing performance or + reproducing a bug. It could also be useful for people who are + implementing their own crypto providers. +

2.3.3. Crypto Provider Information for Developers

+ If you are writing code that uses libqpdf and you want to force a + certain crypto provider to be used, you can call the method + QPDFCryptoProvider::setDefaultProvider. The + argument is the name of a built-in or developer-supplied + provider. To add your own crypto provider, you have to create a + class derived from QPDFCryptoImpl and + register it with QPDFCryptoProvider. For + additional information, see comments in + include/qpdf/QPDFCryptoImpl.hh. +

2.3.4. Crypto Provider Design Notes

+ This section describes a few bits of rationale for why the crypto + provider interface was set up the way it was. You don't need to + know any of this information, but it's provided for the record + and in case it's interesting. +

+ As a general rule, I want to avoid as much as possible including + large blocks of code that are conditionally compiled such that, + in most builds, some code is never built. This is dangerous + because it makes it very easy for invalid code to creep in + unnoticed. As such, I want it to be possible to build qpdf with + all available crypto providers, and this is the way I build qpdf + for local development. At the same time, if a particular packager + feels that it is a security liability for qpdf to use crypto + functionality from other than a library that gets considerable + scrutiny for this specific purpose (such as gnutls, openssl, or + nettle), then I want to give that packager the ability to + completely disable qpdf's native implementation. Or if someone + wants to avoid adding a dependency on one of the external crypto + providers, I don't want the availability of the provider to + impose additional external dependencies within that environment. + Both of these are situations that I know to be true for some + users of qpdf. +

+ I want registration and selection of crypto providers to be + thread-safe, and I want it to work deterministically for a + developer to provide their own crypto provider and be able to set + it up as the default. This was the primary motivation behind + requiring C++-11 as doing so enabled me to exploit the guaranteed + thread safety of local block static initialization. The + QPDFCryptoProvider class uses a singleton + pattern with thread-safe initialization to create the singleton + instance of QPDFCryptoProvider and exposes + only static methods in its public interface. In this way, if a + developer wants to call any + QPDFCryptoProvider methods, the library + guarantees the QPDFCryptoProvider is fully + initialized and all built-in crypto providers are registered. + Making QPDFCryptoProvider actually know + about all the built-in providers may seem a bit sad at first, but + this choice makes it extremely clear exactly what the + initialization behavior is. There's no question about provider + implementations automatically registering themselves in a + nondeterministic order. It also means that implementations do not + need to know anything about the provider interface, which makes + them easier to test in isolation. Another advantage of this + approach is that a developer who wants to develop their own + crypto provider can do so in complete isolation from the qpdf + library and, with just two calls, can make qpdf use their + provider in their application. If they decided to contribute + their code, plugging it into the qpdf library would require a + very small change to qpdf's source code. +

+ The decision to make the crypto provider selectable at runtime + was one I struggled with a little, but I decided to do it for + various reasons. Allowing an end user to switch crypto providers + easily could be very useful for reproducing a potential bug. If a + user reports a bug that some cryptographic thing is broken, I can + easily ask that person to try with the + QPDF_CRYPTO_PROVIDER variable set to different + values. The same could apply in the event of a performance + problem. This also makes it easier for qpdf's own test suite to + exercise code with different providers without having to make + every program that links with qpdf aware of the possibility of + multiple providers. In qpdf's continuous integration environment, + the entire test suite is run for each supported crypto provider. + This is made simple by being able to select the provider using an + environment variable. +

+ Finally, making crypto providers selectable in this way establish + a pattern that I may follow again in the future for stream filter + providers. One could imagine a future enhancement where someone + could provide their own implementations for basic filters like + /FlateDecode or for other filters that qpdf + doesn't support. Implementing the registration functions and + internal storage of registered providers was also easier using + C++-11's functional interfaces, which was another reason to + require C++-11 at this time. +

2.4. Notes for Packagers

+ If you are packaging qpdf for an operating system distribution, + here are some things you may want to keep in mind: +

  • + Starting in qpdf version 9.1.1, qpdf no longer has a runtime + dependency on perl. This is because fix-qdf was rewritten in + C++. However, qpdf still has a build-time dependency on perl. +

  • + Make sure you are getting the intended behavior with regard to + crypto providers. Read Section 2.3.1, “Build Support For Crypto Providers†for + details. +

  • + Passing --enable-show-failed-test-output to + ./configure will cause any failed test + output to be written to the console. This can be very useful + for seeing test failures generated by autobuilders where you + can't access qtest.log after the fact. +

  • + If qpdf's build environment detects the presence of autoconf + and related tools, it will check to ensure that automatically + generated files are up-to-date with recorded checksums and fail + if it detects a discrepancy. This feature is intended to + prevent you from accidentally forgetting to regenerate + automatic files after modifying their sources. If your + packaging environment automatically refreshes automatic files, + it can cause this check to fail. Suppress qpdf's checks by + passing --disable-check-autofiles to + /.configure. This is safe since qpdf's + autogen.sh just runs autotools in the normal + way. +

  • + QPDF's make install does not install + completion files by default, but as a packager, it's good if + you install them wherever your distribution expects such files + to go. You can find completion files to install in the + completions directory. +

  • + Packagers are encouraged to install the source files from the + examples directory along with qpdf + development packages. +

+

Chapter 3. Running QPDF

This chapter describes how to run the qpdf program from the command line.

3.1. Basic Invocation

@@ -181,7 +407,7 @@ parameter --empty may be specified. This causes qpdf to use a dummy input file that contains zero pages. The only normal use case for using --empty would be if you - were going to add pages from another source, as discussed in Section 3.4, “Page Selection Optionsâ€. + were going to add pages from another source, as discussed in Section 3.5, “Page Selection Optionsâ€.

If @filename appears anywhere in the command-line, it will be read line by line, and each line will be @@ -194,23 +420,98 @@ outfilename does not have to be seekable, even when generating linearized files. Specifying “-†as outfilename - means to write to standard output. However, you can't specify the - same file as both the input and the output because qpdf reads data - from the input file as it writes to the output file. QPDF attempts - to detect this case and fail without overwriting the output file. + means to write to standard output. If you want to overwrite the + input file with the output, use the option + --replace-input and omit the output file name. + You can't specify the same file as both the input and the output. + If you do this, qpdf will tell you about the + --replace-input option.

Most options require an output file, but some testing or inspection commands do not. These are specifically noted. -

3.2. Basic Options

+

3.2. Shell Completion

+ Starting in qpdf version 8.3.0, qpdf provides its own completion + support for zsh and bash. You can enable bash completion with + eval $(qpdf --completion-bash) and zsh + completion with eval $(qpdf --completion-zsh). + If qpdf is not in your path, you should invoke + it above with an absolute path. If you invoke it with a relative + path, it will warn you, and the completion won't work if you're in + a different directory. +

+ qpdf will use argv[0] to figure out where its + executable is. This may produce unwanted results in some cases, + especially if you are trying to use completion with copy of qpdf + that is built from source. You can specify a full path to the qpdf + you want to use for completion in the + QPDF_EXECUTABLE environment variable. +

3.3. Basic Options

The following options are the most common ones and perform commonly needed transformations. -

--password=password

- Specifies a password for accessing encrypted files. +

--help

+ Display command-line invocation help. +

--version

+ Display the current version of qpdf. +

--copyright

+ Show detailed copyright information. +

--show-crypto

+ Show a list of available crypto providers, each on a line by + itself. The default provider is always listed first. See Section 2.3, “Crypto Providers†for more information about crypto + providers. +

--completion-bash

+ Output a completion command you can eval to enable shell + completion from bash. +

--completion-zsh

+ Output a completion command you can eval to enable shell + completion from zsh. +

--password=password

+ Specifies a password for accessing encrypted files. Note that + you can use @filename or @- + as described above to put the password in a file or pass it + via standard input so you can avoid specifying it on the + command line. +

--is-encrypted

+ Silently exit with status 0 if the file is encrypted or status + 2 if the file is not encrypted. This is useful for shell + scripts. Other options are ignored if this is given. This + option is mutually exclusive with + --requires-password. Both this option and + --requires-password exit with status 2 for + non-encrypted files. +

--requires-password

+ Silently exit with status 0 if a password (other than as + supplied) is required. Exit with status 2 if the file is not + encrypted. Exit with status 3 if the file is encrypted but + requires no password or the correct password has been + supplied. This is useful for shell scripts. Note that any + supplied password is used when opening the file. When used + with a --password option, this option can be + used to check the correctness of the password. In that case, + an exit status of 3 means the file works with the supplied + password. This option is mutually exclusive with + --is-encrypted. Both this option and + --is-encrypted exit with status 2 for + non-encrypted files.

--verbose

Increase verbosity of output. For now, this just prints some indication of any file that it creates. +

--progress

+ Indicate progress while writing files. +

--no-warn

+ Suppress writing of warnings to stderr. If warnings were + detected and suppressed, qpdf will still + exit with exit code 3.

--linearize

Causes generation of a linearized (web-optimized) output file. +

--replace-input

+ If specified, the output file name should be omitted. This + option tells qpdf to replace the input file with the output. + It does this by writing to + infilename.~qpdf-temp# + and, when done, overwriting the input file with the temporary + file. If there were any warnings, the original input is saved + as + infilename.~qpdf-orig.

--copy-encryption=file

Encrypt the file using the same encryption parameters, including user and owner password, as the specified file. Use @@ -228,7 +529,7 @@ preserve encryption parameters, including the owner password, from a file even if you don't know the file's owner password.

--encrypt options --

- Causes generation an encrypted output file. Please see Section 3.3, “Encryption Options†for details on how to + Causes generation an encrypted output file. Please see Section 3.4, “Encryption Options†for details on how to specify encryption parameters.

--decrypt

Removes any encryption on the file. A password must be @@ -255,22 +556,110 @@ the encryption key used by an encrypted file that you can open normally, use the --show-encryption-key option. -

--rotate=[+|-]angle:page-range

+

--suppress-password-recovery

+ Ordinarily, qpdf attempts to automatically compensate for + passwords specified in the wrong character encoding. This + option suppresses that behavior. Under normal conditions, + there are no reasons to use this option. See Section 3.10, “Unicode Passwords†for a discussion +

--password-mode=mode

+ This option can be used to fine-tune how qpdf interprets + Unicode (non-ASCII) password strings passed on the command + line. With the exception of the hex-bytes + mode, these only apply to passwords provided when encrypting + files. The hex-bytes mode also applies to + passwords specified for reading files. For additional + discussion of the supported password modes and when you might + want to use them, see Section 3.10, “Unicode Passwordsâ€. + The following modes are supported: +

  • + auto: Automatically determine whether the + specified password is a properly encoded Unicode (UTF-8) + string, and transcode it as required by the PDF spec based + on the type encryption being applied. On Windows starting + with version 8.4.0, and on almost all other modern + platforms, incoming passwords will be properly encoded in + UTF-8, so this is almost always what you want. +

  • + unicode: Tells qpdf that the incoming + password is UTF-8, overriding whatever its automatic + detection determines. The only difference between this mode + and auto is that qpdf will fail with an + error message if the password is not valid UTF-8 instead of + falling back to bytes mode with a warning. +

  • + bytes: Interpret the password as a literal + byte string. For non-Windows platforms, this is what + versions of qpdf prior to 8.4.0 did. For Windows platforms, + there is no way to specify strings of binary data on the + command line directly, but you can use the + @filename option to do it, in which case + this option forces qpdf to respect the string of bytes as + provided. This option will allow you to encrypt PDF files + with passwords that will not be usable by other readers. +

  • + hex-bytes: Interpret the password as a + hex-encoded string. This provides a way to pass binary data + as a password on all platforms including Windows. As with + bytes, this option may allow creation of + files that can't be opened by other readers. This mode + affects qpdf's interpretation of passwords specified for + decrypting files as well as for encrypting them. It makes + it possible to specify strings that are encoded in some + manner other than the system's default encoding. +

+

--rotate=[+|-]angle[:page-range]

Apply rotation to specified pages. The page-range portion of the option value has - the same format as page ranges in Section 3.4, “Page Selection Optionsâ€. The angle - portion of the parameter may be either 90, 180, or 270. If - preceded by + or -, the - angle is added to or subtracted from the specified pages' - original rotations. Otherwise the pages' rotations are set to - the exact value. For example, the command qpdf in.pdf - out.pdf --rotate=+90:2,4,6 --rotate=180:7-8 would - rotate pages 2, 4, and 6 90 degrees clockwise from their - original rotation and force the rotation of pages 7 through 9 - to 180 degrees regardless of their original rotation. + the same format as page ranges in Section 3.5, “Page Selection Optionsâ€. If the page range is omitted, + the rotation is applied to all pages. The + angle portion of the parameter may be either + 90, 180, or 270. If preceded by + or + -, the angle is added to or subtracted from + the specified pages' original rotations. Otherwise the pages' + rotations are set to the exact value. For example, the command + qpdf in.pdf out.pdf --rotate=+90:2,4,6 + --rotate=180:7-8 would rotate pages 2, 4, and 6 90 + degrees clockwise from their original rotation and force the + rotation of pages 7 through 9 to 180 degrees regardless of + their original rotation, and the command qpdf in.pdf + out.pdf --rotate=180 would rotate all pages by 180 + degrees. +

--keep-files-open=[yn]

+ This option controls whether qpdf keeps individual files open + while merging. Prior to version 8.1.0, qpdf always kept all + files open, but this meant that the number of files that could + be merged was limited by the operating system's open file + limit. Version 8.1.0 opened files as they were referenced and + closed them after each read, but this caused a major + performance impact. Version 8.2.0 optimized the performance + but did so in a way that, for local file systems, there was a + small but unavoidable performance hit, but for networked file + systems, the performance impact could be very high. Starting + with version 8.2.1, the default behavior is that files are + kept open if no more than 200 files are specified, but that + the behavior can be explicitly overridden with the + --keep-files-open flag. If you are merging + more than 200 files but less than the operating system's max + open files limit, you may want to use + --keep-files-open=y, especially if working + over a networked file system. If you are using a local file + system where the overhead is low and you might sometimes merge + more than the OS limit's number of files from a script and are + not worried about a few seconds additional processing time, + you may want to specify --keep-files-open=n. + The threshold for switching may be changed from the default + 200 with the --keep-files-open-threshold + option. +

--keep-files-open-threshold=count

+ If specified, overrides the default value of 200 used as the + threshold for qpdf deciding whether or not to keep files open. + See --keep-files-open for details.

--pages options --

- Select specific pages from one or more input files. See Section 3.4, “Page Selection Options†for details on how to do page + Select specific pages from one or more input files. See Section 3.5, “Page Selection Options†for details on how to do page selection (splitting and merging). +

--collate

+ When specified, collate rather than concatenate pages from + files specified with --pages. See Section 3.5, “Page Selection Options†for additional details.

--split-pages=[n]

Write each group of n pages to a separate output file. If n is not specified, create @@ -316,6 +705,14 @@ --pages option once for each file. Using --split-pages is much faster if you don't require the global data. +

--overlay options --

+ Overlay pages from another file onto the output pages. See + Section 3.6, “Overlay and Underlay Options†for details on + overlay/underlay. +

--underlay options --

+ Overlay pages from another file onto the output pages. See + Section 3.6, “Overlay and Underlay Options†for details on + overlay/underlay.

Password-protected files may be opened by specifying a password. @@ -332,23 +729,17 @@ restrictions or other restrictions placed on files by their producers.

- In all cases where qpdf allows specification of a password, care - must be taken if the password contains characters that fall - outside of the 7-bit US-ASCII character range to ensure that the - exact correct byte sequence is provided. It is possible that a - future version of qpdf may handle this more gracefully. For - example, if a password was encrypted using a password that was - encoded in ISO-8859-1 and your terminal is configured to use - UTF-8, the password you supply may not work properly. There are - various approaches to handling this. For example, if you are - using Linux and have the iconv executable installed, you could - pass --password=`echo password - | iconv -t iso-8859-1` to qpdf where - password is a password specified in - your terminal's locale. A detailed discussion of this is out of - scope for this manual, but just be aware of this issue if you have - trouble with a password that contains 8-bit characters. -

3.3. Encryption Options

+ Prior to 8.4.0, in the case of passwords that contain characters + that fall outside of 7-bit US-ASCII, qpdf left the burden of + supplying properly encoded encryption and decryption passwords to + the user. Starting in qpdf 8.4.0, qpdf does this automatically in + most cases. For an in-depth discussion, please see Section 3.10, “Unicode Passwordsâ€. Previous versions of this + manual described workarounds using the iconv + command. Such workarounds are no longer required or recommended + with qpdf 8.4.0. However, for backward compatibility, qpdf + attempts to detect those workarounds and do the right thing in + most cases. +

3.4. Encryption Options

To change the encryption parameters of a file, use the --encrypt flag. The syntax is @@ -383,9 +774,29 @@ the following restriction options are available:

--accessibility=[yn]

Determines whether or not to allow accessibility to visually - impaired. + impaired. The qpdf library disregards this field when AES is + used or when 256-bit encryption is used. You should really + never disable accessibility, but qpdf lets you do it in case + you need to configure a file this way for testing purposes. + The PDF spec says that conforming readers should disregard + this permission and always allow accessibility.

--extract=[yn]

Determines whether or not to allow text/graphic extraction. +

--assemble=[yn]

+ Determines whether document assembly (rotation and reordering + of pages) is allowed. +

--annotate=[yn]

+ Determines whether modifying annotations is allowed. This + includes adding comments and filling in form fields. Also + allows editing of form fields if + --modify-other=y is given. +

--form=[yn]

+ Determines whether filling form fields is allowed. +

--modify-other=[yn]

+ Allow all document editing except those controlled separately + by the --assemble, + --annotate, and --form + options.

--print=print-opt

Controls printing access. print-opt may be @@ -398,21 +809,29 @@ none: disallow printing

--modify=modify-opt

- Controls modify access. + Controls modify access. This way of controlling modify access + has less granularity than new options added in qpdf 8.4. modify-opt may be - one of the following, each of which implies all the options - that follow it: + one of the following:

  • all: allow full document modification

  • - annotate: allow comment authoring and form operations + annotate: allow comment authoring, form + operations, and document assembly

  • form: allow form field fill-in and signing + and document assembly

  • assembly: allow document assembly only

  • none: allow no modifications

+ Using the --modify option does not allow you + to create certain combinations of permissions such as allowing + form filling but not allowing document assembly. Starting with + qpdf 8.4, you can either just use the other options to control + fields individually, or you can use something like + --modify=form --assembly=n to fine tune.

--cleartext-metadata

If specified, any metadata stream in the document will be left unencrypted even if the rest of the document is encrypted. @@ -450,7 +869,7 @@ encrypted in this way.

The default for each permission option is to be fully permissive. -

3.4. Page Selection Options

+

3.5. Page Selection Options

Starting with qpdf 3.0, it is possible to split and merge PDF files by selecting pages from one or more input files. Whatever file is given as the primary input file is used as the starting @@ -464,6 +883,10 @@ “--†terminates parsing of page selection flags.

+ Starting with qpf 8.4, the special input file name + “.†can be used shortcut for the + primary input filename. +

For each file that pages should be taken from, specify the file, a password needed to open the file (if any), and a page range. The password needs to be given only once per file. If any of the @@ -484,14 +907,6 @@ easily combine all pages in a set of files with a command like qpdf --empty out.pdf --pages *.pdf --.

- It is not presently possible to specify the same page from the - same file directly more than once, but you can make this work by - specifying two different paths to the same file (such as by - putting ./ somewhere in the path). This can - also be used if you want to repeat a page from one of the input - files in the output file. This may be made more convenient in a - future version of qpdf if there is enough demand for this feature. -

The page range is a set of numbers separated by commas, ranges of numbers separated dashes, or combinations of those. The character “z†represents the last page. A number preceded by an @@ -499,9 +914,12 @@ r3-r1 would be the last three pages of the document. Pages can appear in any order. Ranges can appear with a high number followed by a low number, which causes the pages to - appear in reverse. Repeating a number will cause an error, but you - can use the workaround discussed above should you really want to - include the same page twice. + appear in reverse. Numbers may be repeated in a page range. A page + range may be optionally appended with :even or + :odd to indicate only the even or odd pages in + the given range. Note that even and odd refer to the positions + within the specified, range, not whether the original number is + even or odd.

Example page ranges:

  • @@ -514,27 +932,53 @@

  • r1-r3: the last three pages of the document in reverse order +

  • + 1-20:even: even pages from 2 to 20 +

  • + 5,7-9,12:odd: pages 5, 8, and, 12, which are + the pages in odd positions from among the original range, which + represents pages 5, 7, 8, 9, and 12.

- Note that qpdf doesn't presently do anything special about other - constructs in a PDF file that may know about pages, so semantics - of splitting and merging vary across features. For example, the - document's outlines (bookmarks) point to actual page objects, so - if you select some pages and not others, bookmarks that point to - pages that are in the output file will work, and remaining - bookmarks will not work. On the other hand, page labels (page - numbers specified in the file) are just sequential, so page labels - will be messed up in the output file. A future version of - qpdf may do a better job at handling these - issues. (Note that the qpdf library already contains all of the - APIs required in order to implement this in your own application - if you need it.) In the mean time, you can always use - --empty as the primary input file to avoid - copying all of that from the first file. For example, to take - pages 1 through 5 from a infile.pdf while - preserving all metadata associated with that file, you could use + Starting in qpdf version 8.3, you can specify the + --collate option. Note that this option is + specified outside of --pages ... --. + When --collate is specified, it changes the + meaning of --pages so that the specified files, + as modified by page ranges, are collated rather than concatenated. + For example, if you add the files odd.pdf and + even.pdf containing odd and even pages of a + document respectively, you could run qpdf --collate + odd.pdf --pages odd.pdf even.pdf -- all.pdf to collate + the pages. This would pick page 1 from odd, page 1 from even, page + 2 from odd, page 2 from even, etc. until all pages have been + included. Any number of files and page ranges can be specified. If + any file has fewer pages, that file is just skipped when its pages + have all been included. For example, if you ran qpdf + --collate --empty --pages a.pdf 1-5 b.pdf 6-4 c.pdf r1 -- + out.pdf, you would get the following pages in this + order: +

  • a.pdf page 1

  • b.pdf page 6

  • c.pdf last page

  • a.pdf page 2

  • b.pdf page 5

  • a.pdf page 3

  • b.pdf page 4

  • a.pdf page 4

  • a.pdf page 5

+

+ Starting in qpdf version 8.3, when you split and merge files, any + page labels (page numbers) are preserved in the final file. It is + expected that more document features will be preserved by + splitting and merging. In the mean time, semantics of splitting + and merging vary across features. For example, the document's + outlines (bookmarks) point to actual page objects, so if you + select some pages and not others, bookmarks that point to pages + that are in the output file will work, and remaining bookmarks + will not work. A future version of qpdf may do + a better job at handling these issues. (Note that the qpdf library + already contains all of the APIs required in order to implement + this in your own application if you need it.) In the mean time, + you can always use --empty as the primary input + file to avoid copying all of that from the first file. For + example, to take pages 1 through 5 from a + infile.pdf while preserving all metadata + associated with that file, you could use -

qpdf infile.pdf --pages infile.pdf 1-5 -- outfile.pdf
+    

qpdf infile.pdf --pages . 1-5 -- outfile.pdf
 

If you wanted pages 1 through 5 from infile.pdf but you wanted the rest of the @@ -546,13 +990,13 @@ file1.pdf and pages 11–15 from file2.pdf in reverse, you would run -

qpdf file1.pdf --pages file1.pdf 1-5 file2.pdf 15-11 -- outfile.pdf
+    

qpdf file1.pdf --pages file1.pdf 1-5 . 15-11 -- outfile.pdf
 

If, for some reason, you wanted to take the first page of an encrypted file called encrypted.pdf with password pass and repeat it twice in an output - file, and if you wanted to drop metadata (like page numbers and - outlines) but preserve encryption, you would use + file, and if you wanted to drop document-level metadata but + preserve encryption, you would use

qpdf --empty --copy-encryption=encrypted.pdf --encryption-file-password=pass
 --pages encrypted.pdf --password=pass 1 ./encrypted.pdf --password=pass 1 --
@@ -565,7 +1009,83 @@
     ./encrypted.pdf are separated files.  These
     are all corner cases that most users should hopefully never have
     to be bothered with.
-   

3.5. Advanced Parsing Options

+

+ Prior to version 8.4, it was not possible to specify the same page + from the same file directly more than once, and the workaround of + specifying the same file in more than one way was required. + Version 8.4 removes this limitation, but there is still a valid + use case. When you specify the same page from the same file more + than once, qpdf will share objects between the pages. If you are + going to do further manipulation on the file and need the two + instances of the same original page to be deep copies, then you + can specify the file in two different ways. For example + qpdf in.pdf --pages . 1 ./in.pdf 1 -- out.pdf + would create a file with two copies of the first page of the + input, and the two copies would share any objects in common. This + includes fonts, images, and anything else the page references. +

3.6. Overlay and Underlay Options

+ Starting with qpdf 8.4, it is possible to overlay or underlay + pages from other files onto the output generated by qpdf. Specify + overlay or underlay as follows: + +

{ --overlay | --underlay } file [ options ] --
+

+ Overlay and underlay options are processed late, so they can be + combined with other like merging and will apply to the final + output. The --overlay and + --underlay options work the same way, except + underlay pages are drawn underneath the page to which they are + applied, possibly obscured by the original page, and overlay files + are drawn on top of the page to which they are applied, possibly + obscuring the page. You can combine overlay and underlay. +

+ The default behavior of overlay and underlay is that pages are + taken from the overlay/underlay file in sequence and applied to + corresponding pages in the output until there are no more output + pages. If the overlay or underlay file runs out of pages, + remaining output pages are left alone. This behavior can be + modified by options, which are provided between the + --overlay or --underlay flag and + the -- option. The following options are + supported: +

  • + --password=password: supply a password if the + overlay/underlay file is encrypted. +

  • + --to=page-range: a range of pages in the same + form at described in Section 3.5, “Page Selection Options†+ indicates which pages in the output should have the + overlay/underlay applied. If not specified, overlay/underlay + are applied to all pages. +

  • + --from=[page-range]: a range of pages that + specifies which pages in the overlay/underlay file will be used + for overlay or underlay. If not specified, all pages will be + used. This can be explicitly specified to be empty if + --repeat is used. +

  • + --repeat=page-range: an optional range of + pages that specifies which pages in the overlay/underlay file + will be repeated after the “from†pages are used + up. If you want to repeat a range of pages starting at the + beginning, you can explicitly use --from=. +

+

+ Here are some examples. +

  • + --overlay o.pdf --to=1-5 --from=1-3 + --repeat=4 --: overlay the first three pages from file + o.pdf onto the first three pages of the + output, then overlay page 4 from o.pdf + onto pages 4 and 5 of the output. Leave remaining output pages + untouched. +

  • + --underlay footer.pdf --from= --repeat=1,2 --: + Underlay page 1 of footer.pdf on all odd + output pages, and underlay page 2 of + footer.pdf on all even output pages. +

+

3.7. Advanced Parsing Options

These options control aspects of how qpdf reads PDF files. Mostly these are of use to people who are working with damaged files. There is little reason to use these options unless you are trying @@ -596,7 +1116,7 @@ creation of hybrid PDF files and wish to see how a PDF consumer that doesn't understand object and cross-reference streams would interpret such a file. -

3.6. Advanced Transformation Options

+

3.8. Advanced Transformation Options

These transformation options control fine points of how qpdf creates the output file. Mostly these are of use only to people who are very familiar with the PDF file format or who are PDF @@ -616,21 +1136,26 @@ none: do not attempt to decode any streams

  • generalized: decode streams filtered with - supported generalized filters: /LZWDecode, - /FlateDecode, - /ASCII85Decode, and - /ASCIIHexDecode. We define generalized + supported generalized filters: + /LZWDecode, + /FlateDecode, + /ASCII85Decode, and + /ASCIIHexDecode. We define generalized filters as those to be used for general-purpose compression or encoding, as opposed to filters specifically designed - for image data. + for image data. Note that, by default, streams already + compressed with /FlateDecode are not + uncompressed and recompressed unless you also specify + --recompress-flate.

  • specialized: in addition to generalized, decode streams with supported non-lossy specialized - filters; currently this is just /RunLengthDecode + filters; currently this is just + /RunLengthDecode

  • all: in addition to generalized and specialized, decode streams with supported lossy filters; - currently this is just /DCTDecode (JPEG) + currently this is just /DCTDecode (JPEG)

  • --stream-data=option

    Controls transformation of stream data. This option predates @@ -643,7 +1168,10 @@ compress: recompress stream data when possible (default); equivalent to --compress-streams=y - --decode-level=generalized + --decode-level=generalized. Does not + recompress streams already compressed with + /FlateDecode unless + --recompress-flate is also specified.

  • preserve: leave all stream data as is; equivalent to --compress-streams=n @@ -654,6 +1182,25 @@ equivalent to --compress-streams=n --decode-level=generalized

  • +

    --recompress-flate

    + By default, streams already compressed with + /FlateDecode are left alone rather than + being uncompressed and recompressed. This option causes qpdf + to uncompress and recompress the streams. There is a + significant performance cost to using this option, but you + probably want to use it if you specify + --compression-level. +

    --compression-level=level

    + When writing new streams that are compressed with + /FlateDecode, use the specified compression + level. The value of level should be a number + from 1 to 9 and is passed directly to zlib, which implements + deflate compression. Note that qpdf doesn't uncompress and + recompress streams by default. To have this option apply to + already compressed streams, you should also specify + --recompress-flate. If your goal is to shrink + the size of PDF files, you should also use + --object-streams=generate.

    --normalize-content=[yn]

    Enables or disables normalization of content streams. Content normalization is enabled by default in QDF mode. Please see @@ -686,6 +1233,45 @@ object numbers will be the same since qpdf may create stream lengths as direct or indirect differently from the original file, and the original file may have gaps in its numbering. +

    + See also --preserve-unreferenced-resources, + which does something completely different. +

    --remove-unreferenced-resources=option

    + The option may be + auto, yes, or + no. The default is auto. +

    + Starting with qpdf 8.1, when splitting pages, qpdf is able to + attempt to remove images and fonts that are not used by a page + even if they are referenced in the page's resources + dictionary. When shared resources are in use, this behavior + can greatly reduce the file sizes of split pages, but the + analysis is very slow. In versions from 8.1 through 9.1.1, + qpdf did this analysis by default. Starting in qpdf 10.0.0, if + auto is used, qpdf does a quick analysis of + the file to determine whether the file is likely to have + unreferenced objects on pages, a pattern that frequently + occurs when resource dictionaries are shared across multiple + pages and rarely occurs otherwise. If it discovers this + pattern, then it will attempt to remove unreferenced + resources. Usually this means you get the slower splitting + speed only when it's actually going to create smaller files. + You can suppress removal of unreferenced resources altogether + by specifying no or force it to do the full + algorithm by specifying yes. +

    + Other than cases in which you don't care about file size and + care a lot about runtime, there are few reasons to use this + option, especially now that auto mode is + supported. One reason to use this is if you suspect that qpdf + is removing resources it shouldn't be removing. If you + encounter that case, please report it as bug at https://github.com/qpdf/qpdf/issues/. +

    --preserve-unreferenced-resources

    + This is a synonym for + --remove-unreferenced-resources=no. +

    + See also --preserve-unreferenced, which does + something completely different.

    --newline-before-endstream

    Tells qpdf to insert a newline before the endstream keyword, not counted in the @@ -717,9 +1303,128 @@ file more easily. This can also be combined with QDF mode or content normalization to make it easier to look at all of a page's contents at once. +

    --flatten-annotations=option

    + This option collapses annotations into the pages' contents + with special handling for form fields. Ordinarily, an + annotation is rendered separately and on top of the page. + Combining annotations into the page's contents effectively + freezes the placement of the annotations, making them look + right after various page transformations. The library + functionality backing this option was added for the benefit of + programs that want to create n-up page + layouts and other similar things that don't work well with + annotations. The option parameter + may be any of the following: +

    • + all: include all annotations that are not + marked invisible or hidden +

    • + print: only include annotations that + indicate that they should appear when the page is printed +

    • + screen: omit annotations that indicate + they should not appear on the screen +

    +

    + Note that form fields are special because the annotations that + are used to render filled-in form fields may become out of + date from the fields' values if the form is filled in by a + program that doesn't know how to update the appearances. If + qpdf detects this case, its default behavior is not to flatten + those annotations because doing so would cause the value of + the form field to be lost. This gives you a chance to go back + and resave the form with a program that knows how to generate + appearances. QPDF itself can generate appearances with some + limitations. See the --generate-appearances + option below. +

    --generate-appearances

    + If a file contains interactive form fields and indicates that + the appearances are out of date with the values of the form, + this flag will regenerate appearances, subject to a few + limitations. Note that there is not usually a reason to do + this, but it can be necessary before using the + --flatten-annotations option. Most of these + are not a problem with well-behaved PDF files. The limitations + are as follows: +

    • + Radio button and checkbox appearances use the pre-set + values in the PDF file. QPDF just makes sure that the + correct appearance is displayed based on the value of the + field. This is fine for PDF files that create their forms + properly. Some PDF writers save appearances for fields when + they change, which could cause some controls to have + inconsistent appearances. +

    +

    • + For text fields and list boxes, any characters that fall + outside of US-ASCII or, if detected, “Windows + ANSI†or “Mac Roman†encoding, will be + replaced by the ? character. +

    +

    • + Quadding is ignored. Quadding is used to specify whether + the contents of a field should be left, center, or right + aligned with the field. +

    +

    • + Rich text, multi-line, and other more elaborate formatting + directives are ignored. +

    +

    • + There is no support for multi-select fields or signature + fields. +

    + If qpdf doesn't do a good enough job with your form, use an + external application to save your filled-in form before + processing it with qpdf. +

    --optimize-images

    + This flag causes qpdf to recompress all images that are not + compressed with DCT (JPEG) using DCT compression as long as + doing so decreases the size in bytes of the image data and the + image does not fall below minimum specified dimensions. Useful + information is provided when used in combination with + --verbose. See also the + --oi-min-width, + --oi-min-height, and + --oi-min-area options. By default, starting + in qpdf 8.4, inline images are converted to regular images + and optimized as well. Use + --keep-inline-images to prevent inline images + from being included. +

    --oi-min-width=width

    + Avoid optimizing images whose width is below the specified + amount. If omitted, the default is 128 pixels. Use 0 for no + minimum. +

    --oi-min-height=height

    + Avoid optimizing images whose height is below the specified + amount. If omitted, the default is 128 pixels. Use 0 for no + minimum. +

    --oi-min-area=area-in-pixels

    + Avoid optimizing images whose pixel count + (width × height) is below the specified amount. If + omitted, the default is 16,384 pixels. Use 0 for no minimum. +

    --externalize-inline-images

    + Convert inline images to regular images. By default, images + whose data is at least 1,024 bytes are converted when this + option is selected. Use --ii-min-bytes to + change the size threshold. This option is implicitly selected + when --optimize-images is selected. Use + --keep-inline-images to exclude inline images + from image optimization. +

    --ii-min-bytes=bytes

    + Avoid converting inline images whose size is below the + specified minimum size to regular images. If omitted, the + default is 1,024 bytes. Use 0 for no minimum. +

    --keep-inline-images

    + Prevent inline images from being included in image + optimization. This option has no affect when + --optimize-images is not specified. +

    --remove-page-labels

    + Remove page labels from the output file.

    --qdf

    Turns on QDF mode. For additional information on QDF, please - see Chapter 4, QDF Mode. + see Chapter 4, QDF Mode. Note that + --linearize disables QDF mode.

    --min-version=version

    Forces the PDF version of the output file to be at least version. In other words, if the @@ -845,7 +1550,7 @@ QDF mode is intended for people, mostly developers, who wish to inspect or modify PDF files in a text editor. For details, please see Chapter 4, QDF Mode. -

    3.7. Testing, Inspection, and Debugging Options

    +

    3.9. Testing, Inspection, and Debugging Options

    These options can be useful for digging into PDF files or for use in automated test suites for software that uses the qpdf library. When any of the options in this section are specified, no output @@ -900,7 +1605,7 @@ Shows the contents of the cross-reference table in a human-readable form. This is especially useful for files with cross-reference streams which are stored in a binary format. -

    --show-object=obj[,gen]

    +

    --show-object=trailer|obj[,gen]

    Show the contents of the given object. This is especially useful for inspecting objects that are inside of object streams (also known as “compressed objectsâ€). @@ -930,6 +1635,20 @@ each page. (At present, information about images in shared resource dictionaries are not output by this command. This is discussed in a comment in the source code.) +

    --json

    + Generate a JSON representation of the file. This is described + in depth in Chapter 6, QPDF JSON +

    --json-help

    + Describe the format of the JSON output. +

    --json-key=key

    + This option is repeatable. If specified, only top-level keys + specified will be included in the JSON output. If not + specified, all keys will be shown. +

    --json-object=trailer|obj[,gen]

    + This option is repeatable. If specified, only specified + objects will be shown in the + “objects†key of the JSON + output. If absent, all objects will be shown.

    --check

    Checks file structure and well as encryption, linearization, and encoding of stream data. A file for which @@ -963,6 +1682,111 @@ attempt to normalize the stream data as if it is a page content stream. This attempt will be made even if it is not a page content stream, in which case it will produce unusable results. +

    3.10. Unicode Passwords

    + At the library API level, all methods that perform encryption and + decryption interpret passwords as strings of bytes. It is up to + the caller to ensure that they are appropriately encoded. Starting + with qpdf version 8.4.0, qpdf will attempt to make this easier for + you when interact with qpdf via its command line interface. The + PDF specification requires passwords used to encrypt files with + 40-bit or 128-bit encryption to be encoded with PDF Doc encoding. + This encoding is a single-byte encoding that supports ISO-Latin-1 + and a handful of other commonly used characters. It has a large + overlap with Windows ANSI but is not exactly the same. There is + generally not a way to provide PDF Doc encoded strings on the + command line. As such, qpdf versions prior to 8.4.0 would often + create PDF files that couldn't be opened with other software when + given a password with non-ASCII characters to encrypt a file with + 40-bit or 128-bit encryption. Starting with qpdf 8.4.0, qpdf + recognizes the encoding of the parameter and transcodes it as + needed. The rest of this section provides the details about + exactly how qpdf behaves. Most users will not need to know this + information, but it might be useful if you have been working + around qpdf's old behavior or if you are using qpdf to generate + encrypted files for testing other PDF software. +

    + A note about Windows: when qpdf builds, it attempts to determine + what it has to do to use wmain instead of + main on Windows. The + wmain function is an alternative entry point + that receives all arguments as UTF-16-encoded strings. When qpdf + starts up this way, it converts all the strings to UTF-8 encoding + and then invokes the regular main. This means that, as far as qpdf + is concerned, it receives its command-line arguments with UTF-8 + encoding, just as it would in any modern Linux or UNIX + environment. +

    + If a file is being encrypted with 40-bit or 128-bit encryption and + the supplied password is not a valid UTF-8 string, qpdf will fall + back to the behavior of interpreting the password as a string of + bytes. If you have old scripts that encrypt files by passing the + output of iconv to qpdf, you no longer need to + do that, but if you do, qpdf should still work. The only exception + would be for the extremely unlikely case of a password that is + encoded with a single-byte encoding but also happens to be valid + UTF-8. Such a password would contain strings of even numbers of + characters that alternate between accented letters and symbols. In + the extremely unlikely event that you are intentionally using such + passwords and qpdf is thwarting you by interpreting them as UTF-8, + you can use --password-mode=bytes to suppress + qpdf's automatic behavior. +

    + The --password-mode option, as described earlier + in this chapter, can be used to change qpdf's interpretation of + supplied passwords. There are very few reasons to use this option. + One would be the unlikely case described in the previous paragraph + in which the supplied password happens to be valid UTF-8 but isn't + supposed to be UTF-8. Your best bet would be just to provide the + password as a valid UTF-8 string, but you could also use + --password-mode=bytes. Another reason to use + --password-mode=bytes would be to intentionally + generate PDF files encrypted with passwords that are not properly + encoded. The qpdf test suite does this to generate invalid files + for the purpose of testing its password recovery capability. If + you were trying to create intentionally incorrect files for a + similar purposes, the bytes password mode can + enable you to do this. +

    + When qpdf attempts to decrypt a file with a password that contains + non-ASCII characters, it will generate a list of alternative + passwords by attempting to interpret the password as each of a + handful of different coding systems and then transcode them to the + required format. This helps to compensate for the supplied + password being given in the wrong coding system, such as would + happen if you used the iconv workaround that + was previously needed. It also generates passwords by doing the + reverse operation: translating from correct in incorrect encoding + of the password. This would enable qpdf to decrypt files using + passwords that were improperly encoded by whatever software + encrypted the files, including older versions of qpdf invoked + without properly encoded passwords. The combination of these two + recovery methods should make qpdf transparently open most + encrypted files with the password supplied correctly but in the + wrong coding system. There are no real downsides to this behavior, + but if you don't want qpdf to do this, you can use the + --suppress-password-recovery option. One reason + to do that is to ensure that you know the exact password that was + used to encrypt the file. +

    + With these changes, qpdf now generates compliant passwords in most + cases. There are still some exceptions. In particular, the PDF + specification directs compliant writers to normalize Unicode + passwords and to perform certain transformations on passwords with + bidirectional text. Implementing this functionality requires using + a real Unicode library like ICU. If a client application that uses + qpdf wants to do this, the qpdf library will accept the resulting + passwords, but qpdf will not perform these transformations itself. + It is possible that this will be addressed in a future version of + qpdf. The QPDFWriter methods that enable + encryption on the output file accept passwords as strings of + bytes. +

    + Please note that the --password-is-hex-key option + is unrelated to all this. This flag bypasses the normal process of + going from password to encryption string entirely, allowing the + raw encryption key to be specified directly. This is useful for + forensic purposes or for brute-force recovery of files with + unknown passwords.

    Chapter 4. QDF Mode

    In QDF mode, qpdf creates PDF files in what we call QDF form. A PDF file in QDF form, sometimes called a QDF @@ -973,7 +1797,9 @@ some restrictions, in an ordinary text editor. This can be very useful for experimenting with different PDF constructs or for making one-off edits to PDF files (though there are other reasons - why this may not always work). + why this may not always work). Note that QDF mode does not support + linearized files. If you enable linearization, QDF mode is + automatically disabled.

    It is ordinarily very difficult to edit PDF files in a text editor for two reasons: most meaningful data in PDF files is compressed, @@ -1061,7 +1887,7 @@ the offset to the cross-reference table or cross-reference stream following the startxref token

    -

    Chapter 5. Using the QPDF Library

    +

    Chapter 5. Using the QPDF Library

    5.1. Using QPDF from C++

    The source tree for the qpdf package has an examples directory that contains a few example programs. The qpdf/qpdf.cc source @@ -1088,7 +1914,227 @@ QPDFWriter) can be used in more than one thread at a time. Multiple threads may simultaneously work with different instances of these and all other QPDF objects. -

    Chapter 6. Design and Library Notes

    6.1. Introduction

    +

    5.2. Using QPDF from other languages

    + The qpdf library is implemented in C++, which makes it hard to use + directly in other languages. There are a few things that can help. +

    “Câ€

    + The qpdf library includes a “C†language interface + that provides a subset of the overall capabilities. The header + file qpdf/qpdf-c.h includes information + about its use. As long as you use a C++ linker, you can link C + programs with qpdf and use the C API. For languages that can + directly load methods from a shared library, the C API can also + be useful. People have reported success using the C API from + other languages on Windows by directly calling functions in the + DLL. +

    Python

    + A Python module called pikepdf + provides a clean and highly functional set of Python bindings + to the qpdf library. Using pikepdf, you can work with PDF files + in a natural way and combine qpdf's capabilities with other + functionality provided by Python's rich standard library and + available modules. +

    Other Languages

    + Starting with version 8.3.0, the qpdf + command-line tool can produce a JSON representation of the PDF + file's non-content data. This can facilitate interacting + programmatically with PDF files through qpdf's command line + interface. For more information, please see Chapter 6, QPDF JSON. +

    5.3. A Note About Unicode File Names

    + When strings are passed to qpdf library routines either as + char* or as std::string, + they are treated as byte arrays except where otherwise noted. When + Unicode is desired, qpdf wants UTF-8 unless otherwise noted in + comments in header files. In modern UNIX/Linux environments, this + generally does the right thing. In Windows, it's a bit more + complicated. Starting in qpdf 8.4.0, passwords that contain + Unicode characters are handled much better, and starting in qpdf + 8.4.1, the library attempts to properly handle Unicode characters + in filenames. In particular, in Windows, if a UTF-8 encoded string + is used as a filename in either QPDF or + QPDFWriter, it is internally converted to + wchar_t*, and Unicode-aware Windows APIs are + used. As such, qpdf will generally operate properly on files with + non-ASCII characters in their names as long as the filenames are + UTF-8 encoded for passing into the qpdf library API, but there are + still some rough edges, such as the encoding of the filenames in + error messages our CLI output messages. Patches or bug reports are + welcome for any continuing issues with Unicode file names in + Windows. +

    Chapter 6. QPDF JSON

    6.1. Overview

    + Beginning with qpdf version 8.3.0, the qpdf + command-line program can produce a JSON representation of the + non-content data in a PDF file. It includes a dump in JSON format + of all objects in the PDF file excluding the content of streams. + This JSON representation makes it very easy to look in detail at + the structure of a given PDF file, and it also provides a great way + to work with PDF files programmatically from the command-line in + languages that can't call or link with the qpdf library directly. + Note that stream data can be extracted from PDF files using other + qpdf command-line options. +

    6.2. JSON Guarantees

    + The qpdf JSON representation includes a JSON serialization of the + raw objects in the PDF file as well as some computed information in + a more easily extracted format. QPDF provides some guarantees about + its JSON format. These guarantees are designed to simplify the + experience of a developer working with the JSON format. +

    Compatibility

    + The top-level JSON object output is a dictionary. The JSON + output contains various nested dictionaries and arrays. With + the exception of dictionaries that are populated by the fields + of objects from the file, all instances of a dictionary are + guaranteed to have exactly the same keys. Future versions of + qpdf are free to add additional keys but not to remove keys or + change the type of object that a key points to. The qpdf + program validates this guarantee, and in the unlikely event + that a bug in qpdf should cause it to generate data that + doesn't conform to this rule, it will ask you to file a bug + report. +

    + The top-level JSON structure contains a + “version†key whose value is + simple integer. The value of the version key + will be incremented if a non-compatible change is made. A + non-compatible change would be any change that involves removal + of a key, a change to the format of data pointed to by a key, + or a semantic change that requires a different interpretation + of a previously existing key. A strong effort will be made to + avoid breaking compatibility. +

    Documentation

    + The qpdf command can be invoked with the + --json-help option. This will output a JSON + structure that has the same structure as the JSON output that + qpdf generates, except that each field in the help output is a + description of the corresponding field in the JSON output. The + specific guarantees are as follows: +

    • + A dictionary in the help output means that the + corresponding location in the actual JSON output is also a + dictionary with exactly the same keys; that is, no keys + present in help are absent in the real output, and no keys + will be present in the real output that are not in help. As + a special case, if the dictionary has a single key whose + name starts with < and ends with + >, it means that the JSON output is a + dictionary that can have any keys, each of which conforms + to the value of the special key. This is used for cases in + which the keys of the dictionary are things like object + IDs. +

    • + A string in the help output is a description of the item + that appears in the corresponding location of the actual + output. The corresponding output can have any format. +

    • + An array in the help output always contains a single + element. It indicates that the corresponding location in the + actual output is also an array, and that each element of the + array has whatever format is implied by the single element + of the help output's array. +

    + For example, the help output indicates includes a + “pagelabels†key whose value is + an array of one element. That element is a dictionary with keys + “index†and + “labelâ€. In addition to + describing the meaning of those keys, this tells you that the + actual JSON output will contain a pagelabels + array, each of whose elements is a dictionary that contains an + index key, a label key, + and no other keys. +

    Directness and Simplicity

    + The JSON output contains the value of every object in the file, + but it also contains some processed data. This is analogous to + how qpdf's library interface works. The processed data is + similar to the helper functions in that it allows you to look + at certain aspects of the PDF file without having to understand + all the nuances of the PDF specification, while the raw objects + allow you to mine the PDF for anything that the higher-level + interfaces are lacking. +

    +

    6.3. Limitations of JSON Representation

    + There are a few limitations to be aware of with the JSON structure: +

    • + Strings, names, and indirect object references in the original + PDF file are all converted to strings in the JSON + representation. In the case of a “normal†PDF file, + you can tell the difference because a name starts with a slash + (/), and an indirect object reference looks + like n n R, but if there were to be a string + that looked like a name or indirect object reference, there + would be no way to tell this from the JSON output. Note that + there are certain cases where you know for sure what something + is, such as knowing that dictionary keys in objects are always + names and that certain things in the higher-level computed data + are known to contain indirect object references. +

    • + The JSON format doesn't support binary data very well. Mostly + the details are not important, but they are presented here for + information. When qpdf outputs a string in the JSON + representation, it converts the string to UTF-8, assuming usual + PDF string semantics. Specifically, if the original string is + UTF-16, it is converted to UTF-8. Otherwise, it is assumed to + have PDF doc encoding, and is converted to UTF-8 with that + assumption. This causes strange things to happen to binary + strings. For example, if you had the binary string + <038051>, this would be output to the + JSON as \u0003•Q because + 03 is not a printable character and + 80 is the bullet character in PDF doc + encoding and is mapped to the Unicode value + 2022. Since 51 is + Q, it is output as is. If you wanted to + convert back from here to a binary string, would have to + recognize Unicode values whose code points are higher than + 0xFF and map those back to their + corresponding PDF doc encoding characters. There is no way to + tell the difference between a Unicode string that was originally + encoded as UTF-16 or one that was converted from PDF doc + encoding. In other words, it's best if you don't try to use the + JSON format to extract binary strings from the PDF file, but if + you really had to, it could be done. Note that qpdf's + --show-object option does not have this + limitation and will reveal the string as encoded in the original + file. +

    +

    6.4. JSON: Special Considerations

    + For the most part, the built-in JSON help tells you everything you + need to know about the JSON format, but there are a few + non-obvious things to be aware of: +

    • + While qpdf guarantees that keys present in the help will be + present in the output, those fields may be null or empty if the + information is not known or absent in the file. Also, if you + specify --json-keys, the keys that are not + listed will be excluded entirely except for those that + --json-help says are always present. +

    • + In a few places, there are keys with names containing + pageposfrom1. The values of these keys are + null or an integer. If an integer, they point to a page index + within the file numbering from 1. Note that JSON indexes from + 0, and you would also use 0-based indexing using the API. + However, 1-based indexing is easier in this case because the + command-line syntax for specifying page ranges is 1-based. If + you were going to write a program that looked through the JSON + for information about specific pages and then use the + command-line to extract those pages, 1-based indexing is + easier. Besides, it's more convenient to subtract 1 from a + program in a real programming language than it is to add 1 from + shell code. +

    • + The image information included in the page + section of the JSON output includes the key + “filterableâ€. Note that the + value of this field may depend on the + --decode-level that you invoke qpdf with. The + JSON output includes a top-level key + “parameters†that indicates the + decode level used for computing whether a stream was + filterable. For example, jpeg images will be shown as not + filterable by default, but they will be shown as filterable if + you run qpdf --json --decode-level=all. +

    +

    Chapter 7. Design and Library Notes

    7.1. Introduction

    This section was written prior to the implementation of the qpdf package and was subsequently modified to reflect the implementation. In some cases, for purposes of explanation, it @@ -1098,47 +2144,48 @@ understanding how this code works.

    In general, one should adhere strictly to a specification when - writing but be liberal in reading. This way, the product of our + writing but be liberal in reading. This way, the product of our software will be accepted by the widest range of other programs, - and we will accept the widest range of input files. This library + and we will accept the widest range of input files. This library attempts to conform to that philosophy whenever possible but also aims to provide strict checking for people who want to validate - PDF files. If you don't want to see warnings and are trying to + PDF files. If you don't want to see warnings and are trying to write something that is tolerant, you can call - setSuppressWarnings(true). If you want to fail + setSuppressWarnings(true). If you want to fail on the first error, you can call - setAttemptRecovery(false). The default - behavior is to generating warnings for recoverable problems. Note - that recovery will not always produce the desired results even if - it is able to get through the file. Unlike most other PDF files - that produce generic warnings such as “This file is + setAttemptRecovery(false). The default behavior + is to generating warnings for recoverable problems. Note that + recovery will not always produce the desired results even if it is + able to get through the file. Unlike most other PDF files that + produce generic warnings such as “This file is damaged,â€, qpdf generally issues a detailed error message - that would be most useful to a PDF developer. This is by design - as there seems to be a shortage of PDF validation tools out - there. (This was, in fact, one of the major motivations behind - the initial creation of qpdf.) -

    6.2. Design Goals

    + that would be most useful to a PDF developer. This is by design as + there seems to be a shortage of PDF validation tools out there. + This was, in fact, one of the major motivations behind the initial + creation of qpdf. +

    7.2. Design Goals

    The QPDF package includes support for reading and rewriting PDF - files. It aims to hide from the user details involving object + files. It aims to hide from the user details involving object locations, modified (appended) PDF files, the directness/indirectness of objects, and stream filters including - encryption. It does not aim to hide knowledge of the object - hierarchy or content stream contents. Put another way, a user of + encryption. It does not aim to hide knowledge of the object + hierarchy or content stream contents. Put another way, a user of the qpdf library is expected to have knowledge about how PDF files work, but is not expected to have to keep track of bookkeeping details such as file positions.

    A user of the library never has to care whether an object is - direct or indirect. All access to objects deals with this - transparently. All memory management details are also handled by - the library. + direct or indirect, though it is possible to determine whether an + object is direct or not if this information is needed. All access + to objects deals with this transparently. All memory management + details are also handled by the library.

    The PointerHolder object is used internally - by the library to deal with memory management. This is basically - a smart pointer object very similar in spirit to the Boost - library's shared_ptr object, but predating - it by several years. This library also makes use of a technique - for giving fine-grained access to methods in one class to other + by the library to deal with memory management. This is basically a + smart pointer object very similar in spirit to C++-11's + std::shared_ptr object, but predating it by + several years. This library also makes use of a technique for + giving fine-grained access to methods in one class to other classes by using public subclasses with friends and only private members that in turn call private methods of the containing class. See QPDFObjectHandle::Factory as an @@ -1149,28 +2196,20 @@ library provides methods for both accessing and mutating PDF files.

    - QPDFObject is the basic PDF Object class. - It is an abstract base class from which are derived classes for - each type of PDF object. Clients do not interact with Objects - directly but instead interact with - QPDFObjectHandle. -

    - QPDFObjectHandle contains - PointerHolder<QPDFObject> and - includes accessor methods that are type-safe proxies to the - methods of the derived object classes as well as methods for - querying object types. They can be passed around by value, - copied, stored in containers, etc. with very low overhead. - Instances of QPDFObjectHandle always - contain a reference back to the QPDF object - from which they were created. A + The primary class for interacting with PDF objects is + QPDFObjectHandle. Instances of this class + can be passed around by value, copied, stored in containers, etc. + with very low overhead. Instances of + QPDFObjectHandle created by reading from a + file will always contain a reference back to the + QPDF object from which they were created. A QPDFObjectHandle may be direct or indirect. If indirect, the QPDFObject the PointerHolder initially points to is a null - pointer. In this case, the first attempt to access the underlying + pointer. In this case, the first attempt to access the underlying QPDFObject will result in the QPDFObject being resolved via a call to the - referenced QPDF instance. This makes it + referenced QPDF instance. This makes it essentially impossible to make coding errors in which certain things will work for some PDF files and not for others based on which objects are direct and which objects are indirect. @@ -1185,45 +2224,6 @@ modified in several ways. See comments in QPDFObjectHandle.hh for details.

    - When the QPDF class creates a new object, - it dynamically allocates the appropriate type of - QPDFObject and immediately hands the - pointer to an instance of QPDFObjectHandle. - The parser reads a token from the current file position. If the - token is a not either a dictionary or array opener, an object is - immediately constructed from the single token and the parser - returns. Otherwise, the parser is invoked recursively in a - special mode in which it accumulates objects until it finds a - balancing closer. During this process, the - “R†keyword is recognized and an - indirect QPDFObjectHandle may be - constructed. -

    - The QPDF::resolve() method, which is used to - resolve an indirect object, may be invoked from the - QPDFObjectHandle class. It first checks a - cache to see whether this object has already been read. If not, - it reads the object from the PDF file and caches it. It the - returns the resulting QPDFObjectHandle. - The calling object handle then replaces its - PointerHolder<QDFObject> with the one - from the newly returned QPDFObjectHandle. - In this way, only a single copy of any direct object need exist - and clients can access objects transparently without knowing - caring whether they are direct or indirect objects. Additionally, - no object is ever read from the file more than once. That means - that only the portions of the PDF file that are actually needed - are ever read from the input file, thus allowing the qpdf package - to take advantage of this important design goal of PDF files. -

    - If the requested object is inside of an object stream, the object - stream itself is first read into memory. Then the tokenizer reads - objects from the memory stream based on the offset information - stored in the stream. Those individual objects are cached, after - which the temporary buffer holding the object stream contents are - discarded. In this way, the first time an object in an object - stream is requested, all objects in the stream are cached. -

    An instance of QPDF is constructed by using the class's default constructor. If desired, the QPDF object may be configured with various @@ -1234,7 +2234,7 @@ 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. - [1] + [1] QPDF will allow recovery of a user password given an owner password. The input PDF file must be seekable. (Output files written by QPDFWriter need @@ -1256,8 +2256,173 @@

    There are some convenience routines for very common operations such as walking the page tree and returning a vector of all page - objects. For full details, please see the header file - QPDF.hh. + objects. For full details, please see the header files + QPDF.hh and + QPDFObjectHandle.hh. There are also some + additional helper classes that provide higher level API functions + for certain document constructions. These are discussed in Section 7.3, “Helper Classesâ€. +

    7.3. Helper Classes

    + QPDF version 8.1 introduced the concept of helper classes. Helper + classes are intended to contain higher level APIs that allow + developers to work with certain document constructs at an + abstraction level above that of + QPDFObjectHandle while staying true to + qpdf's philosophy of not hiding document structure from the + developer. As with qpdf in general, the goal is take away some of + the more tedious bookkeeping aspects of working with PDF files, + not to remove the need for the developer to understand how the PDF + construction in question works. The driving factor behind the + creation of helper classes was to allow the evolution of higher + level interfaces in qpdf without polluting the interfaces of the + main top-level classes QPDF and + QPDFObjectHandle. +

    + There are two kinds of helper classes: + document helpers and + object helpers. Document helpers are + constructed with a reference to a QPDF + object and provide methods for working with structures that are at + the document level. Object helpers are constructed with an + instance of a QPDFObjectHandle and provide + methods for working with specific types of objects. +

    + Examples of document helpers include + QPDFPageDocumentHelper, which contains + methods for operating on the document's page trees, such as + enumerating all pages of a document and adding and removing pages; + and QPDFAcroFormDocumentHelper, which + contains document-level methods related to interactive forms, such + as enumerating form fields and creating mappings between form + fields and annotations. +

    + Examples of object helpers include + QPDFPageObjectHelper for performing + operations on pages such as page rotation and some operations on + content streams, QPDFFormFieldObjectHelper + for performing operations related to interactive form fields, and + QPDFAnnotationObjectHelper for working with + annotations. +

    + It is always possible to retrieve the underlying + QPDF reference from a document helper and + the underlying QPDFObjectHandle reference + from an object helper. Helpers are designed to be helpers, not + wrappers. The intention is that, in general, it is safe to freely + intermix operations that use helpers with operations that use the + underlying objects. Document and object helpers do not attempt to + provide a complete interface for working with the things they are + helping with, nor do they attempt to encapsulate underlying + structures. They just provide a few methods to help with + error-prone, repetitive, or complex tasks. In some cases, a helper + object may cache some information that is expensive to gather. In + such cases, the helper classes are implemented so that their own + methods keep the cache consistent, and the header file will + provide a method to invalidate the cache and a description of what + kinds of operations would make the cache invalid. If in doubt, you + can always discard a helper class and create a new one with the + same underlying objects, which will ensure that you have discarded + any stale information. +

    + By Convention, document helpers are called + QPDFSomethingDocumentHelper and are derived + from QPDFDocumentHelper, and object helpers + are called QPDFSomethingObjectHelper and + are derived from QPDFObjectHelper. For + details on specific helpers, please see their header files. You + can find them by looking at + include/qpdf/QPDF*DocumentHelper.hh and + include/qpdf/QPDF*ObjectHelper.hh. +

    + In order to avoid creation of circular dependencies, the following + general guidelines are followed with helper classes: +

    • + Core class interfaces do not know about helper classes. For + example, no methods of QPDF or + QPDFObjectHandle will include helper + classes in their interfaces. +

    • + Interfaces of object helpers will usually not use document + helpers in their interfaces. This is because it is much more + useful for document helpers to have methods that return object + helpers. Most operations in PDF files start at the document + level and go from there to the object level rather than the + other way around. It can sometimes be useful to map back from + object-level structures to document-level structures. If there + is a desire to do this, it will generally be provided by a + method in the document helper class. +

    • + Most of the time, object helpers don't know about other object + helpers. However, in some cases, one type of object may be a + container for another type of object, in which case it may make + sense for the outer object to know about the inner object. For + example, there are methods in the + QPDFPageObjectHelper that know + QPDFAnnotationObjectHelper because + references to annotations are contained in page dictionaries. +

    • + Any helper or core library class may use helpers in their + implementations. +

    +

    + Prior to qpdf version 8.1, higher level interfaces were added as + “convenience functions†in either + QPDF or + QPDFObjectHandle. For compatibility, older + convenience functions for operating with pages will remain in + those classes even as alternatives are provided in helper classes. + Going forward, new higher level interfaces will be provided using + helper classes. +

    7.4. Implementation Notes

    + This section contains a few notes about QPDF's internal + implementation, particularly around what it does when it first + processes a file. This section is a bit of a simplification of + what it actually does, but it could serve as a starting point to + someone trying to understand the implementation. There is nothing + in this section that you need to know to use the qpdf library. +

    + QPDFObject is the basic PDF Object class. + It is an abstract base class from which are derived classes for + each type of PDF object. Clients do not interact with Objects + directly but instead interact with + QPDFObjectHandle. +

    + When the QPDF class creates a new object, + it dynamically allocates the appropriate type of + QPDFObject and immediately hands the + pointer to an instance of QPDFObjectHandle. + The parser reads a token from the current file position. If the + token is a not either a dictionary or array opener, an object is + immediately constructed from the single token and the parser + returns. Otherwise, the parser iterates in a special mode in which + it accumulates objects until it finds a balancing closer. During + this process, the “R†keyword is + recognized and an indirect QPDFObjectHandle + may be constructed. +

    + The QPDF::resolve() method, which is used to + resolve an indirect object, may be invoked from the + QPDFObjectHandle class. It first checks a + cache to see whether this object has already been read. If not, + it reads the object from the PDF file and caches it. It the + returns the resulting QPDFObjectHandle. + The calling object handle then replaces its + PointerHolder<QDFObject> with the one + from the newly returned QPDFObjectHandle. + In this way, only a single copy of any direct object need exist + and clients can access objects transparently without knowing + caring whether they are direct or indirect objects. Additionally, + no object is ever read from the file more than once. That means + that only the portions of the PDF file that are actually needed + are ever read from the input file, thus allowing the qpdf package + to take advantage of this important design goal of PDF files. +

    + If the requested object is inside of an object stream, the object + stream itself is first read into memory. Then the tokenizer reads + objects from the memory stream based on the offset information + stored in the stream. Those individual objects are cached, after + which the temporary buffer holding the object stream contents are + discarded. In this way, the first time an object in an object + stream is requested, all objects in the stream are cached.

    The following example should clarify how QPDF processes a simple file. @@ -1267,12 +2432,11 @@ pdf.processFile("a.pdf");.

  • The QPDF class checks the beginning of - a.pdf for - %!PDF-1.[0-9]+. It then reads the cross - reference table mentioned at the end of the file, ensuring that - it is looking before the last %%EOF. After - getting to trailer keyword, it invokes the - parser. + a.pdf for a PDF header. It then reads the + cross reference table mentioned at the end of the file, + ensuring that it is looking before the last + %%EOF. After getting to + trailer keyword, it invokes the parser.

  • The parser sees “<<â€, so it calls itself recursively in dictionary creation mode. @@ -1326,7 +2490,7 @@ As the client continues to request objects, the same process is followed for each new requested object.

  • -

    6.3. Casting Policy

    +

    7.5. Casting Policy

    This section describes the casting policy followed by qpdf's implementation. This is no concern to qpdf's end users and largely of no concern to people writing code that uses qpdf, but @@ -1347,125 +2511,67 @@ about the use of old-style casts in code that is shared between C and C++ code.

    - The casting policy explicitly prohibits casting between integer - sizes for no purpose other than to quiet a compiler warning when - there is no reasonable chance of a problem resulting. The reason - for this exclusion is that the practice of adding these additional - casts precludes future use of additional compiler warnings as a - tool for making future improvements to this aspect of the code, - and it also damages the readability of the code. -

    - There are a few significant areas where casting is common in the - qpdf sources or where casting would be required to quiet higher - levels of compiler warnings but is omitted at present: -

    • - char vs. unsigned char. For - historical reasons, there are a lot of places in qpdf's - internals that deal with unsigned char, which - means that a lot of casting is required to interoperate with - standard library calls and std::string. In - retrospect, qpdf should have probably used regular (signed) - char and char* everywhere and just - cast to unsigned char when needed, but it's too - late to make that change now. There are - reinterpret_cast calls to go between - char* and unsigned char*, and there - are static_cast calls to go between - char and unsigned char. These should - always be safe. -

    • - Non-const unsigned char* used in the - Pipeline interface. The pipeline interface has a - write call that uses unsigned - char* without a const qualifier. The main - reason for this is to support pipelines that make calls to - third-party libraries, such as zlib, that don't include - const in their interfaces. Unfortunately, there - are many places in the code where it is desirable to have - const char* with pipelines. None of the pipeline - implementations in qpdf currently modify the data passed to - write, and doing so would be counter to the intent of - Pipeline, but there is nothing in the code to - prevent this from being done. There are places in the code - where const_cast is used to remove the - const-ness of pointers going into Pipelines. This - could theoretically be unsafe, but there is adequate testing to - assert that it is safe and will remain safe in qpdf's code. -

    • - size_t vs. qpdf_offset_t. This is - pretty much unavoidable since sizes are unsigned types and - offsets are signed types. Whenever it is necessary to seek by - an amount given by a size_t, it becomes necessary - to mix and match between size_t and - qpdf_offset_t. Additionally, qpdf sometimes - treats memory buffers like files (as with - BufferInputSource, and those seek interfaces have - to be consistent with file-based input sources. Neither gcc - nor MSVC give warnings for this case by default, but both have - warning flags that can enable this. (MSVC: - /W14267 or /W3, which also - enables some additional warnings that we ignore; gcc: - -Wconversion -Wsign-conversion). This could - matter for files whose sizes are larger than - 263 bytes, but it is reasonable to - expect that a world where such files are common would also have - larger size_t and qpdf_offset_t types - in it. On most 64-bit systems at the time of this writing (the - release of version 4.1.0 of qpdf), both size_t and - qpdf_offset_t are 64-bit integer types, while on - many current 32-bit systems, size_t is a 32-bit - type while qpdf_offset_t is a 64-bit type. I am - not aware of any cases where 32-bit systems that have - size_t smaller than qpdf_offset_t - could run into problems. Although I can't conclusively rule - out the possibility of such problems existing, I suspect any - cases would be pretty contrived. In the event that someone - should produce a file that qpdf can't handle because of what is - suspected to be issues involving the handling of - size_t vs. qpdf_offset_t (such files - may behave properly on 64-bit systems but not on 32-bit systems - because they have very large embedded files or streams, for - example), the above mentioned warning flags could be enabled - and all those implicit conversions could be carefully - scrutinized. (I have already gone through that exercise once - in adding support for files larger than 4 GB in size.) I - continue to be committed to supporting large files on 32-bit - systems, but I would not go to any lengths to support corner - cases involving large embedded files or large streams that work - on 64-bit systems but not on 32-bit systems because of - size_t being too small. It is reasonable to - assume that anyone working with such files would be using a - 64-bit system anyway since many 32-bit applications would have - similar difficulties. -

    • - size_t vs. int or long. - There are some cases where size_t and - int or long or size_t - and unsigned int or unsigned long are - used interchangeably. These cases occur when working with very - small amounts of memory, such as with the bit readers (where - we're working with just a few bytes at a time), some cases of - strlen, and a few other cases. I have - scrutinized all of these cases and determined them to be safe, - but there is no mechanism in the code to ensure that new unsafe - conversions between int and size_t - aren't introduced short of good testing and strong awareness of - the issues. Again, if any such bugs are suspected in the - future, enabling the additional warning flags and scrutinizing - the warnings would be in order. -

    -

    - To be clear, I believe qpdf to be well-behaved with respect to - sizes and offsets, and qpdf's test suite includes actual - generation and full processing of files larger than 4 GB in - size. The issues raised here are largely academic and should not - in any way be interpreted to mean that qpdf has practical problems - involving sloppiness with integer types. I also believe that - appropriate measures have been taken in the code to avoid problems - with signed vs. unsigned integers from resulting in memory - overwrites or other issues with potential security implications, - though there are never any absolute guarantees. -

    6.4. Encryption

    + The QIntC namespace, provided by + include/qpdf/QIntC.hh, implements safe + functions for converting between integer types. These functions do + range checking and throw a std::range_error, which is + subclass of std::runtime_error, if conversion from one + integer type to another results in loss of information. There are + many cases in which we have to move between different integer + types because of incompatible integer types used in interoperable + interfaces. Some are unavoidable, such as moving between sizes and + offsets, and others are there because of old code that is too in + entrenched to be fixable without breaking source compatibility and + causing pain for users. QPDF is compiled with extra warnings to + detect conversions with potential data loss, and all such cases + should be fixed by either using a function from + QIntC or a + static_cast. +

    + When the intention is just to switch the type because of + exchanging data between incompatible interfaces, use + QIntC. This is the usual case. However, + there are some cases in which we are explicitly intending to use + the exact same bit pattern with a different type. This is most + common when switching between signed and unsigned characters. A + lot of qpdf's code uses unsigned characters internally, but + std::string and char are signed. Using + QIntC::to_char would be wrong for converting + from unsigned to signed characters because a negative + char value and the corresponding unsigned + char value greater than 127 mean the same + thing. There are also cases in which we use + static_cast when working with bit fields + where we are not representing a numerical value but rather a bunch + of bits packed together in some integer type. Also note that + size_t and long both typically differ + between 32-bit and 64-bit environments, so sometimes an explicit + cast may not be needed to avoid warnings on one platform but may + be needed on another. A conversion with + QIntC should always be used when the types + are different even if the underlying size is the same. QPDF's CI + build builds on 32-bit and 64-bit platforms, and the test suite is + very thorough, so it is hard to make any of the potential errors + here without being caught in build or test. +

    + Non-const unsigned char* is used in the + Pipeline interface. The pipeline interface has a + write call that uses unsigned + char* without a const qualifier. The main + reason for this is to support pipelines that make calls to + third-party libraries, such as zlib, that don't include + const in their interfaces. Unfortunately, there are + many places in the code where it is desirable to have const + char* with pipelines. None of the pipeline implementations + in qpdf currently modify the data passed to write, and doing so + would be counter to the intent of Pipeline, but there + is nothing in the code to prevent this from being done. There are + places in the code where const_cast is used + to remove the const-ness of pointers going into + Pipelines. This could theoretically be unsafe, but + there is adequate testing to assert that it is safe and will + remain safe in qpdf's code. +

    7.6. Encryption

    Encryption is supported transparently by qpdf. When opening a PDF file, if an encryption dictionary exists, the QPDF object processes this dictionary using @@ -1506,28 +2612,50 @@ multiple encryption formats, qpdf will choose the newest format. The only exception to this is that clear-text metadata will be preserved as clear-text if it is that way in the original file. -

    6.5. Random Number Generation

    +

    + One point of confusion some people have about encrypted PDF files + is that encryption is not the same as password protection. + Password protected files are always encrypted, but it is also + possible to create encrypted files that do not have passwords. + Internally, such files use the empty string as a password, and + most readers try the empty string first to see if it works and + prompt for a password only if the empty string doesn't work. + Normally such files have an empty user password and a non-empty + owner password. In that way, if the file is opened by an ordinary + reader without specification of password, the restrictions + specified in the encryption dictionary can be enforced. Most users + wouldn't even realize such a file was encrypted. Since qpdf always + ignores the restrictions (except for the purpose of reporting what + they are), qpdf doesn't care which password you use. QPDF will + allow you to create PDF files with non-empty user passwords and + empty owner passwords. Some readers will require a password when + you open these files, and others will open the files without a + password and not enforce restrictions. Having a non-empty user + password and an empty owner password doesn't really make sense + because it would mean that opening the file with the user password + would be more restrictive than not supplying a password at all. + QPDF also allows you to create PDF files with the same password as + both the user and owner password. Some readers will not ever allow + such files to be accessed without restrictions because they never + try the password as the owner password if it works as the user + password. Nonetheless, one of the powerful aspects of qpdf is that + it allows you to finely specify the way encrypted files are + created, even if the results are not useful to some readers. One + use case for this would be for testing a PDF reader to ensure that + it handles odd configurations of input files. +

    7.7. Random Number Generation

    QPDF generates random numbers to support generation of encrypted - data. Versions prior to 5.0.1 used random or - rand from stdlib to - generate random numbers. Version 5.0.1, if available, used - operating system-provided secure random number generation instead, - enabling use of stdlib random number - generation only if enabled by a compile-time option. Starting in - version 5.1.0, use of insecure random numbers was disabled unless - enabled at compile time. Starting in version 5.1.0, it is also - possible for you to disable use of OS-provided secure random - numbers. This is especially useful on Windows if you want to - avoid a dependency on Microsoft's cryptography API. In this case, - you must provide your own random data provider. Regardless of how - you compile qpdf, starting in version 5.1.0, it is possible for - you to provide your own random data provider at runtime. This - would enable you to use some software-based secure pseudorandom - number generator and to avoid use of whatever the operating system - provides. For details on how to do this, please refer to the - top-level README.md file in the source distribution and to comments - in QUtil.hh. -

    6.6. Adding and Removing Pages

    + data. Starting in qpdf 10.0.0, qpdf uses the crypto provider as + its source of random numbers. Older versions used the OS-provided + source of secure random numbers or, if allowed at build time, + insecure random numbers from stdlib. Starting with version 5.1.0, + you can disable use of OS-provided secure random numbers at build + time. This is especially useful on Windows if you want to avoid a + dependency on Microsoft's cryptography API. You can also supply + your own random data provider. For details on how to do this, + please refer to the top-level README.md file in the source + distribution and to comments in QUtil.hh. +

    7.8. Adding and Removing Pages

    While qpdf's API has supported adding and modifying objects for some time, version 3.0 introduces specific methods for adding and removing pages. These are largely convenience routines that @@ -1536,7 +2664,7 @@ manipulation of the /Pages tree itself. For details, see addPage and surrounding methods in QPDF.hh. -

    6.7. Reserving Object Numbers

    +

    7.9. Reserving Object Numbers

    Version 3.0 of qpdf introduced the concept of reserved objects. These are seldom needed for ordinary operations, but there are cases in which you may want to add a series of indirect objects @@ -1559,10 +2687,10 @@ QPDF::replaceReserved to replace the reserved objects with the real ones. This functionality will never be needed by most applications, but it is used internally by QPDF - when copying objects from other PDF files, as discussed in Section 6.8, “Copying Objects From Other PDF Filesâ€. For an example of how to use + when copying objects from other PDF files, as discussed in Section 7.10, “Copying Objects From Other PDF Filesâ€. For an example of how to use reserved objects, search for newReserved in test_driver.cc in qpdf's sources. -

    6.8. Copying Objects From Other PDF Files

    +

    7.10. Copying Objects From Other PDF Files

    Version 3.0 of qpdf introduced the ability to copy objects into a QPDF object from a different QPDF object, which we refer to as @@ -1602,12 +2730,12 @@ have finished with the destination object. This is because the original object is still used to retrieve any referenced stream data from the copied object. -

    6.9. Writing PDF Files

    +

    7.11. Writing PDF Files

    The qpdf library supports file writing of QPDF objects to PDF files through the QPDFWriter class. The QPDFWriter class has two writing modes: one - for non-linearized files, and one for linearized files. See Chapter 7, Linearization for a description of linearization + for non-linearized files, and one for linearized files. See Chapter 8, Linearization for a description of linearization is implemented. This section describes how we write non-linearized files including the creation of QDF files (see Chapter 4, QDF Mode. @@ -1696,7 +2824,7 @@ xref table. Finally we can write out the trailer dictionary with appropriately computed /ID (see spec, 8.3, File Identifiers), the cross reference table offset, and %%EOF. -

    6.10. Filtered Streams

    +

    7.12. Filtered Streams

    Support for streams is implemented through the Pipeline interface which was designed for this package. @@ -1721,18 +2849,18 @@ filter should write to whatever type of output is required. The QPDF class has an interface to write raw or filtered stream contents to a given pipeline. -





    [1] 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, and qpdf offers may transformations that can do this as well, there seems to be little point in the added complexity of conditionally enforcing document security. -

    Chapter 8. Linearization

    This chapter describes how QPDF and QPDFWriter implement creation and processing of linearized PDFS. -

    7.1. Basic Strategy for Linearization

    +

    8.1. Basic Strategy for Linearization

    To avoid the incestuous problem of having the qpdf library validate its own linearized files, we have a special linearized file checking mode which can be invoked via qpdf @@ -1743,7 +2871,7 @@ validation code was first tested against linearized files created by external tools (Acrobat and pdlin) and then used to validate files created by QPDFWriter itself. -

    7.2. Preparing For Linearization

    +

    8.2. Preparing For Linearization

    Before creating a linearized PDF file from any other PDF file, the PDF file must be altered such that all page attributes are propagated down to the page level (and not inherited from parents @@ -1751,7 +2879,7 @@ which objects refer to which other objects, being concerned with page boundaries and a few other cases. We refer to this part of preparing the PDF file as optimization, - discussed in Section 7.3, “Optimizationâ€. Note the, in + discussed in Section 8.3, “Optimizationâ€. Note the, in this context, the term optimization is a qpdf term, and the term linearization is a term from the PDF specification. Do not be confused by the fact @@ -1767,7 +2895,7 @@

  • Filling in offsets and byte sizes

  • -

    7.3. Optimization

    +

    8.3. Optimization

    In order to perform various operations such as linearization and splitting files into pages, it is necessary to know which objects are referenced by which pages, page thumbnails, and root and @@ -1802,7 +2930,7 @@ Note that pages and thumbnails have different object user types, so the above test on a page will not include objects referenced by the page's thumbnail dictionary and nothing else. -

    7.4. Writing Linearized Files

    +

    8.4. Writing Linearized Files

    We will create files with only primary hint streams. We will never write overflow hint streams. (As of PDF version 1.4, Acrobat doesn't either, and they are never necessary.) The hint @@ -1847,7 +2975,7 @@ Using this strategy, we can write linearized files to a non-seekable output stream with only a single pass to disk or wherever the output is going. -

    7.5. Calculating Linearization Data

    +

    8.5. Calculating Linearization Data

    Once a file is optimized, we have information about which objects access which other objects. We can then process these tables to decide which part (as described in “Linearized PDF Document @@ -1859,7 +2987,7 @@ thrown if an object is encountered that has not already been queued. (This could happen only if there were a bug in the traversal code used to calculate the linearization data.) -

    7.6. Known Issues with Linearization

    +

    8.6. Known Issues with Linearization

    There are a handful of known issues with this linearization code. These issues do not appear to impact the behavior of linearized files which still work as intended: it is possible for a web @@ -1883,7 +3011,7 @@ thumbnail hint tables. There are comments in the code about this.

    -

    7.7. Debugging Note

    +

    8.7. Debugging Note

    The qpdf --show-linearization command can show the complete contents of linearization hint streams. To look at the raw data, you can extract the filtered contents of the @@ -1901,10 +3029,10 @@ map { printf("%08b", ord($_)) } @ch; print "\n";

    -

    Chapter 9. Object and Cross-Reference Streams

    This chapter provides information about the implementation of object stream and cross-reference stream support in qpdf. -

    8.1. Object Streams

    +

    9.1. Object Streams

    Object streams can contain any regular object except the following:

    • @@ -1921,7 +3049,7 @@ object stream if the file is encrypted, though this is not specifically disallowed by the specification.

      - There are additional restrictions for linearized files. See Section 8.3, “Implications for Linearized Filesâ€for details. + There are additional restrictions for linearized files. See Section 9.3, “Implications for Linearized Filesâ€for details.

      The PDF specification refers to objects in object streams as “compressed objects†regardless of whether the object @@ -1959,7 +3087,7 @@ integers, each of which is the object number and the byte offset of the object relative to the first object in the stream, followed by the objects themselves, concatenated. -

    8.2. Cross-Reference Streams

    +

    9.2. Cross-Reference Streams

    For non-hybrid files, the value following startxref is the byte offset to the xref stream rather than the word xref. @@ -2012,7 +3140,7 @@ The other fields in the xref stream, which may be indirect if desired, are the union of those from the xref table's trailer dictionary. -

    8.2.1. Cross-Reference Stream Data

    +

    9.2.1. Cross-Reference Stream Data

    The stream data is binary and encoded in big-endian byte order. Entries are concatenated, and each entry has a length equal to the total of the entries in /W above. Each @@ -2042,7 +3170,7 @@ It seems standard to have the first entry in the table be 0 0 0 instead of 0 0 ffff if there are no deleted objects. -

    8.3. Implications for Linearized Files

    +

    9.3. Implications for Linearized Files

    For linearized files, the linearization dictionary, document catalog, and page objects may not be contained in object streams.

    @@ -2062,7 +3190,7 @@ When numbering objects, all shared objects within both the first and second halves of the linearized files must be numbered consecutively after all normal uncompressed objects in that half. -

    8.4. Implementation Notes

    +

    9.4. Implementation Notes

    There are three modes for writing object streams: disable, preserve, and generate. In disable mode, we do not generate @@ -2084,7 +3212,1179 @@

    Appendix A. Release Notes

    For a detailed list of changes, please see the file ChangeLog in the source distribution. -

    8.0.2: March 6, 2018
    • +

      10.0.1: April 9, 2020
      • + Bug Fixes +

        • + 10.0.0 introduced a bug in which calling + QPDFObjectHandle::getStreamData on a + stream that can't be filtered was returning the raw data + instead of throwing an exception. This is now fixed. +

        • + Fix a bug that was preventing qpdf from linking with some + versions of clang on some platforms. +

      • + Enhancements +

        • + Improve the pdf-invert-images example + to avoid having to load all the images into RAM at the same + time. +

      10.0.0: April 6, 2020
      • + Performance Enhancements +

        • + The qpdf library and executable should run much faster in + this version than in the last several releases. Several + internal library optimizations have been made, and there has + been improved behavior on page splitting as well. This + version of qpdf should outperform any of the 8.x or 9.x + versions. +

      • + Incompatible API (source-level) Changes (minor) +

        • + The QUtil::srandom method was removed. + It didn't do anything unless insecure random numbers were + compiled in, and they have been off by default for a long + time. If you were calling it, just remove the call since it + wasn't doing anything anyway. +

      • + Build/Packaging Changes +

        • + Add a openssl crypto provider, which is + implemented with OpenSSL and also works with BoringSSL. + Thanks to Dean Scarff for this contribution. If you maintain + qpdf for a distribution, pay special attention to make sure + that you are including support for the crypto providers you + want. Package maintainers will have to weigh the advantages + of allowing users to pick a crypto provider at runtime + against the disadvantages of adding more dependencies to + qpdf. +

        • + Allow qpdf to built on stripped down systems whose C/C++ + libraries lack the wchar_t type. + Search for wchar_t in qpdf's + README.md for details. This should be very rare, but it is + known to be helpful in some embedded environments. +

      • + CLI Enhancements +

        • + Add objectinfo key to the JSON output. + This will be a place to put computed metadata or other + information about PDF objects that are not immediately + evident in other ways or that seem useful for some other + reason. In this version, information is provided about each + object indicating whether it is a stream and, if so, what + its length and filters are. Without this, it was not + possible to tell conclusively from the JSON output alone + whether or not an object was a stream. Run qpdf + --json-help for details. +

        • + Add new option + --remove-unreferenced-resources which takes + auto, yes, or + no as arguments. The new + auto mode, which is the default, performs + a fast heuristic over a PDF file when splitting pages to + determine whether the expensive process of finding and + removing unreferenced resources is likely to be of benefit. + For most files, this new default will result in a + significant performance improvement for splitting pages. See + Section 3.8, “Advanced Transformation Options†for a more + detailed discussion. +

        • + The --preserve-unreferenced-resources is + now just a synonym for + --remove-unreferenced-resources=no. +

        • + If the QPDF_EXECUTABLE environment + variable is set when invoking qpdf + --bash-completion or qpdf + --zsh-completion, the completion command that it + outputs will refer to qpdf using the value of that variable + rather than what qpdf determines its + executable path to be. This can be useful when wrapping + qpdf with a script, working with a + version in the source tree, using an AppImage, or other + situations where there is some indirection. +

      • + Library Enhancements +

        • + Random number generation is now delegated to the crypto + provider. The old behavior is still used by the native + crypto provider. It is still possible to provide your own + random number generator. +

        • + Add a new version of + QPDFObjectHandle::StreamDataProvider::provideStreamData + that accepts the suppress_warnings and + will_retry options and allows a success + code to be returned. This makes it possible to implement a + StreamDataProvider that calls + pipeStreamData on another stream and to + pass the response back to the caller, which enables better + error handling on those proxied streams. +

        • + Update QPDFObjectHandle::pipeStreamData + to return an overall success code that goes beyond whether + or not filtered data was written successfully. This allows + better error handling of cases that were not filtering + errors. You have to call this explicitly. Methods in + previously existing APIs have the same semantics as before. +

        • + The + QPDFPageObjectHelper::placeFormXObject + method now allows separate control over whether it should be + willing to shrink or expand objects to fit them better into + the destination rectangle. The previous behavior was that + shrinking was allowed but expansion was not. The previous + behavior is still the default. +

        • + When calling the C API, any non-zero value passed to a + boolean parameter is treated as TRUE. + Previously only the value 1 was accepted. + This makes the C API behave more like most C interfaces and + is known to improve compatibility with some Windows + environments that dynamically load the DLL and call + functions from it. +

        • + Add QPDFObjectHandle::unsafeShallowCopy + for copying only top-level dictionary keys or array items. + This is unsafe because it creates a situation in which + changing a lower-level item in one object may also change it + in another object, but for cases in which you + know you are only inserting or + replacing top-level items, it is much faster than + QPDFObjectHandle::shallowCopy. +

        • + Add QPDFObjectHandle::filterAsContents, + which filter's a stream's data as a content stream. This is + useful for parsing the contents for form XObjects in the + same way as parsing page content streams. +

      • + Bug Fixes +

        • + When detecting and removing unreferenced resources during + page splitting, traverse into form XObjects and handle their + resources dictionaries as well. +

        • + The same error recovery is applied to streams in other than + the primary input file when merging or splitting pages. +

      9.1.1: January 26, 2020
      • + Build/Packaging Changes +

        • + The fix-qdf program was converted from perl to C++. As such, + qpdf no longer has a runtime dependency on perl. +

      • + Library Enhancements +

        • + Added new helper routine + QUtil::call_main_from_wmain which + converts wchar_t arguments to UTF-8 encoded + strings. This is useful for qpdf because library methods + expect file names to be UTF-8 encoded, even on Windows +

        • + Added new QUtil::read_lines_from_file + methods that take FILE* arguments and that + allow preservation of end-of-line characters. This also + fixes a bug where + QUtil::read_lines_from_file wouldn't + work properly with Unicode filenames. +

      • + CLI Enhancements +

        • + Added options --is-encrypted and + --requires-password for testing whether a + file is encrypted or requires a password other than the + supplied (or empty) password. These communicate via exit + status, making them useful for shell scripts. They also work + on encrypted files with unknown passwords. +

        • + Added encrypt key to JSON options. With + the exception of the reconstructed user password for older + encryption formats, this provides the same information as + --show-encryption but in a consistent, + parseable format. See output of qpdf + --json-help for details. +

      • + Bug Fixes +

        • + In QDF mode, be sure not to write more than one XRef stream + to a file, even when + --preserve-unreferenced is used. + fix-qdf assumes that there is only one + XRef stream, and that it appears at the end of the file. +

        • + When externalizing inline images, properly handle images + whose color space is a reference to an object in the page's + resource dictionary. +

        • + Windows-specific fix for acquiring crypt context with a new + keyset. +

      9.1.0: November 17, 2019
      • + Build Changes +

      • + Library Enhancements +

        • + Incorporate contribution from Masamichi Hosoda to properly + handle signature dictionaries by not including them in + object streams, formatting the Contents + key has a hexadecimal string, and excluding the + /Contents key from encryption and + decryption. +

        • + Incorporate contribution from Masamichi Hosoda to provide + new API calls for getting file-level information about + input and output files, enabling certain operations on + the files at the file level rather than the object level. + New methods include + QPDF::getXRefTable(), + QPDFObjectHandle::getParsedOffset(), + QPDFWriter::getRenumberedObjGen(QPDFObjGen), + and QPDFWriter::getWrittenXRefTable(). +

        • + Support build-time and runtime selectable crypto providers. + This includes the addition of new classes + QPDFCryptoProvider and + QPDFCryptoImpl and the recognition + of the QPDF_CRYPTO_PROVIDER environment + variable. Crypto providers are described in depth in Section 2.3, “Crypto Providersâ€. +

      • + CLI Enhancements +

        • + Addition of the --show-crypto option in + support of selectable crypto providers, as described in + Section 2.3, “Crypto Providersâ€. +

        • + Allow :even or :odd to + be appended to numeric ranges for specification of the even + or odd pages from among the pages specified in the range. +

        • + Fix shell wildcard expansion behavior (* + and ?) of the qpdf.exe + as built my MSVC. +

      9.0.2: October 12, 2019
      • + Bug Fix +

        • + Fix the name of the temporary file used by + --replace-input so that it doesn't require + path splitting and works with paths include directories. +

      9.0.1: September 20, 2019
      • + Bug Fixes/Enhancements +

        • + Fix some build and test issues on big-endian systems and + compilers with characters that are unsigned by default. + The problems were in build and test only. There were no + actual bugs in the qpdf library itself relating to + endianness or unsigned characters. +

        • + When a dictionary has a duplicated key, report this with a + warning. The behavior of the library in this case is + unchanged, but the error condition is no longer silently + ignored. +

        • + When a form field's display rectangle is erroneously + specified with inverted coordinates, detect and correct this + situation. This avoids some form fields from being flipped + when flattening annotations on files with this condition. +

      9.0.0: August 31, 2019
      • + Incompatible API (source-level) Changes (minor) +

        • + The method QUtil::strcasecmp has been + renamed to QUtil::str_compare_nocase. + This incompatible change is necessary to enable qpdf to + build on platforms that define + strcasecmp as a macro. +

        • + The QPDF::copyForeignObject method had + an overloaded version that took a boolean parameter that was + not used. If you were using this version, just omit the + extra parameter. +

        • + There was a version + QPDFTokenizer::expectInlineImage that + took no arguments. This version has been removed since it + caused the tokenizer to return incorrect inline images. A + new version was added some time ago that produces correct + output. This is a very low level method that doesn't make + sense to call outside of qpdf's lexical engine. There are + higher level methods for tokenizing content streams. +

        • + Change + QPDFOutlineDocumentHelper::getTopLevelOutlines + and QPDFOutlineObjectHelper::getKids to + return a std::vector instead of a + std::list of + QPDFOutlineObjectHelper objects. +

        • + Remove method + QPDFTokenizer::allowPoundAnywhereInName. + This function would allow creation of name tokens whose + value would change when unparsed, which is never the correct + behavior. +

      • + CLI Enhancements +

        • + The --replace-input option may be given in + place of an output file name. This causes qpdf to overwrite + the input file with the output. See the description of + --replace-input in Section 3.3, “Basic Options†for more details. +

        • + The --recompress-flate instructs + qpdf to recompress streams that are + already compressed with /FlateDecode. + Useful with --compression-level. +

        • + The + --compression-level=level + sets the zlib compression level used for any streams + compressed by /FlateDecode. Most + effective when combined with + --recompress-flate. +

      • + Library Enhancements +

        • + A new namespace QIntC, provided by + qpdf/QIntC.hh, provides safe conversion + methods between different integer types. These conversion + methods do range checking to ensure that the cast can be + performed with no loss of information. Every use of + static_cast in the library was + inspected to see if it could use one of these safe + converters instead. See Section 7.5, “Casting Policy†for + additional details. +

        • + Method QPDF::anyWarnings tells whether + there have been any warnings without clearing the list of + warnings. +

        • + Method QPDF::closeInputSource closes or + otherwise releases the input source. This enables the input + file to be deleted or renamed. +

        • + New methods have been added to QUtil + for converting back and forth between strings and unsigned + integers: uint_to_string, + uint_to_string_base, + string_to_uint, and + string_to_ull. +

        • + New methods have been added to + QPDFObjectHandle that return the + value of Integer objects as + int or unsigned int with range + checking and sensible fallback values, and a new method was + added to return an unsigned value. This makes it easier to + write code that is safe from unintentional data loss. + Functions: getUIntValue, + getIntVauleAsInt, + getUIntValueAsUInt. +

        • + When parsing content streams with + QPDFObjectHandle::ParserCallbacks, in + place of the method + handleObject(QPDFObjectHandle), the + developer may override + handleObject(QPDFObjectHandle, size_t offset, + size_t length). If this method is defined, it + will be invoked with the object along with its offset and + length within the overall contents being parsed. Intervening + spaces and comments are not included in offset and length. + Additionally, a new method + contentSize(size_t) may be implemented. + If present, it will be called prior to the first call to + handleObject with the total size in + bytes of the combined contents. +

        • + New methods QPDF::userPasswordMatched + and QPDF::ownerPasswordMatched have + been added to enable a caller to determine whether the + supplied password was the user password, the owner password, + or both. This information is also displayed by qpdf + --show-encryption and qpdf + --check. +

        • + Static method + Pl_Flate::setCompressionLevel can be + called to set the zlib compression level globally used by + all instances of Pl_Flate in deflate mode. +

        • + The method + QPDFWriter::setRecompressFlate can be + called to tell QPDFWriter to + uncompress and recompress streams already compressed with + /FlateDecode. +

        • + The underlying implementation of QPDF arrays has been + enhanced to be much more memory efficient when dealing with + arrays with lots of nulls. This enables qpdf to use + drastically less memory for certain types of files. +

        • + When traversing the pages tree, if nodes are encountered + with invalid types, the types are fixed, and a warning is + issued. +

        • + A new helper method + QUtil::read_file_into_memory was added. +

        • + All conditions previously reported by + QPDF::checkLinearization() as errors + are now presented as warnings. +

        • + Name tokens containing the # character + not preceded by two hexadecimal digits, which is invalid in + PDF 1.2 and above, are properly handled by the library: a + warning is generated, and the name token is properly + preserved, even if invalid, in the output. See + ChangeLog for a more complete + description of this change. +

      • + Bug Fixes +

        • + A small handful of memory issues, assertion failures, and + unhandled exceptions that could occur on badly mangled input + files have been fixed. Most of these problems were found by + Google's OSS-Fuzz project. +

        • + When qpdf --check or qpdf + --check-linearization encounters a file with + linearization warnings but not errors, it now properly exits + with exit code 3 instead of 2. +

        • + The --completion-bash and + --completion-zsh options now work properly + when qpdf is invoked as an AppImage. +

        • + Calling + QPDFWriter::set*EncryptionParameters on + a QPDFWriter object whose output + filename has not yet been set no longer produces a + segmentation fault. +

        • + When reading encrypted files, follow the spec more closely + regarding encryption key length. This allows qpdf to open + encrypted files in most cases when they have invalid or + missing /Length keys in the encryption dictionary. +

      • + Build Changes +

        • + On platforms that support it, qpdf now builds with + -fvisibility=hidden. If you build qpdf with + your own build system, this is now safe to use. This + prevents methods that are not part of the public API from + being exported by the shared library, and makes qpdf's ELF + shared libraries (used on Linux, MacOS, and most other UNIX + flavors) behave more like the Windows DLL. Since the DLL + already behaves in much this way, it is unlikely that there + are any methods that were accidentally not exported. + However, with ELF shared libraries, typeinfo for some + classes has to be explicitly exported. If there are problems + in dynamically linked code catching exceptions or + subclassing, this could be the reason. If you see this, + please report a bug at https://github.com/qpdf/qpdf/issues/. +

        • + QPDF is now compiled with integer conversion and sign + conversion warnings enabled. Numerous changes were made to + the library to make this safe. +

        • + QPDF's make install target explicitly + specifies the mode to use when installing files instead of + relying the user's umask. It was previously doing this for + some files but not others. +

        • + If pkg-config is available, use it to + locate libjpeg and + zlib dependencies, falling back on old + behavior if unsuccessful. +

      • + Other Notes +

        • + QPDF has been fully integrated into Google's OSS-Fuzz + project. This project exercises code with randomly + mutated inputs and is great for discovering hidden security + crashes and security issues. Several bugs found by oss-fuzz + have already been fixed in qpdf. +

      8.4.2: May 18, 2019

      + This release has just one change: correction of a buffer overrun + in the Windows code used to open files. Windows users should + take this update. There are no code changes that affect + non-Windows releases. +

      8.4.1: April 27, 2019
      • + Enhancements +

        • + When qpdf --version is run, it will + detect if the qpdf CLI was built with a different version of + qpdf than the library, which may indicate a problem with the + installation. +

        • + New option --remove-page-labels will remove page + labels before generating output. This used to happen if you + ran qpdf --empty --pages .. --, but the + behavior changed in qpdf 8.3.0. This option enables people + who were relying on the old behavior to get it again. +

        • + New option + --keep-files-open-threshold=count + can be used to override number of files that qpdf will use + to trigger the behavior of not keeping all files open when + merging files. This may be necessary if your system allows + fewer than the default value of 200 files to be open at the + same time. +

      • + Bug Fixes +

        • + Handle Unicode characters in filenames on Windows. The + changes to support Unicode on the CLI in Windows broke + Unicode filenames for Windows. +

        • + Slightly tighten logic that determines whether an object is + a page. This should resolve problems in some rare files + where some non-page objects were passing qpdf's test for + whether something was a page, thus causing them to be + erroneously lost during page splitting operations. +

        • + Revert change that included preservation of outlines + (bookmarks) in --split-pages. The way it + was implemented in 8.3.0 and 8.4.0 caused a very significant + degradation of performance for splitting certain files. A + future release of qpdf may re-introduce the behavior in a + more performant and also more correct fashion. +

        • + In JSON mode, add missing leading 0 to decimal values + between -1 and 1 even if not present in the input. The JSON + specification requires the leading 0. The PDF specification + does not. +

      8.4.0: February 1, 2019
      • + Command-line Enhancements +

        • + Non-compatible CLI change: The qpdf + command-line tool interprets passwords given at the + command-line differently from previous releases when the + passwords contain non-ASCII characters. In some cases, the + behavior differs from previous releases. For a discussion of + the current behavior, please see Section 3.10, “Unicode Passwordsâ€. The incompatibilities are + as follows: +

          • + On Windows, qpdf now receives all command-line options as + Unicode strings if it can figure out the appropriate + compile/link options. This is enabled at least for MSVC + and mingw builds. That means that if non-ASCII strings + are passed to the qpdf CLI in Windows, qpdf will now + correctly receive them. In the past, they would have + either been encoded as Windows code page 1252 (also known + as “Windows ANSI†or as something + unintelligible. In almost all cases, qpdf is able to + properly interpret Unicode arguments now, whereas in the + past, it would almost never interpret them properly. The + result is that non-ASCII passwords given to the qpdf CLI + on Windows now have a much greater chance of creating PDF + files that can be opened by a variety of readers. In the + past, usually files encrypted from the Windows CLI using + non-ASCII passwords would not be readable by most + viewers. Note that the current version of qpdf is able to + decrypt files that it previously created using the + previously supplied password. +

          • + The PDF specification requires passwords to be encoded as + UTF-8 for 256-bit encryption and with PDF Doc encoding + for 40-bit or 128-bit encryption. Older versions of qpdf + left it up to the user to provide passwords with the + correct encoding. The qpdf CLI now detects when a + password is given with UTF-8 encoding and automatically + transcodes it to what the PDF spec requires. While this + is almost always the correct behavior, it is possible to + override the behavior if there is some reason to do so. + This is discussed in more depth in Section 3.10, “Unicode Passwordsâ€. +

          +

        • + New options --externalize-inline-images, + --ii-min-bytes, and + --keep-inline-images control qpdf's + handling of inline images and possible conversion of them to + regular images. By default, + --optimize-images now also applies to + inline images. These options are discussed in Section 3.8, “Advanced Transformation Optionsâ€. +

        • + Add options --overlay and + --underlay for overlaying or underlaying + pages of other files onto output pages. See Section 3.6, “Overlay and Underlay Options†for details. +

        • + When opening an encrypted file with a password, if the + specified password doesn't work and the password contains + any non-ASCII characters, qpdf will try a number of + alternative passwords to try to compensate for possible + character encoding errors. This behavior can be suppressed + with the --suppress-password-recovery + option. See Section 3.10, “Unicode Passwords†for a + full discussion. +

        • + Add the --password-mode option to fine-tune + how qpdf interprets password arguments, especially when they + contain non-ASCII characters. See Section 3.10, “Unicode Passwords†for more information. +

        • + In the --pages option, it is now possible + to copy the same page more than once from the same file + without using the previous workaround of specifying two + different paths to the same file. +

        • + In the --pages option, allow use of + “.†as a shortcut for the primary input file. + That way, you can do qpdf in.pdf --pages . 1-2 -- + out.pdf instead of having to repeat + in.pdf in the command. +

        • + When encrypting with 128-bit and 256-bit encryption, new + encryption options --assemble, + --annotate, --form, and + --modify-other allow more fine-grained + granularity in configuring options. Before, the + --modify option only configured certain + predefined groups of permissions. +

      • + Bug Fixes and Enhancements +

        • + Potential data-loss bug: Versions of + qpdf between 8.1.0 and 8.3.0 had a bug that could cause page + splitting and merging operations to drop some font or image + resources if the PDF file's internal structure shared these + resource lists across pages and if some but not all of the + pages in the output did not reference all the fonts and + images. Using the + --preserve-unreferenced-resources option + would work around the incorrect behavior. This bug was the + result of a typo in the code and a deficiency in the test + suite. The case that triggered the error was known, just not + handled properly. This case is now exercised in qpdf's test + suite and properly handled. +

        • + When optimizing images, detect and refuse to optimize + images that can't be converted to JPEG because of bit depth + or color space. +

        • + Linearization and page manipulation APIs now detect and + recover from files that have duplicate Page objects in the + pages tree. +

        • + Using older option --stream-data=compress + with object streams, object streams and xref streams were + not compressed. +

        • + When the tokenizer returns inline image tokens, delimiters + following ID and EI + operators are no longer excluded. This makes it possible to + reliably extract the actual image data. +

      • + Library Enhancements +

        • + Add method + QPDFPageObjectHelper::externalizeInlineImages + to convert inline images to regular images. +

        • + Add method + QUtil::possible_repaired_encodings() to + generate a list of strings that represent other ways the + given string could have been encoded. This is the method the + QPDF CLI uses to generate the strings it tries when + recovering incorrectly encoded Unicode passwords. +

        • + Add new versions of + QPDFWriter::setR{3,4,5,6}EncryptionParameters + that allow more granular setting of permissions bits. See + QPDFWriter.hh for details. +

        • + Add new versions of the transcoders from UTF-8 to + single-byte coding systems in QUtil + that report success or failure rather than just substituting + a specified unknown character. +

        • + Add method QUtil::analyze_encoding() to + determine whether a string has high-bit characters and is + appears to be UTF-16 or valid UTF-8 encoding. +

        • + Add new method + QPDFPageObjectHelper::shallowCopyPage() + to copy a new page that is a “shallow copy†of a + page. The resulting object is an indirect object ready to be + passed to + QPDFPageDocumentHelper::addPage() for + either the original QPDF object or a + different one. This is what the qpdf + command-line tool uses to copy the same page multiple times + from the same file during splitting and merging operations. +

        • + Add method QPDF::getUniqueId(), which + returns a unique identifier for the given QPDF object. The + identifier will be unique across the life of the + application. The returned value can be safely used as a map + key. +

        • + Add method QPDF::setImmediateCopyFrom. + This further enhances qpdf's ability to allow a + QPDF object from which objects are + being copied to go out of scope before the destination + object is written. If you call this method on a + QPDF instances, objects copied + from this instance will be copied + immediately instead of lazily. This option uses more memory + but allows the source object to go out of scope before the + destination object is written in all cases. See comments in + QPDF.hh for details. +

        • + Add method + QPDFPageObjectHelper::getAttribute for + retrieving an attribute from the page dictionary taking + inheritance into consideration, and optionally making a copy + if your intention is to modify the attribute. +

        • + Fix long-standing limitation of + QPDFPageObjectHelper::getPageImages so + that it now properly reports images from inherited resources + dictionaries, eliminating the need to call + QPDFPageDocumentHelper::pushInheritedAttributesToPage + in this case. +

        • + Add method + QPDFObjectHandle::getUniqueResourceName + for finding an unused name in a resource dictionary. +

        • + Add method + QPDFPageObjectHelper::getFormXObjectForPage + for generating a form XObject equivalent to a page. The + resulting object can be used in the same file or copied to + another file with copyForeignObject. + This can be useful for implementing underlay, overlay, n-up, + thumbnails, or any other functionality requiring replication + of pages in other contexts. +

        • + Add method + QPDFPageObjectHelper::placeFormXObject + for generating content stream text that places a given form + XObject on a page, centered and fit within a specified + rectangle. This method takes care of computing the proper + transformation matrix and may optionally compensate for + rotation or scaling of the destination page. +

      • + Build Improvements +

        • + Add new configure option + --enable-avoid-windows-handle, which causes + the preprocessor symbol + AVOID_WINDOWS_HANDLE to be defined. When + defined, qpdf will avoid referencing the Windows + HANDLE type, which is disallowed with + certain versions of the Windows SDK. +

        • + For Windows builds, attempt to determine what options, if + any, have to be passed to the compiler and linker to enable + use of wmain. This causes the + preprocessor symbol WINDOWS_WMAIN to be + defined. If you do your own builds with other compilers, you + can define this symbol to cause wmain + to be used. This is needed to allow the Windows + qpdf command to receive Unicode + command-line options. +

      8.3.0: January 7, 2019
      • + Command-line Enhancements +

        • + Shell completion: you can now use eval $(qpdf + --completion-bash) and eval $(qpdf + --completion-zsh) to enable shell completion for + bash and zsh. +

        • + Page numbers (also known as page labels) are now preserved + when merging and splitting files with the + --pages and --split-pages + options. +

        • + Bookmarks are partially preserved when splitting pages with + the --split-pages option. Specifically, the + outlines dictionary and some supporting metadata are copied + into the split files. The result is that all bookmarks from + the original file appear, those that point to pages that are + preserved work, and those that point to pages that are not + preserved don't do anything. This is an interim step toward + proper support for bookmarks in splitting and merging + operations. +

        • + Page collation: add new option --collate. + When specified, the semantics of --pages + change from concatenation to collation. See Section 3.5, “Page Selection Options†for examples and discussion. +

        • + Generation of information in JSON format, primarily to + facilitate use of qpdf from languages other than C++. Add + new options --json, + --json-key, and + --json-object to generate a JSON + representation of the PDF file. Run qpdf + --json-help to get a description of the JSON + format. For more information, see Chapter 6, QPDF JSON. +

        • + The --generate-appearances flag will cause + qpdf to generate appearances for form fields if the PDF file + indicates that form field appearances are out of date. This + can happen when PDF forms are filled in by a program that + doesn't know how to regenerate the appearances of the + filled-in fields. +

        • + The --flatten-annotations flag can be used + to flatten annotations, including form + fields. Ordinarily, annotations are drawn separately from + the page. Flattening annotations is the process of combining + their appearances into the page's contents. You might want + to do this if you are going to rotate or combine pages using + a tool that doesn't understand about annotations. You may + also want to use --generate-appearances + when using this flag since annotations for outdated form + fields are not flattened as that would cause loss of + information. +

        • + The --optimize-images flag tells qpdf to + recompresses every image using DCT (JPEG) compression as + long as the image is not already compressed with lossy + compression and recompressing the image reduces its size. + The additional options --oi-min-width, + --oi-min-height, and + --oi-min-area prevent recompression of + images whose width, height, or pixel area + (width × height) are below a specified + threshold. +

        • + The --show-object option can now be given + as --show-object=trailer to show the + trailer dictionary. +

      • + Bug Fixes and Enhancements +

        • + QPDF now automatically detects and recovers from dangling + references. If a PDF file contained an indirect reference to + a non-existent object, which is valid, when adding a new + object to the file, it was possible for the new object to + take the object ID of the dangling reference, thereby + causing the dangling reference to point to the new object. + This case is now prevented. +

        • + Fixes to form field setting code: strings are always written + in UTF-16 format, and checkboxes and radio buttons are + handled properly with respect to synchronization of values + and appearance states. +

        • + The QPDF::checkLinearization() no + longer causes the program to crash when it detects problems + with linearization data. Instead, it issues a normal warning + or error. +

        • + Ordinarily qpdf treats an argument of the form + @file to mean that command-line options + should be read from file. Now, if + file does not exist but + @file does, qpdf will treat + @file as a regular option. This makes + it possible to work more easily with PDF files whose names + happen to start with the @ character. +

      • + Library Enhancements +

        • + Remove the restriction in most cases that the source QPDF + object used in a + QPDF::copyForeignObject call has to + stick around until the destination QPDF is written. The + exceptional case is when the source stream gets is data + using a QPDFObjectHandle::StreamDataProvider. For a more + in-depth discussion, see comments around + copyForeignObject in + QPDF.hh. +

        • + Add new method + QPDFWriter::getFinalVersion(), which + returns the PDF version that will ultimately be written to + the final file. See comments in + QPDFWriter.hh for some restrictions on + its use. +

        • + Add several methods for transcoding strings to some of the + character sets used in PDF files: + QUtil::utf8_to_ascii, + QUtil::utf8_to_win_ansi, + QUtil::utf8_to_mac_roman, and + QUtil::utf8_to_utf16. For the + single-byte encodings that support only a limited character + sets, these methods replace unsupported characters with a + specified substitute. +

        • + Add new methods to + QPDFAnnotationObjectHelper and + QPDFFormFieldObjectHelper for + querying flags and interpretation of different field types. + Define constants in qpdf/Constants.h to + help with interpretation of flag values. +

        • + Add new methods + QPDFAcroFormDocumentHelper::generateAppearancesIfNeeded + and + QPDFFormFieldObjectHelper::generateAppearance + for generating appearance streams. See discussion in + QPDFFormFieldObjectHelper.hh for + limitations. +

        • + Add two new helper functions for dealing with resource + dictionaries: + QPDFObjectHandle::getResourceNames() + returns a list of all second-level keys, which correspond to + the names of resources, and + QPDFObjectHandle::mergeResources() + merges two resources dictionaries as long as they have + non-conflicting keys. These methods are useful for certain + types of objects that resolve resources from multiple places, + such as form fields. +

        • + Add methods + QPDFPageDocumentHelper::flattenAnnotations() + and + QPDFAnnotationObjectHelper::getPageContentForAppearance() + for handling low-level details of annotation flattening. +

        • + Add new helper classes: + QPDFOutlineDocumentHelper, + QPDFOutlineObjectHelper, + QPDFPageLabelDocumentHelper, + QPDFNameTreeObjectHelper, and + QPDFNumberTreeObjectHelper. +

        • + Add method QPDFObjectHandle::getJSON() + that returns a JSON representation of the object. Call + serialize() on the result to convert it + to a string. +

        • + Add a simple JSON serializer. This is not a complete or + general-purpose JSON library. It allows assembly and + serialization of JSON structures with some restrictions, + which are described in the header file. This is the + serializer used by qpdf's new JSON representation. +

        • + Add new QPDFObjectHandle::Matrix + class along with a few convenience methods for dealing with + six-element numerical arrays as matrices. +

        • + Add new method + QPDFObjectHandle::wrapInArray, which returns + the object itself if it is an array, or an array containing + the object otherwise. This is a common construct in PDF. + This method prevents you from having to explicitly test + whether something is a single element or an array. +

      • + Build Improvements +

        • + It is no longer necessary to run + autogen.sh to build from a pristine + checkout. Automatically generated files are now committed so + that it is possible to build on platforms without autoconf + directly from a clean checkout of the repository. The + configure script detects if the files are + out of date when it also determines that the tools are + present to regenerate them. +

        • + Pull requests and the master branch are now built + automatically in Azure + Pipelines, which is free for open source projects. + The build includes Linux, mac, Windows 32-bit and 64-bit + with mingw and MSVC, and an AppImage build. Official qpdf + releases are now built with Azure Pipelines. +

      • + Notes for Packagers +

        • + A new section has been added to the documentation with notes + for packagers. Please see Section 2.4, “Notes for Packagersâ€. +

        • + The qpdf detects out-of-date automatically generated files. + If your packaging system automatically refreshes libtool or + autoconf files, it could cause this check to fail. To avoid + this problem, pass + --disable-check-autofiles to + configure. +

        • + If you would like to have qpdf completion enabled + automatically, you can install completion files in the + distribution's default location. You can find sample + completion files to install in the + completions directory. +

      8.2.1: August 18, 2018
      • + Command-line Enhancements +

        • + Add + --keep-files-open=[yn] + to override default determination of whether to keep files + open when merging. Please see the discussion of + --keep-files-open in Section 3.3, “Basic Options†for additional details. +

      8.2.0: August 16, 2018
      • + Command-line Enhancements +

        • + Add --no-warn option to suppress issuing + warning messages. If there are any conditions that would + have caused warnings to be issued, the exit status is still + 3. +

      • + Bug Fixes and Optimizations +

        • + Performance fix: optimize page merging operation to avoid + unnecessary open/close calls on files being merged. This + solves a dramatic slow-down that was observed when merging + certain types of files. +

        • + Optimize how memory was used for the TIFF predictor, + drastically improving performance and memory usage for files + containing high-resolution images compressed with Flate + using the TIFF predictor. +

        • + Bug fix: end of line characters were not properly handled + inside strings in some cases. +

        • + Bug fix: using --progress on very small + files could cause an infinite loop. +

      • + API enhancements +

        • + Add new class QPDFSystemError, derived + from std::runtime_error, which is now + thrown by QUtil::throw_system_error. + This enables the triggering errno + value to be retrieved. +

        • + Add ClosedFileInputSource::stayOpen + method, enabling a + ClosedFileInputSource to stay open + during manually indicated periods of high activity, thus + reducing the overhead of frequent open/close operations. +

      • + Build Changes +

        • + For the mingw builds, change the name of the DLL import + library from libqpdf.a to + libqpdf.dll.a to more accurately + reflect that it is an import library rather than a static + library. This potentially clears the way for supporting a + static library in the future, though presently, the qpdf + Windows build only builds the DLL and executables. +

      8.1.0: June 23, 2018
      • + Usability Improvements +

        • + When splitting files, qpdf detects fonts and images that the + document metadata claims are referenced from a page but are + not actually referenced and omits them from the output file. + This change can cause a significant reduction in the size of + split PDF files for files created by some software packages. + In some cases, it can also make page splitting slower. Prior + versions of qpdf would believe the document metadata and + sometimes include all the images from all the other pages + even though the pages were no longer present. In the + unlikely event that the old behavior should be desired, or + if you have a case where page splitting is very slow, the + old behavior (and speed) can be enabled by specifying + --preserve-unreferenced-resources. For + additional details, please see Section 3.8, “Advanced Transformation Optionsâ€. +

        • + When merging multiple PDF files, qpdf no longer leaves all + the files open. This makes it possible to merge numbers of + files that may exceed the operating system's limit for the + maximum number of open files. +

        • + The --rotate option's syntax has been + extended to make the page range optional. If you specify + --rotate=angle + without specifying a page range, the rotation will be + applied to all pages. This can be especially useful for + adjusting a PDF created from a multi-page document that + was scanned upside down. +

        • + When merging multiple files, the --verbose + option now prints information about each file as it operates + on that file. +

        • + When the --progress option is specified, + qpdf will print a running indicator of its best guess at how + far through the writing process it is. Note that, as with + all progress meters, it's an approximation. This option is + implemented in a way that makes it useful for software that + uses the qpdf library; see API Enhancements below. +

      • + Bug Fixes +

        • + Properly decrypt files that use revision 3 of the standard + security handler but use 40 bit keys (even though revision 3 + supports 128-bit keys). +

        • + Limit depth of nested data structures to prevent crashes + from certain types of malformed (malicious) PDFs. +

        • + In “newline before endstream†mode, insert the + required extra newline before the + endstream at the end of object streams. + This one case was previously omitted. +

      • + API Enhancements +

        • + The first round of higher level “helper†+ interfaces has been introduced. These are designed to + provide a more convenient way of interacting with certain + document features than using + QPDFObjectHandle directly. For + details on helpers, see Section 7.3, “Helper Classesâ€. Specific additional + interfaces are described below. +

        • + Add two new document helper classes: + QPDFPageDocumentHelper for working + with pages, and + QPDFAcroFormDocumentHelper for + working with interactive forms. No old methods have been + removed, but QPDFPageDocumentHelper + is now the preferred way to perform operations on pages + rather than calling the old methods in + QPDFObjectHandle and + QPDF directly. Comments in the header + files direct you to the new interfaces. Please see the + header files and ChangeLog for + additional details. +

        • + Add three new object helper class: + QPDFPageObjectHelper for pages, + QPDFFormFieldObjectHelper for + interactive form fields, and + QPDFAnnotationObjectHelper for + annotations. All three classes are fairly sparse at the + moment, but they have some useful, basic functionality. +

        • + A new example program + examples/pdf-set-form-values.cc has + been added that illustrates use of the new document and + object helpers. +

        • + The method + QPDFWriter::registerProgressReporter + has been added. This method allows you to register a + function that is called by QPDFWriter + to update your idea of the percentage it thinks it is + through writing its output. Client programs can use this to + implement reasonably accurate progress meters. The + qpdf command line tool uses this to + implement its --progress option. +

        • + New methods + QPDFObjectHandle::newUnicodeString and + QPDFObject::unparseBinary have been + added to allow for more convenient creation of strings that + are explicitly encoded using big-endian UTF-16. This is + useful for creating strings that appear outside of content + streams, such as labels, form fields, outlines, document + metadata, etc. +

        • + A new class + QPDFObjectHandle::Rectangle has been + added to ease working with PDF rectangles, which are just + arrays of four numeric values. +

      8.0.2: March 6, 2018
      • When a loop is detected while following cross reference streams or tables, treat this as damage instead of silently ignoring the previous table. This prevents loss of otherwise @@ -2093,9 +4393,9 @@ Properly handle pages with no contents.

      8.0.1: March 4, 2018
      • Disregard data check errors when uncompressing - /FlateDecode streams. This is consistent with - most other PDF readers and allows qpdf to recover data from - another class of malformed PDF files. + /FlateDecode streams. This is consistent + with most other PDF readers and allows qpdf to recover data + from another class of malformed PDF files.

      • On the command line when specifying page ranges, support preceding a page number by “r†to indicate that it @@ -2181,7 +4481,7 @@ optionally display the encryption key used by a file. This is a non-standard operation, but it can be useful in certain situations. Please see the discussion of - --password-is-hex-key in Section 3.2, “Basic Options†or the comments around + --password-is-hex-key in Section 3.3, “Basic Options†or the comments around QPDF::setPasswordIsHexKey in QPDF.hh for additional details.

      • @@ -2313,7 +4613,7 @@ and qpdf_set_newline_before_endstream corresponding to the new QPDFWriter methods. -

    6.0.0: November 10, 2015
    • +

    6.0.0: November 10, 2015