From 979eb2ba2e57d6915687ba0d238bc4eeef2ad462 Mon Sep 17 00:00:00 2001 From: Jiyong Min Date: Fri, 5 Jan 2018 08:02:59 +0900 Subject: [PATCH] Imported Upstream version 4.0.9 Change-Id: I227fcd36c78a251a89ac08c47aeeaf0600286e23 --- CMakeLists.txt | 2 +- ChangeLog | 872 ++++++++++++++++++++++++++++++++++++++- HOWTO-RELEASE | 2 +- RELEASE-DATE | 2 +- VERSION | 2 +- config/ltmain.sh | 37 +- configure | 67 ++- configure.ac | 10 +- html/Makefile.am | 4 +- html/Makefile.in | 4 +- html/index.html | 14 +- html/man/CMakeLists.txt | 2 - html/man/Makefile.am | 2 - html/man/Makefile.in | 2 - html/man/rgb2ycbcr.1.html | 155 ------- html/man/thumbnail.1.html | 148 ------- html/v4.0.7.html | 2 +- html/v4.0.8.html | 445 ++++++++++++++++++++ html/v4.0.9.html | 373 +++++++++++++++++ libtiff/libtiff.def | 2 + libtiff/tif_aux.c | 9 +- libtiff/tif_color.c | 40 +- libtiff/tif_dir.c | 50 ++- libtiff/tif_dir.h | 3 +- libtiff/tif_dirinfo.c | 105 ++++- libtiff/tif_dirread.c | 237 +++++++++-- libtiff/tif_dirwrite.c | 137 +++++- libtiff/tif_error.c | 26 +- libtiff/tif_fax3.c | 77 +++- libtiff/tif_fax3.h | 6 +- libtiff/tif_getimage.c | 329 +++++++++------ libtiff/tif_jbig.c | 3 +- libtiff/tif_jpeg.c | 209 +++++++++- libtiff/tif_jpeg_12.c | 1 + libtiff/tif_luv.c | 51 ++- libtiff/tif_lzw.c | 40 +- libtiff/tif_ojpeg.c | 25 +- libtiff/tif_open.c | 6 +- libtiff/tif_packbits.c | 12 +- libtiff/tif_pixarlog.c | 67 ++- libtiff/tif_predict.c | 25 +- libtiff/tif_print.c | 10 +- libtiff/tif_read.c | 625 +++++++++++++++++++++++----- libtiff/tif_strip.c | 11 +- libtiff/tif_swab.c | 24 +- libtiff/tif_unix.c | 10 +- libtiff/tif_warning.c | 26 +- libtiff/tif_win32.c | 10 +- libtiff/tif_write.c | 32 +- libtiff/tif_zip.c | 8 +- libtiff/tiffio.h | 5 +- libtiff/tiffiop.h | 31 +- libtiff/tiffvers.h | 4 +- m4/libtool.m4 | 27 +- man/CMakeLists.txt | 2 - man/Makefile.am | 2 - man/Makefile.in | 2 - man/TIFFGetField.3tiff | 4 +- man/TIFFSetDirectory.3tiff | 4 +- man/TIFFSetField.3tiff | 4 +- man/rgb2ycbcr.1 | 99 ----- man/thumbnail.1 | 90 ---- nmake.opt | 13 +- test/CMakeLists.txt | 34 +- test/Makefile.am | 31 +- test/Makefile.in | 73 +++- test/TiffTestCommon.cmake | 5 + test/common.sh | 1 + test/images/quad-lzw-compat.tiff | Bin 0 -> 214342 bytes test/tiff2bw-palette-1c-8b.sh | 7 + test/tiff2bw-quad-lzw-compat.sh | 7 + test/tiff2bw-rgb-3c-8b.sh | 7 + test/tiffcp-lzw-compat.sh | 6 + tools/fax2tiff.c | 6 +- tools/raw2tiff.c | 10 +- tools/tiff2bw.c | 37 +- tools/tiff2pdf.c | 42 +- tools/tiff2ps.c | 15 +- tools/tiffcp.c | 65 ++- tools/tiffcrop.c | 23 +- tools/tiffinfo.c | 4 +- tools/tiffset.c | 4 +- 82 files changed, 3928 insertions(+), 1097 deletions(-) mode change 100644 => 100755 config/ltmain.sh delete mode 100644 html/man/rgb2ycbcr.1.html delete mode 100644 html/man/thumbnail.1.html create mode 100644 html/v4.0.8.html create mode 100644 html/v4.0.9.html delete mode 100644 man/rgb2ycbcr.1 delete mode 100644 man/thumbnail.1 create mode 100644 test/images/quad-lzw-compat.tiff create mode 100755 test/tiff2bw-palette-1c-8b.sh create mode 100755 test/tiff2bw-quad-lzw-compat.sh create mode 100755 test/tiff2bw-rgb-3c-8b.sh create mode 100755 test/tiffcp-lzw-compat.sh diff --git a/CMakeLists.txt b/CMakeLists.txt index 1ee6fd4..52b5ae9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -467,7 +467,7 @@ report_values(CMAKE_HOST_SYSTEM_PROCESSOR HOST_FILLORDER HOST_BIG_ENDIAN HAVE_IEEEFP) # Large file support -if (UNIX) +if (UNIX OR MINGW) # This might not catch every possibility catered for by # AC_SYS_LARGEFILE. add_definitions(-D_FILE_OFFSET_BITS=64) diff --git a/ChangeLog b/ChangeLog index 9b9d397..ea8622b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,873 @@ +2017-11-18 Bob Friesenhahn + + * configure.ac: libtiff 4.0.9 released. + + * html/v4.0.9.html: Add HTML file to document changes in libtiff + v4.0.9. + +2017-11-17 Even Rouault + + * libtiff/tif_aux.c, tif_getimage.c, tif_read.c: typo fixes in + comments. + +2017-11-02 Bob Friesenhahn + + * test/Makefile.am: Add some tests for tiff2bw. + +2017-11-01 Bob Friesenhahn + + * tools/tiff2bw.c (main): Free memory allocated in the tiff2bw + program. This is in response to the report associated with + CVE-2017-16232 but does not solve the extremely high memory usage + with the associated POC file. + +2017-10-29 Bob Friesenhahn + + * tools/tiff2pdf.c (t2p_sample_realize_palette): Fix possible + arithmetic overflow in bounds checking code and eliminate + comparison between signed and unsigned type. + + * tools/fax2tiff.c (_FAX_Client_Data): Pass FAX_Client_Data as the + client data. This client data is not used at all at the moment, + but it makes the most sense. Issue that the value of + client_data.fd was passed where a pointer is expected was reported + via email by Gerald Schade on Sun, 29 Oct 2017. + +2017-10-23 Even Rouault + + * libtiff/tif_getimage.c: avoid floating point division by zero in + initCIELabConversion() + Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=3733 + Credit to OSS Fuzz + +2017-10-17 Even Rouault + + * libtiff/tif_jpeg.c: add compatibility with libjpeg-turbo 1.5.2 that + honours max_memory_to_use > 0. + Cf https://github.com/libjpeg-turbo/libjpeg-turbo/issues/162 + +2017-10-10 Even Rouault + + * nmake.opt: support a DEBUG=1 option, so as to adjust OPTFLAGS and use + /MDd runtime in debug mode. + +2017-10-01 Even Rouault + + * tools/tiffset.c: fix setting a single value for the ExtraSamples tag + (and other tags with variable number of values). + So 'tiffset -s ExtraSamples 1 X'. This only worked + when setting 2 or more values, but not just one. + +2017-09-29 Even Rouault + + * libtiff/libtiff.def: add TIFFReadRGBAStripExt and TIFFReadRGBATileExt + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2735 + +2017-09-09 Even Rouault + + * libtiff/tif_dirread.c: add NULL check to avoid likely false positive + null-pointer dereference warning by CLang Static Analyzer. + +2017-09-07 Even Rouault + + * libtiff/tiffiop.h, tif_aux.c: redirect SeekOK() macro to a _TIFFSeekoK() + function that checks if the offset is not bigger than INT64_MAX, so as + to avoid a -1 error return code of TIFFSeekFile() to match a required + seek to UINT64_MAX/-1. + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2726 + Adapted from proposal by Nicolas Ruff. + +2017-08-29 Even Rouault + + * libtiff/tif_jpeg.c: accept reading the last strip of a JPEG compressed + file if the codestream height is larger than the truncated height of the + strip. Emit a warning in this situation since this is non compliant. + +2017-08-28 Even Rouault + + * test/Makefile.am: add missing reference to images/quad-lzw-compat.tiff + to fix "make distcheck". Patch by Roger Leigh + +2017-08-23 Even Rouault + + * libtiff/tif_dirwrite.c: replace assertion to tag value not fitting + on uint32 when selecting the value of SubIFD tag by runtime check + (in TIFFWriteDirectoryTagSubifd()). + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2728 + Reported by team OWL337 + +2017-08-23 Even Rouault + + * libtiff/tif_dirwrite.c: replace assertion related to not finding the + SubIFD tag by runtime check (in TIFFWriteDirectorySec()) + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2727 + Reported by team OWL337 + +2017-07-24 Even Rouault + + * libtiff/tif_luv.c: further reduce memory requirements for temporary + buffer when RowsPerStrip >= image_length in LogLuvInitState() and + LogL16InitState(). + Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2700 + Credit to OSS Fuzz + +2017-07-24 Even Rouault + + * libtiff/tif_getimage.c: fix fromskew computation when to-be-skipped + pixel number is not a multiple of the horizontal subsampling, and + also in some other cases. Impact putcontig8bitYCbCr44tile, + putcontig8bitYCbCr42tile, putcontig8bitYCbCr41tile, + putcontig8bitYCbCr21tile and putcontig8bitYCbCr12tile + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2637 (discovered + by Agostino Sarubbo) + and https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2691 (credit + to OSS Fuzz) + +2017-07-24 Even Rouault + + * libtiff/tif_getimage.c: gtTileContig() and gtTileSeparate(): + properly break from loops on error when stoponerr is set, instead + of going on iterating on row based loop. + +2017-07-18 Even Rouault + + * libtiff/tif_luv.c: LogLuvInitState(): avoid excessive memory + allocation when RowsPerStrip tag is missing. + Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2683 + Credit to OSS-Fuzz + +2017-07-15 Even Rouault + + * libtiff/tif_read.c: add protection against excessive memory + allocation attempts in TIFFReadDirEntryArray() on short files. + Effective for mmap'ed case. And non-mmap'ed case, but restricted + to 64bit builds. + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2675 + +2017-07-15 Even Rouault + + * libtiff/tif_read.c: in TIFFFetchStripThing(), only grow the + arrays that hold StripOffsets/StripByteCounts, when they are smaller + than the expected number of striles, up to 1 million striles, and + error out beyond. Can be tweaked by setting the environment variable + LIBTIFF_STRILE_ARRAY_MAX_RESIZE_COUNT. + This partially goes against a change added on 2002-12-17 to accept + those arrays of wrong sizes, but is needed to avoid denial of services. + Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2350 + Credit to OSS Fuzz + +2017-07-15 Even Rouault + + * libtiff/tif_read.c: TIFFFillStrip() / TIFFFillTile(). + Complementary fix for http://bugzilla.maptools.org/show_bug.cgi?id=2708 + in the isMapped() case, so as to avoid excessive memory allocation + when we need a temporary buffer but the file is truncated. + +2017-07-15 Even Rouault + + * tools/tiff2pdf.c: prevent heap buffer overflow write in "Raw" + mode on PlanarConfig=Contig input images. + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2715 + Reported by team OWL337 + +2017-07-11 Even Rouault + + * libtiff/tif_dir.c: avoid potential null pointer dereference in + _TIFFVGetField() on corrupted TIFFTAG_NUMBEROFINKS tag instance. + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2713 + +2017-07-11 Even Rouault + + * libtiff/tif_lzw.c: fix potential out-of-buffer read on 1-byte LZW + strips. Crashing issue only on memory mapped files, where the strip + offset is the last byte of the file, and the file size is a multiple + of one page size on the CPU architecture (typically 4096). Credit + to myself :-) + +2017-07-11 Even Rouault + + * test/tiffcp-lzw-compat.sh, test/images/quad-lzw-compat.tiff: new files + to test old-style LZW decompression + * test/common.sh, Makefile.am, CMakeList.txt: updated with above + +2017-07-11 Even Rouault + + * refresh autoconf/make stuff with what is on Ubuntu 16.04 (minor changes) + +2017-07-11 Even Rouault + + * libtiff/tif_lzw.c: fix 4.0.8 regression in the decoding of old-style LZW + compressed files. + +2017-07-10 Even Rouault + + * libtiff/tif_pixarlog.c: avoid excessive memory allocation on decoding + when RowsPerStrip tag is not defined (and thus td_rowsperstrip == UINT_MAX) + Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2554 + Credit to OSS Fuzz + +2017-07-04 Even Rouault + + * libtiff/tif_read.c, tiffiop.h: add a _TIFFReadEncodedTileAndAllocBuffer() + and _TIFFReadTileAndAllocBuffer() variants of TIFFReadEncodedTile() and + TIFFReadTile() that allocates the decoded buffer only after a first + successful TIFFFillTile(). This avoids excessive memory allocation + on corrupted files. + * libtiff/tif_getimage.c: use _TIFFReadTileAndAllocBuffer(). + Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2470 + Credit to OSS Fuzz. + +2017-07-04 Even Rouault + + * libtiff/tif_error.c, tif_warning.c: correctly use va_list when both + an old-style and new-style warning/error handlers are installed. + Patch by Paavo Helde (sent on the mailing list) + +2017-07-02 Even Rouault + + * libtiff/tif_read.c: TIFFStartTile(): set tif_rawcc to + tif_rawdataloaded when it is set. Similarly to TIFFStartStrip(). + This issue was revealed by the change of 2017-06-30 in TIFFFileTile(), + limiting the number of bytes read. But it could probably have been hit + too in CHUNKY_STRIP_READ_SUPPORT mode previously ? + Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2454 + Credit to OSS Fuzz + +2017-06-30 Even Rouault + + * man: update documentation regarding SubIFD tag and + TIFFSetSubDirectory() data type. + Patch by Eric Piel + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2671 + +2017-06-30 Even Rouault + + * libtiff/tif_dirwrite.c: in TIFFWriteDirectoryTagCheckedXXXX() + functions associated with LONG8/SLONG8 data type, replace assertion that + the file is BigTIFF, by a non-fatal error. + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2712 + Reported by team OWL337 + +2017-06-30 Even Rouault + + * libtiff/tif_read.c, tiffiop.h: add a _TIFFReadEncodedStripAndAllocBuffer() + function, variant of TIFFReadEncodedStrip() that allocates the + decoded buffer only after a first successful TIFFFillStrip(). This avoids + excessive memory allocation on corrupted files. + * libtiff/tif_getimage.c: use _TIFFReadEncodedStripAndAllocBuffer(). + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2708 and + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2433 . + Credit to OSS Fuzz + +2017-06-30 Even Rouault + + * libtiff/tif_read.c: TIFFFillTile(): add limitation to the number + of bytes read in case td_stripbytecount[strip] is bigger than + reasonable, so as to avoid excessive memory allocation (similarly to + what was done for TIFFFileStrip() on 2017-05-10) + +2017-06-29 Even Rouault + + * libtiff/tiffiop.h, libtiff/tif_jpeg.c, libtiff/tif_jpeg_12.c, + libtiff/tif_read.c: make TIFFReadScanline() works in + CHUNKY_STRIP_READ_SUPPORT mode with JPEG stream with multiple scans. + Also make configurable through a LIBTIFF_JPEG_MAX_ALLOWED_SCAN_NUMBER + environment variable the maximum number of scans allowed. Defaults to + 100. + +2017-06-27 Even Rouault + + * libtiff/tif_dirread.c: in TIFFReadDirEntryFloat(), check that a + double value can fit in a float before casting. Patch by Nicolas RUFF + +2017-06-26 Even Rouault + + * libtiff/tif_jbig.c: fix memory leak in error code path of JBIGDecode() + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2706 + Reported by team OWL337 + +2017-06-24 Even Rouault + + * libtiff/tif_jpeg.c: error out at decoding time if anticipated libjpeg + memory allocation is above 100 MB. libjpeg in case of multiple scans, + which is allowed even in baseline JPEG, if components are spread over several + scans and not interleavedin a single one, needs to allocate memory (or + backing store) for the whole strip/tile. + See http://www.libjpeg-turbo.org/pmwiki/uploads/About/TwoIssueswiththeJPEGStandard.pdf + This limitation may be overriden by setting the + LIBTIFF_ALLOW_LARGE_LIBJPEG_MEM_ALLOC environment variable, or recompiling + libtiff with a custom value of TIFF_LIBJPEG_LARGEST_MEM_ALLOC macro. + +2017-06-24 Even Rouault + + * libtiff/tif_jpeg.c: add anti-denial of service measure to avoid excessive + CPU consumption on progressive JPEGs with a huge number of scans. + See http://www.libjpeg-turbo.org/pmwiki/uploads/About/TwoIssueswiththeJPEGStandard.pdf + Note: only affects libtiff since 2014-12-29 where support of non-baseline JPEG + was added. + +2017-06-18 Even Rouault + + * libtiff/tiffiop.h: add TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW macro to + disable CLang warnings raised by -fsanitize=undefined,unsigned-integer-overflow + * libtiff/tif_predict.c: decorate legitimate functions where unsigned int + overflow occur with TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW + * libtiff/tif_dirread.c: avoid unsigned int overflow in EstimateStripByteCounts() + and BYTECOUNTLOOKSBAD when file is too short. + * libtiff/tif_jpeg.c: avoid (harmless) unsigned int overflow on tiled images. + * libtiff/tif_fax3.c: avoid unsigned int overflow in Fax3Encode2DRow(). Could + potentially be a bug with huge rows. + * libtiff/tif_getimage.c: avoid many (harmless) unsigned int overflows. + +2017-06-12 Even Rouault + + * libtiff/tif_dirread.c: TIFFFetchStripThing(): limit the number of items + read in StripOffsets/StripByteCounts tags to the number of strips to avoid + excessive memory allocation. + Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2215 + Credit to OSS Fuzz + +2017-06-12 Even Rouault + + * libtiff/tif_dirread.c: fix regression of libtiff 4.0.8 in + ChopUpSingleUncompressedStrip() regarding update of newly single-strip + uncompressed files whose bytecount is 0. Before the change of 2016-12-03, + the condition bytecount==0 used to trigger an early exit/disabling of + strip chop. Re-introduce that in update mode. Otherwise this cause + later incorrect setting for the value of StripByCounts/StripOffsets. + ( https://trac.osgeo.org/gdal/ticket/6924 ) + +2017-06-10 Even Rouault + + * .appveyor.yml, .travis.yml, build/travis-ci: apply patches + 0001-ci-Travis-script-improvements.patch and + 0002-ci-Invoke-helper-script-via-shell.patch by Roger Leigh + (sent to mailing list) + +2017-06-08 Even Rouault + + * .travis.yml, build/travis-ci: new files from + 0001-ci-Add-Travis-support-for-Linux-builds-with-Autoconf.patch by + Roger Leigh (sent to mailing list on 2017-06-08) + This patch adds support for the Travis-CI service. + + * .appveyor.yml: new file from + 0002-ci-Add-AppVeyor-support.patch by Roger Leigh (sent to mailing + list on 2017-06-08) + This patch adds a .appveyor.yml file to the top-level. This allows + one to opt in to having a branch built on Windows with Cygwin, + MinGW and MSVC automatically when a branch is pushed to GitHub, + GitLab, BitBucket or any other supported git hosting service. + + * CMakeLists.txt, test/CMakeLists.txt, test/TiffTestCommon.cmake: apply + patch 0001-cmake-Improve-Cygwin-and-MingGW-test-support.patch from Roger + Leigh (sent to mailing list on 2017-06-08) + This patch makes the CMake build system support running the tests + with MinGW or Cygwin. + +2017-06-08 Even Rouault + + * libtiff/tif_swab.c: if DISABLE_CHECK_TIFFSWABMACROS is defined, do not do + the #ifdef TIFFSwabXXX checks. Make it easier for GDAL to rename the symbols + of its internal libtiff copy. + +2017-06-01 Even Rouault + + * libtiff/tif_dirinfo.c, tif_dirread.c: add _TIFFCheckFieldIsValidForCodec(), + and use it in TIFFReadDirectory() so as to ignore fields whose tag is a + codec-specified tag but this codec is not enabled. This avoids TIFFGetField() + to behave differently depending on whether the codec is enabled or not, and + thus can avoid stack based buffer overflows in a number of TIFF utilities + such as tiffsplit, tiffcmp, thumbnail, etc. + Patch derived from 0063-Handle-properly-CODEC-specific-tags.patch + (http://bugzilla.maptools.org/show_bug.cgi?id=2580) by Raphaël Hertzog. + Fixes: + http://bugzilla.maptools.org/show_bug.cgi?id=2580 + http://bugzilla.maptools.org/show_bug.cgi?id=2693 + http://bugzilla.maptools.org/show_bug.cgi?id=2625 (CVE-2016-10095) + http://bugzilla.maptools.org/show_bug.cgi?id=2564 (CVE-2015-7554) + http://bugzilla.maptools.org/show_bug.cgi?id=2561 (CVE-2016-5318) + http://bugzilla.maptools.org/show_bug.cgi?id=2499 (CVE-2014-8128) + http://bugzilla.maptools.org/show_bug.cgi?id=2441 + http://bugzilla.maptools.org/show_bug.cgi?id=2433 + +2017-05-29 Even Rouault + + * libtiff/tif_getimage.c: initYCbCrConversion(): stricter validation for + refBlackWhite coefficients values. To avoid invalid float->int32 conversion + (when refBlackWhite[0] == 2147483648.f) + Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=1907 + Credit to OSS Fuzz + +2017-05-29 Even Rouault + + * libtiff/tif_color.c: TIFFYCbCrToRGBInit(): stricter clamping to avoid + int32 overflow in TIFFYCbCrtoRGB(). + Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=1844 + Credit to OSS Fuzz + +2017-05-21 Bob Friesenhahn + + * configure.ac: libtiff 4.0.8 released. + + * html/v4.0.8.html: Add description of changes targeting the 4.0.8 + release. + +2017-05-20 Even Rouault + + * libtiff/tif_getimage.c: initYCbCrConversion(): stricter validation for + refBlackWhite coefficients values. To avoid invalid float->int32 conversion. + Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=1718 + Credit to OSS Fuzz + +2017-05-18 Even Rouault + + * libtiff/tif_getimage.c: initYCbCrConversion(): check luma[1] is not zero + to avoid division by zero. + Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=1665 + Credit to OSS Fuzz + +2017-05-17 Even Rouault + + * libtiff/tif_read.c: _TIFFVSetField(): fix outside range cast of double to + float. + Credit to Google Autofuzz project + +2017-05-17 Even Rouault + + * libtiff/tif_getimage.c: initYCbCrConversion(): add basic validation of + luma and refBlackWhite coefficients (just check they are not NaN for now), + to avoid potential float to int overflows. + Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=1663 + Credit to OSS Fuzz + +2017-05-17 Even Rouault + + * libtiff/tif_pixarlog.c: PixarLogDecode(): resync tif_rawcp with + next_in and tif_rawcc with avail_in at beginning and end of function, + similarly to what is done in LZWDecode(). Likely needed so that it + works properly with latest chnges in tif_read.c in CHUNKY_STRIP_READ_SUPPORT + mode. But untested... + +2017-05-17 Even Rouault + + * libtiff/tif_lzw.c: update dec_bitsleft at beginning of LZWDecode(), + and update tif_rawcc at end of LZWDecode(). This is needed to properly + work with the latest chnges in tif_read.c in CHUNKY_STRIP_READ_SUPPORT + mode. + +2017-05-14 Even Rouault + + * libtiff/tif_luv.c: LogL16InitState(): avoid excessive memory + allocation when RowsPerStrip tag is missing. + Credit to OSS-Fuzz (locally run, on GDAL) + +2017-05-14 Even Rouault + + * libtiff/tif_packbits.c: fix out-of-buffer read in PackBitsDecode() + Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=1563 + Credit to OSS-Fuzz + +2017-05-13 Even Rouault + + * libtiff/tif_pixarlog.c, tif_luv.c: avoid potential int32 + overflows in multiply_ms() and add_ms(). + Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=1558 + Credit to OSS-Fuzz + +2017-05-13 Even Rouault + + * libtiff/tif_color.c: avoid potential int32 overflow in + TIFFYCbCrToRGBInit() + Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=1533 + Credit to OSS-Fuzz + +2017-05-13 Even Rouault + + * libtiff/tif_read.c: update tif_rawcc in CHUNKY_STRIP_READ_SUPPORT + mode with tif_rawdataloaded when calling TIFFStartStrip() or + TIFFFillStripPartial(). This avoids reading beyond tif_rawdata + when bytecount > tif_rawdatasize. + Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=1545. + Credit to OSS-Fuzz + +2017-05-12 Even Rouault + + * libtiff/tif_read.c: TIFFFillStripPartial(): + avoid excessive memory allocation in case of shorten files. + Only effective on 64 bit builds. + Credit to OSS-Fuzz (locally run, on GDAL) + +2017-05-12 Even Rouault + + * libtiff/tif_read.c: TIFFFillStripPartial() / TIFFSeek(), + avoid potential integer overflows with read_ahead in + CHUNKY_STRIP_READ_SUPPORT mode. Should + especially occur on 32 bit platforms. + +2017-05-10 Even Rouault + + * libtiff/tif_read.c: TIFFFillStrip() and TIFFFillTile(): + avoid excessive memory allocation in case of shorten files. + Only effective on 64 bit builds and non-mapped cases. + Credit to OSS-Fuzz (locally run, on GDAL) + +2017-05-10 Even Rouault + + * libtiff/tif_zip.c, tif_pixarlog.c, tif_predict.c: fix memory + leak when the underlying codec (ZIP, PixarLog) succeeds its + setupdecode() method, but PredictorSetup fails. + Credit to OSS-Fuzz (locally run, on GDAL) + +2017-05-10 Even Rouault + + * libtiff/tif_read.c: TIFFFillStrip(): add limitation to the number + of bytes read in case td_stripbytecount[strip] is bigger than + reasonable, so as to avoid excessive memory allocation. + +2017-04-28 Even Rouault + + * tools/tiff2bw.c: close TIFF handle in error code path. + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2677 + +2017-04-27 Even Rouault + + * litiff/tif_fax3.c: avoid crash in Fax3Close() on empty file. + Patch by Alan Coopersmith + complement by myself. + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2673 + * tools/fax2tiff.c: emit appropriate message if the input file is + empty. Patch by Alan Coopersmith. + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2672 + +2017-04-27 Even Rouault + + * libtiff/tif_ojpeg.c: fix potential memory leak in + OJPEGReadHeaderInfoSecTablesQTable, OJPEGReadHeaderInfoSecTablesDcTable + and OJPEGReadHeaderInfoSecTablesAcTable + Patch by Nicolás Peña. + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2670 + +2017-04-27 Even Rouault + + * libtiff/tif_dirread.c: fix memory leak in non DEFER_STRILE_LOAD + mode (ie default) when there is both a StripOffsets and + TileOffsets tag, or a StripByteCounts and TileByteCounts + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2689 + * tools/tiff2ps.c: call TIFFClose() in error code paths. + +2017-02-25 Even Rouault + + * libtiff/tif_fax3.c, tif_predict.c, tif_getimage.c: fix GCC 7 + -Wimplicit-fallthrough warnings. + +2017-02-18 Even Rouault + + * libtiff/tif_pixarlog.c: fix memory leak in error code path of + PixarLogSetupDecode(). Patch by Nicolás Peña. + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2665 + +2017-02-18 Even Rouault + + * libtiff/tif_lzw.c: in LZWPostEncode(), increase, if necessary, the + code bit-width after flushing the remaining code and before emitting + the EOI code. + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=1982 + +2017-01-31 Even Rouault + + * libtiff/tif_jpeg.c: only run JPEGFixupTagsSubsampling() if the + YCbCrSubsampling tag is not explicitly present. This helps a bit to reduce + the I/O amount when te tag is present (especially on cloud hosted files). + +2017-01-14 Even Rouault + + * tools/raw2tiff.c: avoid integer division by zero. + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2631 + +2017-01-12 Even Rouault + + * libtiff/tif_ojpeg.c: fix leak in OJPEGReadHeaderInfoSecTablesQTable, + OJPEGReadHeaderInfoSecTablesDcTable and OJPEGReadHeaderInfoSecTablesAcTable + when read fails. + Patch by Nicolás Peña. + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2659 + +2017-01-11 Even Rouault + + * libtiff/tif_luv.c, tif_lzw.c, tif_packbits.c: return 0 in Encode + functions instead of -1 when TIFFFlushData1() fails. + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2130 + +2017-01-11 Even Rouault + + * tools/tiffcp.c: error out cleanly in cpContig2SeparateByRow and + cpSeparate2ContigByRow if BitsPerSample != 8 to avoid heap based overflow. + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2656 and + http://bugzilla.maptools.org/show_bug.cgi?id=2657 + +2017-01-11 Even Rouault + + * libtiff/tiffio.h, tif_unix.c, tif_win32.c, tif_vms.c: add _TIFFcalloc() + + * libtiff/tif_read.c: TIFFReadBufferSetup(): use _TIFFcalloc() to zero + initialize tif_rawdata. + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2651 + +2017-01-11 Even Rouault + + * libtiff/tif_getimage.c: add explicit uint32 cast in putagreytile to + avoid UndefinedBehaviorSanitizer warning. + Patch by Nicolás Peña. + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2658 + +2017-01-11 Even Rouault + + * libtiff/tif_read.c: avoid potential undefined behaviour on signed integer + addition in TIFFReadRawStrip1() in isMapped() case. + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2650 + +2017-01-11 Even Rouault + + * libtiff/tif_jpeg.c: validate BitsPerSample in JPEGSetupEncode() to avoid + undefined behaviour caused by invalid shift exponent. + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2648 + +2017-01-11 Even Rouault + + * libtiff/tif_dir.c, tif_dirread.c, tif_dirwrite.c: implement various clampings + of double to other data types to avoid undefined behaviour if the output range + isn't big enough to hold the input value. + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2643 + http://bugzilla.maptools.org/show_bug.cgi?id=2642 + http://bugzilla.maptools.org/show_bug.cgi?id=2646 + http://bugzilla.maptools.org/show_bug.cgi?id=2647 + +2017-01-11 Even Rouault + + * libtiff/tif_dirread.c: avoid division by floating point 0 in + TIFFReadDirEntryCheckedRational() and TIFFReadDirEntryCheckedSrational(), + and return 0 in that case (instead of infinity as before presumably) + Apparently some sanitizers do not like those divisions by zero. + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2644 + +2017-01-11 Even Rouault + + * libtiff/tif_dirwrite.c: in TIFFWriteDirectoryTagCheckedRational, replace + assertion by runtime check to error out if passed value is strictly + negative. + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2535 + + * tools/tiffcrop.c: remove extraneous TIFFClose() in error code path, that + caused double free. + Related to http://bugzilla.maptools.org/show_bug.cgi?id=2535 + +2017-01-11 Even Rouault + + * libtiff/tif_jpeg.c: avoid integer division by zero in + JPEGSetupEncode() when horizontal or vertical sampling is set to 0. + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2653 + +2017-01-03 Even Rouault + + * libtiff/tif_jpeg.c: increase libjpeg max memory usable to + 10 MB instead of libjpeg 1MB default. This helps when creating files + with "big" tile, without using libjpeg temporary files. + Related to https://trac.osgeo.org/gdal/ticket/6757 + +2016-12-20 Even Rouault + + * tools/tiff2pdf.c: avoid potential heap-based overflow in + t2p_readwrite_pdf_image_tile(). + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2640 + +2016-12-20 Even Rouault + + * tools/tiff2pdf.c: avoid potential invalid memory read in + t2p_writeproc. + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2639 + +2016-12-20 Even Rouault + + * tools/tiff2pdf.c: fix wrong usage of memcpy() that can trigger + unspecified behaviour. + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2638 + +2016-12-18 Even Rouault + + * libtiff/tif_getimage.c: fix potential memory leaks in error code + path of TIFFRGBAImageBegin(). + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2627 + +2016-12-18 Even Rouault + + * tools/tiff2pdf.c: prevent heap-based buffer overflow in -j mode + on a paletted image. Note: this fix errors out before the overflow + happens. There could probably be a better fix. + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2635 + +2016-12-17 Even Rouault + + * libtiff/tiffio.h, libtiff/tif_getimage.c: add TIFFReadRGBAStripExt() + and TIFFReadRGBATileExt() variants of the functions without ext, with + an extra argument to control the stop_on_error behaviour. + +2016-12-17 Even Rouault + + * tools/tiff2ps.c: fix 2 heap-based buffer overflows (in PSDataBW + and PSDataColorContig). Reported by Agostino Sarubbo. + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2633 and + http://bugzilla.maptools.org/show_bug.cgi?id=2634. + +2016-12-13 Even Rouault + + * libtiff/tif_fax3.h: revert change done on 2016-01-09 that made + Param member of TIFFFaxTabEnt structure a uint16 to reduce size of + the binary. It happens that the Hylafax software uses the tables that + follow this typedef (TIFFFaxMainTable, TIFFFaxWhiteTable, + TIFFFaxBlackTable), although they are not in a public libtiff header. + Raised by Lee Howard. + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2636 + +2016-12-04 Even Rouault + + * html/man/Makefile.am: remove thumbnail.1.html and rgb2ycbcr.1.html + from installed pages since the corresponding utilities are no longer + installed. Reported by Havard Eidnes + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2606 + +2016-12-03 Even Rouault + + * libtiff/tif_write.c: fix misleading indentation as warned by GCC. + +2016-12-03 Even Rouault + + * tools/tiffcp.c: replace assert( (bps % 8) == 0 ) by a non assert check. + Reported by Agostino Sarubbo. + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2605 + +2016-12-03 Even Rouault + + * tools/tiffcp.c: fix uint32 underflow/overflow that can cause heap-based + buffer overflow. + Reported by Agostino Sarubbo. + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2610 + +2016-12-03 Even Rouault + + * tools/tiffcp.c: avoid potential division by zero is BitsPerSamples tag is + missing. + Reported by Agostino Sarubbo. + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2607 + +2016-12-03 Even Rouault + + * man/Makefile.am: remove thumbnail.1 and rgb2ycbcr.1 from installed man + pages since the corresponding utilities are no longer installed. + Reported by Havard Eidnes + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2606 + +2016-12-03 Even Rouault + + * tools/tif_dir.c: when TIFFGetField(, TIFFTAG_NUMBEROFINKS, ) is called, + limit the return number of inks to SamplesPerPixel, so that code that parses + ink names doesn't go past the end of the buffer. + Reported by Agostino Sarubbo. + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2599 + +2016-12-03 Even Rouault + + * tools/tiffcp.c: avoid potential division by zero is BitsPerSamples tag is + missing. + Reported by Agostino Sarubbo. + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2597 + +2016-12-03 Even Rouault + + * tools/tiffinfo.c: fix null pointer dereference in -r mode when the image has + no StripByteCount tag. + Reported by Agostino Sarubbo. + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2594 + +2016-12-03 Even Rouault + + * tools/tiffcrop.c: fix integer division by zero when BitsPerSample is missing. + Reported by Agostino Sarubbo. + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2619 + +2016-12-03 Even Rouault + + * tools/tiffcrop.c: add 3 extra bytes at end of strip buffer in + readSeparateStripsIntoBuffer() to avoid read outside of heap allocated buffer. + Reported by Agostino Sarubbo. + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2621 + +2016-12-03 Even Rouault + + * tools/tiffcrop.c: fix readContigStripsIntoBuffer() in -i (ignore) mode so + that the output buffer is correctly incremented to avoid write outside bounds. + Reported by Agostino Sarubbo. + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2620 + +2016-12-03 Even Rouault + + * libtiff/tif_ojpeg.c: make OJPEGDecode() early exit in case of failure in + OJPEGPreDecode(). This will avoid a divide by zero, and potential other issues. + Reported by Agostino Sarubbo. + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2611 + +2016-12-03 Even Rouault + + * libtiff/tif_dirread.c: modify ChopUpSingleUncompressedStrip() to + instanciate compute ntrips as TIFFhowmany_32(td->td_imagelength, rowsperstrip), + instead of a logic based on the total size of data. Which is faulty is + the total size of data is not sufficient to fill the whole image, and thus + results in reading outside of the StripByCounts/StripOffsets arrays when + using TIFFReadScanline(). + Reported by Agostino Sarubbo. + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2608. + + * libtiff/tif_strip.c: revert the change in TIFFNumberOfStrips() done + for http://bugzilla.maptools.org/show_bug.cgi?id=2587 / CVE-2016-9273 since + the above change is a better fix that makes it unnecessary. + +2016-12-03 Even Rouault + + * libtiff/tif_pixarlog.c, libtiff/tif_luv.c: fix heap-based buffer + overflow on generation of PixarLog / LUV compressed files, with + ColorMap, TransferFunction attached and nasty plays with bitspersample. + The fix for LUV has not been tested, but suffers from the same kind + of issue of PixarLog. + Reported by Agostino Sarubbo. + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2604 + +2016-12-02 Even Rouault + + * tools/tiffcp.c: avoid uint32 underflow in cpDecodedStrips that + can cause various issues, such as buffer overflows in the library. + Reported by Agostino Sarubbo. + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2598 + +2016-12-02 Even Rouault + + * libtiff/tif_read.c, libtiff/tiffiop.h: fix uint32 overflow in + TIFFReadEncodedStrip() that caused an integer division by zero. + Reported by Agostino Sarubbo. + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2596 + +2016-11-20 Even Rouault + + * libtiff/tif_getimage.c, libtiff/tif_open.c: add parenthesis to + fix cppcheck clarifyCalculation warnings + * libtiff/tif_predict.c, libtiff/tif_print.c: fix printf unsigned + vs signed formatting (cppcheck invalidPrintfArgType_uint warnings) + +2016-11-20 Bob Friesenhahn + + * tools/fax2tiff.c (main): Applied patch by Jörg Ahrens to fix + passing client data for Win32 builds using tif_win32.c + (USE_WIN32_FILEIO defined) for file I/O. Patch was provided via + email on November 20, 2016. + 2016-11-19 Bob Friesenhahn * libtiff 4.0.7 released. @@ -85,7 +955,7 @@ writeBufferToSeparateStrips(), writeBufferToContigTiles() and writeBufferToSeparateTiles() that could cause heap buffer overflows. Reported by Henri Salo from Nixu Corporation. - Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2592 + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2592 (CVE-2016-9532) 2016-11-10 Even Rouault diff --git a/HOWTO-RELEASE b/HOWTO-RELEASE index 9293592..ae75011 100644 --- a/HOWTO-RELEASE +++ b/HOWTO-RELEASE @@ -28,7 +28,7 @@ Notes on releasing. Take ChangeLog entries and html-ify in there. Easist thing to do is take html/vX.(X-1).html and use it as a template. -3. Add vX.X.html file to the list of EXTRA_DIST files in the html/Makefile.am. +3. Add vX.X.html file to the list of 'docfiles' files in the html/Makefile.am. 4. Update html/index.html to refer to this new page as the current release. diff --git a/RELEASE-DATE b/RELEASE-DATE index fb9e3f6..f5a5ad7 100644 --- a/RELEASE-DATE +++ b/RELEASE-DATE @@ -1 +1 @@ -20161119 +20171118 diff --git a/VERSION b/VERSION index 43beb40..7919852 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -4.0.7 +4.0.9 diff --git a/config/ltmain.sh b/config/ltmain.sh old mode 100644 new mode 100755 index 0f0a2da..147d758 --- a/config/ltmain.sh +++ b/config/ltmain.sh @@ -31,7 +31,7 @@ PROGRAM=libtool PACKAGE=libtool -VERSION=2.4.6 +VERSION="2.4.6 Debian-2.4.6-0.1" package_revision=2.4.6 @@ -2073,7 +2073,7 @@ include the following information: autoconf: `($AUTOCONF --version) 2>/dev/null |$SED 1q` Report bugs to . -GNU libtool home page: . +GNU libtool home page: . General help using GNU software: ." exit 0 } @@ -7272,10 +7272,13 @@ func_mode_link () # -tp=* Portland pgcc target processor selection # --sysroot=* for sysroot support # -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization + # -specs=* GCC specs files # -stdlib=* select c++ std lib with clang + # -fsanitize=* Clang/GCC memory and address sanitizer -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ - -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*) + -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*| \ + -specs=*|-fsanitize=*) func_quote_for_eval "$arg" arg=$func_quote_for_eval_result func_append compile_command " $arg" @@ -7568,7 +7571,10 @@ func_mode_link () case $pass in dlopen) libs=$dlfiles ;; dlpreopen) libs=$dlprefiles ;; - link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; + link) + libs="$deplibs %DEPLIBS%" + test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs" + ;; esac fi if test lib,dlpreopen = "$linkmode,$pass"; then @@ -7887,19 +7893,19 @@ func_mode_link () # It is a libtool convenience library, so add in its objects. func_append convenience " $ladir/$objdir/$old_library" func_append old_convenience " $ladir/$objdir/$old_library" + tmp_libs= + for deplib in $dependency_libs; do + deplibs="$deplib $deplibs" + if $opt_preserve_dup_deps; then + case "$tmp_libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append tmp_libs " $deplib" + done elif test prog != "$linkmode" && test lib != "$linkmode"; then func_fatal_error "'$lib' is not a convenience library" fi - tmp_libs= - for deplib in $dependency_libs; do - deplibs="$deplib $deplibs" - if $opt_preserve_dup_deps; then - case "$tmp_libs " in - *" $deplib "*) func_append specialdeplibs " $deplib" ;; - esac - fi - func_append tmp_libs " $deplib" - done continue fi # $pass = conv @@ -8823,6 +8829,9 @@ func_mode_link () revision=$number_minor lt_irix_increment=no ;; + *) + func_fatal_configuration "$modename: unknown library version type '$version_type'" + ;; esac ;; no) diff --git a/configure b/configure index db23694..4bb7c05 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for LibTIFF Software 4.0.7. +# Generated by GNU Autoconf 2.69 for LibTIFF Software 4.0.9. # # Report bugs to . # @@ -590,8 +590,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='LibTIFF Software' PACKAGE_TARNAME='tiff' -PACKAGE_VERSION='4.0.7' -PACKAGE_STRING='LibTIFF Software 4.0.7' +PACKAGE_VERSION='4.0.9' +PACKAGE_STRING='LibTIFF Software 4.0.9' PACKAGE_BUGREPORT='tiff@lists.maptools.org' PACKAGE_URL='' @@ -1408,7 +1408,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures LibTIFF Software 4.0.7 to adapt to many kinds of systems. +\`configure' configures LibTIFF Software 4.0.9 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1482,7 +1482,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of LibTIFF Software 4.0.7:";; + short | recursive ) echo "Configuration of LibTIFF Software 4.0.9:";; esac cat <<\_ACEOF @@ -1668,7 +1668,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -LibTIFF Software configure 4.0.7 +LibTIFF Software configure 4.0.9 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2441,7 +2441,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by LibTIFF Software $as_me 4.0.7, which was +It was created by LibTIFF Software $as_me 4.0.9, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -3384,7 +3384,7 @@ fi # Define the identity of the package. PACKAGE='tiff' - VERSION='4.0.7' + VERSION='4.0.9' cat >>confdefs.h <<_ACEOF @@ -3588,14 +3588,14 @@ fi LIBTIFF_MAJOR_VERSION=4 LIBTIFF_MINOR_VERSION=0 -LIBTIFF_MICRO_VERSION=7 +LIBTIFF_MICRO_VERSION=9 LIBTIFF_ALPHA_VERSION= LIBTIFF_VERSION=$LIBTIFF_MAJOR_VERSION.$LIBTIFF_MINOR_VERSION.$LIBTIFF_MICRO_VERSION$LIBTIFF_ALPHA_VERSION LIBTIFF_RELEASE_DATE=`date +"%Y%m%d"` -LIBTIFF_CURRENT=7 -LIBTIFF_REVISION=5 -LIBTIFF_AGE=2 +LIBTIFF_CURRENT=8 +LIBTIFF_REVISION=0 +LIBTIFF_AGE=3 LIBTIFF_VERSION_INFO=$LIBTIFF_CURRENT:$LIBTIFF_REVISION:$LIBTIFF_AGE # This is a special hack for OpenBSD and MirOS systems. The dynamic linker @@ -6104,7 +6104,7 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) lt_cv_deplibs_check_method=pass_all ;; -netbsd*) +netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' else @@ -10091,6 +10091,9 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie openbsd* | bitrig*) with_gnu_ld=no ;; + linux* | k*bsd*-gnu | gnu*) + link_all_deplibs=no + ;; esac ld_shlibs=yes @@ -10345,7 +10348,7 @@ _LT_EOF fi ;; - netbsd*) + netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= @@ -11015,6 +11018,7 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; } if test yes = "$lt_cv_irix_exported_symbol"; then archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' fi + link_all_deplibs=no else archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' @@ -11036,7 +11040,7 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; } esac ;; - netbsd*) + netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else @@ -12151,6 +12155,18 @@ fi dynamic_linker='GNU/Linux ld.so' ;; +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + netbsd*) version_type=sunos need_lib_prefix=no @@ -15463,7 +15479,7 @@ lt_prog_compiler_static_CXX= ;; esac ;; - netbsd*) + netbsd* | netbsdelf*-gnu) ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise @@ -15838,6 +15854,9 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie ;; esac ;; + linux* | k*bsd*-gnu | gnu*) + link_all_deplibs_CXX=no + ;; *) export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; @@ -16531,6 +16550,18 @@ fi dynamic_linker='GNU/Linux ld.so' ;; +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + netbsd*) version_type=sunos need_lib_prefix=no @@ -21500,7 +21531,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by LibTIFF Software $as_me 4.0.7, which was +This file was extended by LibTIFF Software $as_me 4.0.9, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -21566,7 +21597,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -LibTIFF Software config.status 4.0.7 +LibTIFF Software config.status 4.0.9 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index 23d543c..0dd32b7 100644 --- a/configure.ac +++ b/configure.ac @@ -25,7 +25,7 @@ dnl OF THIS SOFTWARE. dnl Process this file with autoconf to produce a configure script. AC_PREREQ(2.64) -AC_INIT([LibTIFF Software],[4.0.7],[tiff@lists.maptools.org],[tiff]) +AC_INIT([LibTIFF Software],[4.0.9],[tiff@lists.maptools.org],[tiff]) AC_CONFIG_AUX_DIR(config) AC_CONFIG_MACRO_DIR(m4) AC_LANG(C) @@ -41,7 +41,7 @@ dnl Versioning. dnl Don't fill the ALPHA_VERSION field, if not applicable. LIBTIFF_MAJOR_VERSION=4 LIBTIFF_MINOR_VERSION=0 -LIBTIFF_MICRO_VERSION=7 +LIBTIFF_MICRO_VERSION=9 LIBTIFF_ALPHA_VERSION= LIBTIFF_VERSION=$LIBTIFF_MAJOR_VERSION.$LIBTIFF_MINOR_VERSION.$LIBTIFF_MICRO_VERSION$LIBTIFF_ALPHA_VERSION dnl This will be used with the 'make release' target @@ -76,9 +76,9 @@ dnl 5. If any interfaces have been added since the last public release, then dnl increment age. dnl 6. If any interfaces have been removed since the last public release, dnl then set age to 0. -LIBTIFF_CURRENT=7 -LIBTIFF_REVISION=5 -LIBTIFF_AGE=2 +LIBTIFF_CURRENT=8 +LIBTIFF_REVISION=0 +LIBTIFF_AGE=3 LIBTIFF_VERSION_INFO=$LIBTIFF_CURRENT:$LIBTIFF_REVISION:$LIBTIFF_AGE # This is a special hack for OpenBSD and MirOS systems. The dynamic linker diff --git a/html/Makefile.am b/html/Makefile.am index 01549ba..12193df 100644 --- a/html/Makefile.am +++ b/html/Makefile.am @@ -84,7 +84,9 @@ docfiles = \ v4.0.4.html \ v4.0.5.html \ v4.0.6.html \ - v4.0.7.html + v4.0.7.html \ + v4.0.8.html \ + v4.0.9.html dist_doc_DATA = $(docfiles) diff --git a/html/Makefile.in b/html/Makefile.in index 3cb22e6..4c0c8e3 100644 --- a/html/Makefile.in +++ b/html/Makefile.in @@ -447,7 +447,9 @@ docfiles = \ v4.0.4.html \ v4.0.5.html \ v4.0.6.html \ - v4.0.7.html + v4.0.7.html \ + v4.0.8.html \ + v4.0.9.html dist_doc_DATA = $(docfiles) SUBDIRS = images man diff --git a/html/index.html b/html/index.html index 71af0af..1c5a3ec 100644 --- a/html/index.html +++ b/html/index.html @@ -24,7 +24,7 @@ Latest Stable Release - v4.0.7 + v4.0.9 Master Download Site @@ -81,12 +81,14 @@ http://lists.maptools.org/mailman/listinfo/tiff.

- The persons responsible for putting up this site and putting together - versions >= 3.5.1 are + The persons currently actively maintaining and releasing libtiff + are Even Rouault + and Bob Friesenhahn. +

+

Significant maintainers in the past (since the 3.5.1 release) are Frank Warmerdam, Andrey Kiselev, - Bob Friesenhahn, - Joris Van Damme, Lee Howard and Even Rouault. + Joris Van Damme, and Lee Howard.

The following sections are included in this documentation: @@ -114,7 +116,7 @@


- Last updated $Date: 2016-09-25 20:05:44 $. + Last updated $Date: 2017-11-07 02:00:06 $.

diff --git a/html/man/CMakeLists.txt b/html/man/CMakeLists.txt index cb92ea2..897a0e7 100644 --- a/html/man/CMakeLists.txt +++ b/html/man/CMakeLists.txt @@ -74,8 +74,6 @@ set(docfiles pal2rgb.1.html ppm2tiff.1.html raw2tiff.1.html - rgb2ycbcr.1.html - thumbnail.1.html tiff2bw.1.html tiff2pdf.1.html tiff2ps.1.html diff --git a/html/man/Makefile.am b/html/man/Makefile.am index 587296c..3ed00d4 100644 --- a/html/man/Makefile.am +++ b/html/man/Makefile.am @@ -81,8 +81,6 @@ docfiles = \ pal2rgb.1.html \ ppm2tiff.1.html \ raw2tiff.1.html \ - rgb2ycbcr.1.html \ - thumbnail.1.html \ tiff2bw.1.html \ tiff2pdf.1.html \ tiff2ps.1.html \ diff --git a/html/man/Makefile.in b/html/man/Makefile.in index 7f4648c..eb99fd1 100644 --- a/html/man/Makefile.in +++ b/html/man/Makefile.in @@ -383,8 +383,6 @@ docfiles = \ pal2rgb.1.html \ ppm2tiff.1.html \ raw2tiff.1.html \ - rgb2ycbcr.1.html \ - thumbnail.1.html \ tiff2bw.1.html \ tiff2pdf.1.html \ tiff2ps.1.html \ diff --git a/html/man/rgb2ycbcr.1.html b/html/man/rgb2ycbcr.1.html deleted file mode 100644 index 6e481f7..0000000 --- a/html/man/rgb2ycbcr.1.html +++ /dev/null @@ -1,155 +0,0 @@ - - - - - - -RGB2YCBCR - - - -

RGB2YCBCR

-NAME
-SYNOPSIS
-DESCRIPTION
-OPTIONS
-SEE ALSO
- -
- -

NAME

- - - - - -
-

rgb2ycbcr − convert non-YCbCr TIFF -images to a YCbCr TIFF image

-
- -

SYNOPSIS

- - - - - -
-

rgb2ycbcr [ options ] src1.tif src2.tif -... dst.tif

-
- -

DESCRIPTION

- - - - - -
-

rgb2ycbcr converts RGB color, -greyscale, or bi-level TIFF images to YCbCr -images by transforming and sampling pixel data. If multiple -files are specified on the command line each source file is -converted to a separate directory in the destination -file.

- -

By default, chrominance samples are created by sampling 2 -by 2 blocks of luminance values; this can be changed with -the −h and −v options. Output data -are compressed with the PackBits compression -scheme, by default; an alternate scheme can be selected with -the −c option. By default, output data are -compressed in strips with the number of rows in each strip -selected so that the size of a strip is never more than 8 -kilobytes; the −r option can be used to -explicitly set the number of rows per strip.

-
- -

OPTIONS

- - - - - - - - - - - - - - - - - - - - - - - - - - -
- -

−c

-
- -

Specify a compression scheme to use when writing image -data: −c none for no compression, −c -packbits for the PackBits compression algorithm (the -default), −c jpeg for the JPEG compression -algorithm, −c zip for the deflate compression -algorithm, and −c lzw for Lempel-Ziv & -Welch.

-
-
- -

−h

-
- -

Set the horizontal sampling dimension to one of: 1, 2 -(default), or 4.

-
-
- -

−r

-
- -

Write data with a specified number of rows per strip; by -default the number of rows/strip is selected so that each -strip is approximately 8 kilobytes.

-
-
- -

−v

-
- -

Set the vertical sampling dimension to one of: 1, 2 -(default), or 4.

-
-
- -

SEE ALSO

- - - - - -
-

tiffinfo(1), tiffcp(1), -libtiff(3)

- -

Libtiff library home page: -http://www.simplesystems.org/libtiff/

-
-
- - diff --git a/html/man/thumbnail.1.html b/html/man/thumbnail.1.html deleted file mode 100644 index 8b11413..0000000 --- a/html/man/thumbnail.1.html +++ /dev/null @@ -1,148 +0,0 @@ - - - - - - -THUMBNAIL - - - -

THUMBNAIL

-NAME
-SYNOPSIS
-DESCRIPTION
-OPTIONS
-BUGS
-SEE ALSO
- -
- -

NAME

- - - - - -
-

thumbnail − create a TIFF file with -thumbnail images

-
- -

SYNOPSIS

- - - - - -
-

thumbnail [ options ] input.tif -output.tif

-
- -

DESCRIPTION

- - - - - -
-

thumbnail is a program written to show how one -might use the SubIFD tag (#330) to store thumbnail images. -thumbnail copies a TIFF Class F -facsimile file to the output file and for each image an -8-bit greyscale thumbnail sketch. The output file -contains the thumbnail image with the associated -full-resolution page linked below with the SubIFD tag.

- -

By default, thumbnail images are 216 pixels wide by 274 -pixels high. Pixels are calculated by sampling and filtering -the input image with each pixel value passed through a -contrast curve.

-
- -

OPTIONS

- - - - - - - - - - - - - - - - - - - - -
- -

−w

-
- -

Specify the width of thumbnail images in pixels.

-
-
- -

−h

-
- -

Specify the height of thumbnail images in pixels.

-
-
- -

−c

-
- -

Specify a contrast curve to apply in generating the -thumbnail images. By default pixels values are passed -through a linear contrast curve that simply maps the pixel -value ranges. Alternative curves are: exp50 for a 50% -exponential curve, exp60 for a 60% exponential curve, -exp70 for a 70% exponential curve, exp80 for a -80% exponential curve, exp90 for a 90% exponential -curve, exp for a pure exponential curve, -linear for a linear curve.

-
-
- -

BUGS

- - - - - -
-

There are no options to control the format of the saved -thumbnail images.

-
- -

SEE ALSO

- - - - - -
-

tiffdump(1), tiffgt(1), tiffinfo(1), -libtiff(3)

- -

Libtiff library home page: -http://www.simplesystems.org/libtiff/

-
-
- - diff --git a/html/v4.0.7.html b/html/v4.0.7.html index 151861f..e29e8d5 100644 --- a/html/v4.0.7.html +++ b/html/v4.0.7.html @@ -405,7 +405,7 @@ information is located here: -Last updated $Date: 2016-11-12 21:43:44 $. +Last updated $Date: 2016-11-19 17:47:40 $. diff --git a/html/v4.0.8.html b/html/v4.0.8.html new file mode 100644 index 0000000..8b85e9c --- /dev/null +++ b/html/v4.0.8.html @@ -0,0 +1,445 @@ + + + + Changes in TIFF v4.0.8 + + + + + + + +TIFF CHANGE INFORMATION + + + + +

+This document describes the changes made to the software between the +previous and current versions (see above). If you don't +find something listed here, then it was not done in this timeframe, or +it was not considered important enough to be mentioned. The following +information is located here: +

+

+


+ + + +MAJOR CHANGES: + +
    + +
  • None + +
+ + +


+ + +CHANGES IN THE SOFTWARE CONFIGURATION: + +
    + +
  • None + +
+ +


+ + + +CHANGES IN LIBTIFF: + +
    + +
  • libtiff/tif_getimage.c, libtiff/tif_open.c: add parenthesis + to fix cppcheck clarifyCalculation warnings * + libtiff/tif_predict.c, libtiff/tif_print.c: fix printf + unsigned vs signed formatting (cppcheck + invalidPrintfArgType_uint warnings) + +
  • libtiff/tif_read.c, libtiff/tiffiop.h: fix uint32 overflow in + TIFFReadEncodedStrip() that caused an integer division by + zero. Reported by Agostino Sarubbo. Fixes + http://bugzilla.maptools.org/show_bug.cgi?id=2596 + +
  • libtiff/tif_pixarlog.c, libtiff/tif_luv.c: fix heap-based + buffer overflow on generation of PixarLog / LUV compressed + files, with ColorMap, TransferFunction attached and nasty + plays with bitspersample. The fix for LUV has not been + tested, but suffers from the same kind of issue of PixarLog. + Reported by Agostino Sarubbo. Fixes + http://bugzilla.maptools.org/show_bug.cgi?id=2604 + +
  • libtiff/tif_strip.c: revert the change in + TIFFNumberOfStrips() done for + http://bugzilla.maptools.org/show_bug.cgi?id=2587 / + CVE-2016-9273 since the above change is a better fix that + makes it unnecessary. + +
  • libtiff/tif_dirread.c: modify ChopUpSingleUncompressedStrip() + to instanciate compute ntrips as + TIFFhowmany_32(td->td_imagelength, rowsperstrip), instead of a + logic based on the total size of data. Which is faulty is the + total size of data is not sufficient to fill the whole image, + and thus results in reading outside of the + StripByCounts/StripOffsets arrays when using + TIFFReadScanline(). Reported by Agostino Sarubbo. Fixes + http://bugzilla.maptools.org/show_bug.cgi?id=2608. + +
  • libtiff/tif_ojpeg.c: make OJPEGDecode() early exit in case of + failure in OJPEGPreDecode(). This will avoid a divide by zero, + and potential other issues. Reported by Agostino Sarubbo. + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2611 + +
  • libtiff/tif_write.c: fix misleading indentation as warned by GCC. + + +
  • libtiff/tif_fax3.h: revert change done on 2016-01-09 that + made Param member of TIFFFaxTabEnt structure a uint16 to + reduce size of the binary. It happens that the Hylafax + software uses the tables that follow this typedef + (TIFFFaxMainTable, TIFFFaxWhiteTable, TIFFFaxBlackTable), + although they are not in a public libtiff header. Raised by + Lee Howard. Fixes + http://bugzilla.maptools.org/show_bug.cgi?id=2636 + +
  • libtiff/tiffio.h, libtiff/tif_getimage.c: add + TIFFReadRGBAStripExt() and TIFFReadRGBATileExt() variants of + the functions without ext, with an extra argument to control + the stop_on_error behaviour. + +
  • libtiff/tif_getimage.c: fix potential memory leaks in error + code path of TIFFRGBAImageBegin(). Fixes + http://bugzilla.maptools.org/show_bug.cgi?id=2627 + +
  • libtiff/tif_jpeg.c: increase libjpeg max memory usable to 10 + MB instead of libjpeg 1MB default. This helps when creating + files with "big" tile, without using libjpeg temporary files. + Related to https://trac.osgeo.org/gdal/ticket/6757 + +
  • libtiff/tif_jpeg.c: avoid integer division by zero in + JPEGSetupEncode() when horizontal or vertical sampling is set + to 0. Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2653 + +
  • libtiff/tif_dirwrite.c: in + TIFFWriteDirectoryTagCheckedRational, replace assertion by + runtime check to error out if passed value is strictly + negative. Fixes + http://bugzilla.maptools.org/show_bug.cgi?id=2535 + +
  • libtiff/tif_dirread.c: avoid division by floating point 0 in + TIFFReadDirEntryCheckedRational() and + TIFFReadDirEntryCheckedSrational(), and return 0 in that case + (instead of infinity as before presumably) Apparently some + sanitizers do not like those divisions by zero. Fixes + http://bugzilla.maptools.org/show_bug.cgi?id=2644 + +
  • libtiff/tif_dir.c, tif_dirread.c, tif_dirwrite.c: implement + various clampings of double to other data types to avoid + undefined behaviour if the output range isn't big enough to + hold the input value. Fixes + http://bugzilla.maptools.org/show_bug.cgi?id=2643 + http://bugzilla.maptools.org/show_bug.cgi?id=2642 + http://bugzilla.maptools.org/show_bug.cgi?id=2646 + http://bugzilla.maptools.org/show_bug.cgi?id=2647 + +
  • libtiff/tif_jpeg.c: validate BitsPerSample in + JPEGSetupEncode() to avoid undefined behaviour caused by + invalid shift exponent. Fixes + http://bugzilla.maptools.org/show_bug.cgi?id=2648 + +
  • libtiff/tif_read.c: avoid potential undefined behaviour on + signed integer addition in TIFFReadRawStrip1() in isMapped() + case. Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2650 + +
  • libtiff/tif_getimage.c: add explicit uint32 cast in + putagreytile to avoid UndefinedBehaviorSanitizer warning. + Patch by Nicolás Peña. Fixes + http://bugzilla.maptools.org/show_bug.cgi?id=2658 + +
  • libtiff/tif_read.c: TIFFReadBufferSetup(): use _TIFFcalloc() + to zero initialize tif_rawdata. Fixes + http://bugzilla.maptools.org/show_bug.cgi?id=2651 + +
  • libtiff/tiffio.h, tif_unix.c, tif_win32.c, tif_vms.c: add + _TIFFcalloc() + +
  • libtiff/tif_luv.c, tif_lzw.c, tif_packbits.c: return 0 in + Encode functions instead of -1 when TIFFFlushData1() fails. + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2130 + +
  • libtiff/tif_ojpeg.c: fix leak in + OJPEGReadHeaderInfoSecTablesQTable, + OJPEGReadHeaderInfoSecTablesDcTable and + OJPEGReadHeaderInfoSecTablesAcTable when read fails. Patch by + Nicolás Peña. Fixes + http://bugzilla.maptools.org/show_bug.cgi?id=2659 + +
  • libtiff/tif_jpeg.c: only run JPEGFixupTagsSubsampling() if + the YCbCrSubsampling tag is not explicitly present. This helps + a bit to reduce the I/O amount when the tag is present + (especially on cloud hosted files). + +
  • libtiff/tif_lzw.c: in LZWPostEncode(), increase, if + necessary, the code bit-width after flushing the remaining + code and before emitting the EOI code. Fixes + http://bugzilla.maptools.org/show_bug.cgi?id=1982 + +
  • libtiff/tif_pixarlog.c: fix memory leak in error code path of + PixarLogSetupDecode(). Patch by Nicolás Peña. Fixes + http://bugzilla.maptools.org/show_bug.cgi?id=2665 + +
  • libtiff/tif_fax3.c, tif_predict.c, tif_getimage.c: fix GCC 7 + -Wimplicit-fallthrough warnings. + +
  • libtiff/tif_dirread.c: fix memory leak in non + DEFER_STRILE_LOAD mode (ie default) when there is both a + StripOffsets and TileOffsets tag, or a StripByteCounts and + TileByteCounts Fixes + http://bugzilla.maptools.org/show_bug.cgi?id=2689 + +
  • libtiff/tif_ojpeg.c: fix potential memory leak in + OJPEGReadHeaderInfoSecTablesQTable, + OJPEGReadHeaderInfoSecTablesDcTable and + OJPEGReadHeaderInfoSecTablesAcTable Patch by Nicolás Peña. + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2670 + +
  • libtiff/tif_fax3.c: avoid crash in Fax3Close() on empty file. + Patch by Alan Coopersmith + complement by myself. Fixes + http://bugzilla.maptools.org/show_bug.cgi?id=2673 + +
  • libtiff/tif_read.c: TIFFFillStrip(): add limitation to the + number of bytes read in case td_stripbytecount[strip] is + bigger than reasonable, so as to avoid excessive memory + allocation. + +
  • libtiff/tif_zip.c, tif_pixarlog.c, tif_predict.c: fix memory + leak when the underlying codec (ZIP, PixarLog) succeeds its + setupdecode() method, but PredictorSetup fails. Credit to + OSS-Fuzz (locally run, on GDAL) + +
  • libtiff/tif_read.c: TIFFFillStrip() and TIFFFillTile(): avoid + excessive memory allocation in case of shorten files. Only + effective on 64 bit builds and non-mapped cases. Credit to + OSS-Fuzz (locally run, on GDAL) + +
  • libtiff/tif_read.c: TIFFFillStripPartial() / TIFFSeek(), + avoid potential integer overflows with read_ahead in + CHUNKY_STRIP_READ_SUPPORT mode. Should + especially occur on 32 bit platforms. + +
  • libtiff/tif_read.c: TIFFFillStripPartial(): avoid excessive + memory allocation in case of shorten files. Only effective on + 64 bit builds. Credit to OSS-Fuzz (locally run, on GDAL) + +
  • libtiff/tif_read.c: update tif_rawcc in + CHUNKY_STRIP_READ_SUPPORT mode with tif_rawdataloaded when + calling TIFFStartStrip() or TIFFFillStripPartial(). This + avoids reading beyond tif_rawdata when bytecount > + tif_rawdatasize. Fixes + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=1545. + Credit to OSS-Fuzz + +
  • libtiff/tif_color.c: avoid potential int32 overflow in + TIFFYCbCrToRGBInit() Fixes + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=1533 + Credit to OSS-Fuzz + +
  • libtiff/tif_pixarlog.c, tif_luv.c: avoid potential int32 + overflows in multiply_ms() and add_ms(). Fixes + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=1558 + Credit to OSS-Fuzz + +
  • libtiff/tif_packbits.c: fix out-of-buffer read in + PackBitsDecode() Fixes + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=1563 + Credit to OSS-Fuzz + +
  • libtiff/tif_luv.c: LogL16InitState(): avoid excessive memory + allocation when RowsPerStrip tag is missing. + Credit to OSS-Fuzz (locally run, on GDAL) + +
  • libtiff/tif_lzw.c: update dec_bitsleft at beginning of + LZWDecode(), and update tif_rawcc at end of LZWDecode(). This + is needed to properly work with the latest chnges in + tif_read.c in CHUNKY_STRIP_READ_SUPPORT mode. + +
  • libtiff/tif_pixarlog.c: PixarLogDecode(): resync tif_rawcp + with next_in and tif_rawcc with avail_in at beginning and end + of function, similarly to what is done in LZWDecode(). Likely + needed so that it works properly with latest chnges in + tif_read.c in CHUNKY_STRIP_READ_SUPPORT mode. But untested... + +
  • libtiff/tif_getimage.c: initYCbCrConversion(): add basic + validation of luma and refBlackWhite coefficients (just check + they are not NaN for now), to avoid potential float to int + overflows. Fixes + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=1663 + Credit to OSS Fuzz + +
  • libtiff/tif_read.c: _TIFFVSetField(): fix outside range cast + of double to float. Credit to Google Autofuzz project + +
  • libtiff/tif_getimage.c: initYCbCrConversion(): check luma[1] + is not zero to avoid division by zero. Fixes + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=1665 + Credit to OSS Fuzz + +
  • libtiff/tif_read.c: _TIFFVSetField(): fix outside range cast + of double to float. Credit to Google Autofuzz project + +
  • libtiff/tif_getimage.c: initYCbCrConversion(): check luma[1] + is not zero to avoid division by zero. Fixes + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=1665 + Credit to OSS Fuzz + +
  • libtiff/tif_getimage.c: initYCbCrConversion(): stricter + validation for refBlackWhite coefficients values. To avoid + invalid float->int32 conversion. Fixes + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=1718 + Credit to OSS Fuzz + +
+ +


+ + + +CHANGES IN THE TOOLS: + +
    + +
  • tools/fax2tiff.c (main): Applied patch by Jörg Ahrens to fix + passing client data for Win32 builds using tif_win32.c + (USE_WIN32_FILEIO defined) for file I/O. Patch was provided + via email on November 20, 2016. + +
  • tools/tiffcp.c: avoid uint32 underflow in cpDecodedStrips + that can cause various issues, such as buffer overflows in the + library. Reported by Agostino Sarubbo. Fixes + http://bugzilla.maptools.org/show_bug.cgi?id=2598 + +
  • tools/tiffcrop.c: fix readContigStripsIntoBuffer() in -i + (ignore) mode so that the output buffer is correctly + incremented to avoid write outside bounds. Reported by + Agostino Sarubbo. Fixes + http://bugzilla.maptools.org/show_bug.cgi?id=2620 + +
  • tools/tiffcrop.c: add 3 extra bytes at end of strip buffer in + readSeparateStripsIntoBuffer() to avoid read outside of heap + allocated buffer. Reported by Agostino Sarubbo. Fixes + http://bugzilla.maptools.org/show_bug.cgi?id=2621 + +
  • tools/tiffcrop.c: fix integer division by zero when + BitsPerSample is missing. Reported by Agostino Sarubbo. + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2619 + +
  • tools/tiffinfo.c: fix null pointer dereference in -r mode + when the image has no StripByteCount tag. Reported by + Agostino Sarubbo. Fixes + http://bugzilla.maptools.org/show_bug.cgi?id=2594 + +
  • tools/tiffcp.c: avoid potential division by zero is + BitsPerSamples tag is missing. Reported by Agostino Sarubbo. + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2597 + +
  • tools/tif_dir.c: when TIFFGetField(, TIFFTAG_NUMBEROFINKS, ) + is called, limit the return number of inks to SamplesPerPixel, + so that code that parses ink names doesn't go past the end of + the buffer. Reported by Agostino Sarubbo. Fixes + http://bugzilla.maptools.org/show_bug.cgi?id=2599 + +
  • tools/tiffcp.c: avoid potential division by zero is + BitsPerSamples tag is missing. Reported by Agostino Sarubbo. + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2607 + +
  • tools/tiffcp.c: fix uint32 underflow/overflow that can cause + heap-based buffer overflow. Reported by Agostino Sarubbo. + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2610 + +
  • tools/tiffcp.c: replace assert( (bps % 8) == 0 ) by a non + assert check. Reported by Agostino Sarubbo. Fixes + http://bugzilla.maptools.org/show_bug.cgi?id=2605 + +
  • tools/tiff2ps.c: fix 2 heap-based buffer overflows (in + PSDataBW and PSDataColorContig). Reported by Agostino Sarubbo. + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2633 and + http://bugzilla.maptools.org/show_bug.cgi?id=2634. + +
  • tools/tiff2pdf.c: prevent heap-based buffer overflow in -j + mode on a paletted image. Note: this fix errors out before the + overflow happens. There could probably be a better fix. Fixes + http://bugzilla.maptools.org/show_bug.cgi?id=2635 + +
  • tools/tiff2pdf.c: fix wrong usage of memcpy() that can + trigger unspecified behaviour. Fixes + http://bugzilla.maptools.org/show_bug.cgi?id=2638 + +
  • tools/tiff2pdf.c: avoid potential invalid memory read in + t2p_writeproc. Fixes + http://bugzilla.maptools.org/show_bug.cgi?id=2639 + +
  • tools/tiff2pdf.c: avoid potential heap-based overflow in + t2p_readwrite_pdf_image_tile(). Fixes + http://bugzilla.maptools.org/show_bug.cgi?id=2640 + +
  • tools/tiffcrop.c: remove extraneous TIFFClose() in error code + path, that caused double free. Related to + http://bugzilla.maptools.org/show_bug.cgi?id=2535 + +
  • tools/tiffcp.c: error out cleanly in cpContig2SeparateByRow + and cpSeparate2ContigByRow if BitsPerSample != 8 to avoid heap + based overflow. Fixes + http://bugzilla.maptools.org/show_bug.cgi?id=2656 and + http://bugzilla.maptools.org/show_bug.cgi?id=2657 + +
  • tools/raw2tiff.c: avoid integer division by zero. Fixes + http://bugzilla.maptools.org/show_bug.cgi?id=2631 + +
  • tools/tiff2ps.c: call TIFFClose() in error code paths. + +
  • tools/fax2tiff.c: emit appropriate message if the input file + is empty. Patch by Alan Coopersmith. Fixes + http://bugzilla.maptools.org/show_bug.cgi?id=2672 + +
  • tools/tiff2bw.c: close TIFF handle in error code path. Fixes + http://bugzilla.maptools.org/show_bug.cgi?id=2677 + +
+ +


+ + + +CHANGES IN THE CONTRIB AREA: + +
    + +
  • None + +
+ +Last updated $Date: 2017-05-21 17:47:46 $. + + + diff --git a/html/v4.0.9.html b/html/v4.0.9.html new file mode 100644 index 0000000..9be5f27 --- /dev/null +++ b/html/v4.0.9.html @@ -0,0 +1,373 @@ + + + + Changes in TIFF v4.0.9 + + + + + + + +TIFF CHANGE INFORMATION + + + + +

+This document describes the changes made to the software between the +previous and current versions (see above). If you don't +find something listed here, then it was not done in this timeframe, or +it was not considered important enough to be mentioned. The following +information is located here: +

+

+


+ + + +MAJOR CHANGES: + +
    + +
  • None + +
+ + +


+ + +CHANGES IN THE SOFTWARE CONFIGURATION: + +
    + +
  • test/Makefile.am: Add some tests for tiff2bw. +
  • * .appveyor.yml, .travis.yml, build/travis-ci: apply patches + 0001-ci-Travis-script-improvements.patch and + 0002-ci-Invoke-helper-script-via-shell.patch by Roger Leigh + (sent to mailing list) +
  • .travis.yml, build/travis-ci: new files from + 0001-ci-Add-Travis-support-for-Linux-builds-with-Autoconf.patch by + Roger Leigh (sent to mailing list on 2017-06-08) + This patch adds support for the Travis-CI service. +
  • .appveyor.yml: new file from + 0002-ci-Add-AppVeyor-support.patch by Roger Leigh (sent to mailing + list on 2017-06-08) + This patch adds a .appveyor.yml file to the top-level. This allows + one to opt in to having a branch built on Windows with Cygwin, + MinGW and MSVC automatically when a branch is pushed to GitHub, + GitLab, BitBucket or any other supported git hosting service. +
  • CMakeLists.txt, test/CMakeLists.txt, test/TiffTestCommon.cmake: apply + patch 0001-cmake-Improve-Cygwin-and-MingGW-test-support.patch from Roger + Leigh (sent to mailing list on 2017-06-08) + This patch makes the CMake build system support running the tests + with MinGW or Cygwin. + +
  • test/tiffcp-lzw-compat.sh, test/images/quad-lzw-compat.tiff: new files + to test old-style LZW decompression +
  • test/common.sh, Makefile.am, CMakeList.txt: updated with above +
  • test/Makefile.am: add missing reference to images/quad-lzw-compat.tiff + to fix "make distcheck". Patch by Roger Leigh +
  • nmake.opt: support a DEBUG=1 option, so as to adjust OPTFLAGS and use + /MDd runtime in debug mode. + + +
+ +


+ + + +CHANGES IN LIBTIFF: + +
    + +
  • libtiff/tif_color.c: TIFFYCbCrToRGBInit(): stricter clamping to avoid + int32 overflow in TIFFYCbCrtoRGB(). + Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=1844 + Credit to OSS Fuzz + +
  • libtiff/tif_getimage.c: initYCbCrConversion(): stricter validation for + refBlackWhite coefficients values. To avoid invalid float->int32 conversion + (when refBlackWhite[0] == 2147483648.f) + Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=1907 + Credit to OSS Fuzz + +
  • libtiff/tif_dirinfo.c, tif_dirread.c: add _TIFFCheckFieldIsValidForCodec(), + and use it in TIFFReadDirectory() so as to ignore fields whose tag is a + codec-specified tag but this codec is not enabled. This avoids TIFFGetField() + to behave differently depending on whether the codec is enabled or not, and + thus can avoid stack based buffer overflows in a number of TIFF utilities + such as tiffsplit, tiffcmp, thumbnail, etc. + Patch derived from 0063-Handle-properly-CODEC-specific-tags.patch + (http://bugzilla.maptools.org/show_bug.cgi?id=2580) by Raphaël Hertzog. + Fixes: + http://bugzilla.maptools.org/show_bug.cgi?id=2580 + http://bugzilla.maptools.org/show_bug.cgi?id=2693 + http://bugzilla.maptools.org/show_bug.cgi?id=2625 (CVE-2016-10095) + http://bugzilla.maptools.org/show_bug.cgi?id=2564 (CVE-2015-7554) + http://bugzilla.maptools.org/show_bug.cgi?id=2561 (CVE-2016-5318) + http://bugzilla.maptools.org/show_bug.cgi?id=2499 (CVE-2014-8128) + http://bugzilla.maptools.org/show_bug.cgi?id=2441 + http://bugzilla.maptools.org/show_bug.cgi?id=2433 + +
  • libtiff/tif_swab.c: if DISABLE_CHECK_TIFFSWABMACROS is defined, do not do + the #ifdef TIFFSwabXXX checks. Make it easier for GDAL to rename the symbols + of its internal libtiff copy. + + +
  • libtiff/tif_dirread.c: fix regression of libtiff 4.0.8 in + ChopUpSingleUncompressedStrip() regarding update of newly single-strip + uncompressed files whose bytecount is 0. Before the change of 2016-12-03, + the condition bytecount==0 used to trigger an early exit/disabling of + strip chop. Re-introduce that in update mode. Otherwise this cause + later incorrect setting for the value of StripByCounts/StripOffsets. + ( https://trac.osgeo.org/gdal/ticket/6924 ) +
  • libtiff/tif_dirread.c: TIFFFetchStripThing(): limit the number of items + read in StripOffsets/StripByteCounts tags to the number of strips to avoid + excessive memory allocation. + Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2215 + Credit to OSS Fuzz +
  • libtiff/tif_getimage.c: avoid many (harmless) unsigned int overflows. +
  • libtiff/tif_fax3.c: avoid unsigned int overflow in Fax3Encode2DRow(). Could + potentially be a bug with huge rows. +
  • libtiff/tif_jpeg.c: avoid (harmless) unsigned int overflow on tiled images. +
  • libtiff/tif_dirread.c: avoid unsigned int overflow in EstimateStripByteCounts() + and BYTECOUNTLOOKSBAD when file is too short. +
  • libtiff/tif_predict.c: decorate legitimate functions where unsigned int + overflow occur with TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW + * libtiff/tif_dirread.c: avoid unsigned int overflow in EstimateStripByteCounts() +
  • libtiff/tiffiop.h: add TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW macro to + disable CLang warnings raised by -fsanitize=undefined,unsigned-integer-overflow +
  • libtiff/tif_jpeg.c: add anti-denial of service measure to avoid excessive + CPU consumption on progressive JPEGs with a huge number of scans. + See http://www.libjpeg-turbo.org/pmwiki/uploads/About/TwoIssueswiththeJPEGStandard.pdf + Note: only affects libtiff since 2014-12-29 where support of non-baseline JPEG + was added. + +
  • libtiff/tif_jpeg.c: error out at decoding time if anticipated libjpeg + memory allocation is above 100 MB. libjpeg in case of multiple scans, + which is allowed even in baseline JPEG, if components are spread over several + scans and not interleavedin a single one, needs to allocate memory (or + backing store) for the whole strip/tile. + See http://www.libjpeg-turbo.org/pmwiki/uploads/About/TwoIssueswiththeJPEGStandard.pdf + This limitation may be overriden by setting the + LIBTIFF_ALLOW_LARGE_LIBJPEG_MEM_ALLOC environment variable, or recompiling + libtiff with a custom value of TIFF_LIBJPEG_LARGEST_MEM_ALLOC macro. +
  • libtiff/tif_jbig.c: fix memory leak in error code path of JBIGDecode() + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2706 + Reported by team OWL337 +
  • libtiff/tif_dirread.c: in TIFFReadDirEntryFloat(), check that a + double value can fit in a float before casting. Patch by Nicolas RUFF +
  • libtiff/tiffiop.h, libtiff/tif_jpeg.c, libtiff/tif_jpeg_12.c, + libtiff/tif_read.c: make TIFFReadScanline() works in + CHUNKY_STRIP_READ_SUPPORT mode with JPEG stream with multiple scans. + Also make configurable through a LIBTIFF_JPEG_MAX_ALLOWED_SCAN_NUMBER + environment variable the maximum number of scans allowed. Defaults to + 100. +
  • libtiff/tif_read.c: TIFFFillTile(): add limitation to the number + of bytes read in case td_stripbytecount[strip] is bigger than + reasonable, so as to avoid excessive memory allocation (similarly to + what was done for TIFFFileStrip() on 2017-05-10) +
  • libtiff/tif_getimage.c: use _TIFFReadEncodedStripAndAllocBuffer(). + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2708 and + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2433 . + Credit to OSS Fuzz +
  • libtiff/tif_read.c, tiffiop.h: add a _TIFFReadEncodedStripAndAllocBuffer() + function, variant of TIFFReadEncodedStrip() that allocates the + decoded buffer only after a first successful TIFFFillStrip(). This avoids + excessive memory allocation on corrupted files. +
  • libtiff/tif_dirwrite.c: in TIFFWriteDirectoryTagCheckedXXXX() + functions associated with LONG8/SLONG8 data type, replace assertion that + the file is BigTIFF, by a non-fatal error. + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2712 + Reported by team OWL337 +
  • libtiff/tif_read.c: TIFFStartTile(): set tif_rawcc to + tif_rawdataloaded when it is set. Similarly to TIFFStartStrip(). + This issue was revealed by the change of 2017-06-30 in TIFFFileTile(), + limiting the number of bytes read. But it could probably have been hit + too in CHUNKY_STRIP_READ_SUPPORT mode previously ? + Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2454 + Credit to OSS Fuzz +
  • libtiff/tif_error.c, tif_warning.c: correctly use va_list when both + an old-style and new-style warning/error handlers are installed. + Patch by Paavo Helde (sent on the mailing list) +
  • libtiff/tif_getimage.c: use _TIFFReadTileAndAllocBuffer(). + Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2470 + Credit to OSS Fuzz. +
  • libtiff/tif_read.c, tiffiop.h: add a _TIFFReadEncodedTileAndAllocBuffer() + and _TIFFReadTileAndAllocBuffer() variants of TIFFReadEncodedTile() and + TIFFReadTile() that allocates the decoded buffer only after a first + successful TIFFFillTile(). This avoids excessive memory allocation + on corrupted files. +
  • libtiff/tif_pixarlog.c: avoid excessive memory allocation on decoding + when RowsPerStrip tag is not defined (and thus td_rowsperstrip == UINT_MAX) + Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2554 + Credit to OSS Fuzz +
  • libtiff/tif_lzw.c: fix 4.0.8 regression in the decoding of old-style LZW + compressed files. +
  • libtiff/tif_lzw.c: fix potential out-of-buffer read on 1-byte LZW + strips. Crashing issue only on memory mapped files, where the strip + offset is the last byte of the file, and the file size is a multiple + of one page size on the CPU architecture (typically 4096). Credit + to myself :-) +
  • libtiff/tif_dir.c: avoid potential null pointer dereference in + _TIFFVGetField() on corrupted TIFFTAG_NUMBEROFINKS tag instance. + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2713 +
  • tools/tiff2pdf.c: prevent heap buffer overflow write in "Raw" + mode on PlanarConfig=Contig input images. + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2715 + Reported by team OWL337 +
  • libtiff/tif_read.c: TIFFFillStrip() / TIFFFillTile(). + Complementary fix for http://bugzilla.maptools.org/show_bug.cgi?id=2708 + in the isMapped() case, so as to avoid excessive memory allocation + when we need a temporary buffer but the file is truncated. +
  • libtiff/tif_read.c: TIFFFillStrip() / TIFFFillTile(). + Complementary fix for http://bugzilla.maptools.org/show_bug.cgi?id=2708 + in the isMapped() case, so as to avoid excessive memory allocation + when we need a temporary buffer but the file is truncated. +
  • libtiff/tif_read.c: in TIFFFetchStripThing(), only grow the + arrays that hold StripOffsets/StripByteCounts, when they are smaller + than the expected number of striles, up to 1 million striles, and + error out beyond. Can be tweaked by setting the environment variable + LIBTIFF_STRILE_ARRAY_MAX_RESIZE_COUNT. + This partially goes against a change added on 2002-12-17 to accept + those arrays of wrong sizes, but is needed to avoid denial of services. + Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2350 + Credit to OSS Fuzz +
  • libtiff/tif_read.c: in TIFFFetchStripThing(), only grow the + arrays that hold StripOffsets/StripByteCounts, when they are smaller + than the expected number of striles, up to 1 million striles, and + error out beyond. Can be tweaked by setting the environment variable + LIBTIFF_STRILE_ARRAY_MAX_RESIZE_COUNT. + This partially goes against a change added on 2002-12-17 to accept + those arrays of wrong sizes, but is needed to avoid denial of services. + Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2350 + Credit to OSS Fuzz +
  • libtiff/tif_read.c: add protection against excessive memory + allocation attempts in TIFFReadDirEntryArray() on short files. + Effective for mmap'ed case. And non-mmap'ed case, but restricted + to 64bit builds. + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2675 +
  • libtiff/tif_read.c: add protection against excessive memory + allocation attempts in TIFFReadDirEntryArray() on short files. + Effective for mmap'ed case. And non-mmap'ed case, but restricted + to 64bit builds. + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2675 +
  • libtiff/tif_luv.c: LogLuvInitState(): avoid excessive memory + allocation when RowsPerStrip tag is missing. + Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2683 + Credit to OSS-Fuzz +
  • libtiff/tif_getimage.c: gtTileContig() and gtTileSeparate(): + properly break from loops on error when stoponerr is set, instead + of going on iterating on row based loop. +
  • libtiff/tif_getimage.c: fix fromskew computation when to-be-skipped + pixel number is not a multiple of the horizontal subsampling, and + also in some other cases. Impact putcontig8bitYCbCr44tile, + putcontig8bitYCbCr42tile, putcontig8bitYCbCr41tile, + putcontig8bitYCbCr21tile and putcontig8bitYCbCr12tile + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2637 (discovered + by Agostino Sarubbo) + and https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2691 (credit + to OSS Fuzz) +
  • libtiff/tif_luv.c: further reduce memory requirements for temporary + buffer when RowsPerStrip >= image_length in LogLuvInitState() and + LogL16InitState(). + Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2700 + Credit to OSS Fuzz +
  • libtiff/tif_dirwrite.c: replace assertion related to not finding the + SubIFD tag by runtime check (in TIFFWriteDirectorySec()) + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2727 + Reported by team OWL337 +
  • libtiff/tif_dirwrite.c: replace assertion to tag value not fitting + on uint32 when selecting the value of SubIFD tag by runtime check + (in TIFFWriteDirectoryTagSubifd()). + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2728 + Reported by team OWL337 +
  • libtiff/tif_jpeg.c: accept reading the last strip of a JPEG compressed + file if the codestream height is larger than the truncated height of the + strip. Emit a warning in this situation since this is non compliant. +
  • libtiff/tiffiop.h, tif_aux.c: redirect SeekOK() macro to a _TIFFSeekoK() + function that checks if the offset is not bigger than INT64_MAX, so as + to avoid a -1 error return code of TIFFSeekFile() to match a required + seek to UINT64_MAX/-1. + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2726 + Adapted from proposal by Nicolas Ruff. +
  • libtiff/tif_dirread.c: add NULL check to avoid likely false positive + null-pointer dereference warning by CLang Static Analyzer. +
  • libtiff/libtiff.def: add TIFFReadRGBAStripExt and TIFFReadRGBATileExt + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2735 +
  • libtiff/tif_jpeg.c: add compatibility with libjpeg-turbo 1.5.2 that + honours max_memory_to_use > 0. + Cf https://github.com/libjpeg-turbo/libjpeg-turbo/issues/162 +
  • libtiff/tif_getimage.c: avoid floating point division by zero in + initCIELabConversion() + Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=3733 + Credit to OSS Fuzz +
+ +


+ + + +CHANGES IN THE TOOLS: + +
    + +
  • tools/tiff2pdf.c: prevent heap buffer overflow write in "Raw" + mode on PlanarConfig=Contig input images. + Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2715 + Reported by team OWL337 +
  • tools/tiffset.c: fix setting a single value for the ExtraSamples tag + (and other tags with variable number of values). + So 'tiffset -s ExtraSamples 1 X'. This only worked + when setting 2 or more values, but not just one. +
  • tools/fax2tiff.c (_FAX_Client_Data): Pass FAX_Client_Data as the + client data. This client data is not used at all at the moment, + but it makes the most sense. Issue that the value of + client_data.fd was passed where a pointer is expected was reported + via email by Gerald Schade on Sun, 29 Oct 2017. +
  • tools/tiff2pdf.c (t2p_sample_realize_palette): Fix possible + arithmetic overflow in bounds checking code and eliminate + comparison between signed and unsigned type. +
  • tools/tiff2bw.c (main): Free memory allocated in the tiff2bw + program. This is in response to the report associated with + CVE-2017-16232 but does not solve the extremely high memory usage + with the associated POC file. + +
+ +


+ + + +CHANGES IN THE CONTRIB AREA: + +
    + +
  • None + +
+ +Last updated $Date: 2017-11-18 19:38:06 $. + + + diff --git a/libtiff/libtiff.def b/libtiff/libtiff.def index acf8609..341c719 100644 --- a/libtiff/libtiff.def +++ b/libtiff/libtiff.def @@ -85,7 +85,9 @@ EXPORTS TIFFAccessTagMethods TIFFReadRGBAImage TIFFReadRGBAImageOriented TIFFReadRGBAStrip + TIFFReadRGBAStripExt TIFFReadRGBATile + TIFFReadRGBATileExt TIFFReadRawStrip TIFFReadRawTile TIFFReadScanline diff --git a/libtiff/tif_aux.c b/libtiff/tif_aux.c index 3d35ba9..10b8d00 100644 --- a/libtiff/tif_aux.c +++ b/libtiff/tif_aux.c @@ -1,4 +1,4 @@ -/* $Id: tif_aux.c,v 1.29 2016-11-11 20:45:53 erouault Exp $ */ +/* $Id: tif_aux.c,v 1.31 2017-11-17 20:21:00 erouault Exp $ */ /* * Copyright (c) 1991-1997 Sam Leffler @@ -359,6 +359,13 @@ _TIFFUInt64ToDouble(uint64 ui64) } } +int _TIFFSeekOK(TIFF* tif, toff_t off) +{ + /* Huge offsets, especially -1 / UINT64_MAX, can cause issues */ + /* See http://bugzilla.maptools.org/show_bug.cgi?id=2726 */ + return off <= (~(uint64)0)/2 && TIFFSeekFile(tif,off,SEEK_SET)==off; +} + /* vim: set ts=8 sts=8 sw=8 noet: */ /* * Local Variables: diff --git a/libtiff/tif_color.c b/libtiff/tif_color.c index 89194c2..71cafcd 100644 --- a/libtiff/tif_color.c +++ b/libtiff/tif_color.c @@ -1,4 +1,4 @@ -/* $Id: tif_color.c,v 1.22 2016-09-04 21:32:56 erouault Exp $ */ +/* $Id: tif_color.c,v 1.24 2017-05-29 10:12:54 erouault Exp $ */ /* * Copyright (c) 1988-1997 Sam Leffler @@ -199,6 +199,23 @@ TIFFYCbCrtoRGB(TIFFYCbCrToRGB *ycbcr, uint32 Y, int32 Cb, int32 Cr, *b = CLAMP(i, 0, 255); } +/* Clamp function for sanitization purposes. Normally clamping should not */ +/* occur for well behaved chroma and refBlackWhite coefficients */ +static float CLAMPw(float v, float vmin, float vmax) +{ + if( v < vmin ) + { + /* printf("%f clamped to %f\n", v, vmin); */ + return vmin; + } + if( v > vmax ) + { + /* printf("%f clamped to %f\n", v, vmax); */ + return vmax; + } + return v; +} + /* * Initialize the YCbCr->RGB conversion tables. The conversion * is done according to the 6.0 spec: @@ -238,10 +255,10 @@ TIFFYCbCrToRGBInit(TIFFYCbCrToRGB* ycbcr, float *luma, float *refBlackWhite) ycbcr->Cb_g_tab = ycbcr->Cr_g_tab + 256; ycbcr->Y_tab = ycbcr->Cb_g_tab + 256; - { float f1 = 2-2*LumaRed; int32 D1 = FIX(f1); - float f2 = LumaRed*f1/LumaGreen; int32 D2 = -FIX(f2); - float f3 = 2-2*LumaBlue; int32 D3 = FIX(f3); - float f4 = LumaBlue*f3/LumaGreen; int32 D4 = -FIX(f4); + { float f1 = 2-2*LumaRed; int32 D1 = FIX(CLAMP(f1,0.0F,2.0F)); + float f2 = LumaRed*f1/LumaGreen; int32 D2 = -FIX(CLAMP(f2,0.0F,2.0F)); + float f3 = 2-2*LumaBlue; int32 D3 = FIX(CLAMP(f3,0.0F,2.0F)); + float f4 = LumaBlue*f3/LumaGreen; int32 D4 = -FIX(CLAMP(f4,0.0F,2.0F)); int x; #undef LumaBlue @@ -256,17 +273,20 @@ TIFFYCbCrToRGBInit(TIFFYCbCrToRGB* ycbcr, float *luma, float *refBlackWhite) * constructing tables indexed by the raw pixel data. */ for (i = 0, x = -128; i < 256; i++, x++) { - int32 Cr = (int32)Code2V(x, refBlackWhite[4] - 128.0F, - refBlackWhite[5] - 128.0F, 127); - int32 Cb = (int32)Code2V(x, refBlackWhite[2] - 128.0F, - refBlackWhite[3] - 128.0F, 127); + int32 Cr = (int32)CLAMPw(Code2V(x, refBlackWhite[4] - 128.0F, + refBlackWhite[5] - 128.0F, 127), + -128.0F * 32, 128.0F * 32); + int32 Cb = (int32)CLAMPw(Code2V(x, refBlackWhite[2] - 128.0F, + refBlackWhite[3] - 128.0F, 127), + -128.0F * 32, 128.0F * 32); ycbcr->Cr_r_tab[i] = (int32)((D1*Cr + ONE_HALF)>>SHIFT); ycbcr->Cb_b_tab[i] = (int32)((D3*Cb + ONE_HALF)>>SHIFT); ycbcr->Cr_g_tab[i] = D2*Cr; ycbcr->Cb_g_tab[i] = D4*Cb + ONE_HALF; ycbcr->Y_tab[i] = - (int32)Code2V(x + 128, refBlackWhite[0], refBlackWhite[1], 255); + (int32)CLAMPw(Code2V(x + 128, refBlackWhite[0], refBlackWhite[1], 255), + -128.0F * 32, 128.0F * 32); } } diff --git a/libtiff/tif_dir.c b/libtiff/tif_dir.c index ad21655..f00f808 100644 --- a/libtiff/tif_dir.c +++ b/libtiff/tif_dir.c @@ -1,4 +1,4 @@ -/* $Id: tif_dir.c,v 1.127 2016-10-25 21:35:15 erouault Exp $ */ +/* $Id: tif_dir.c,v 1.131 2017-07-11 21:38:04 erouault Exp $ */ /* * Copyright (c) 1988-1997 Sam Leffler @@ -31,6 +31,7 @@ * (and also some miscellaneous stuff) */ #include "tiffiop.h" +#include /* * These are used in the backwards compatibility code... @@ -154,6 +155,15 @@ bad: return (0); } +static float TIFFClampDoubleToFloat( double val ) +{ + if( val > FLT_MAX ) + return FLT_MAX; + if( val < -FLT_MAX ) + return -FLT_MAX; + return (float)val; +} + static int _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap) { @@ -312,13 +322,13 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap) dblval = va_arg(ap, double); if( dblval < 0 ) goto badvaluedouble; - td->td_xresolution = (float) dblval; + td->td_xresolution = TIFFClampDoubleToFloat( dblval ); break; case TIFFTAG_YRESOLUTION: dblval = va_arg(ap, double); if( dblval < 0 ) goto badvaluedouble; - td->td_yresolution = (float) dblval; + td->td_yresolution = TIFFClampDoubleToFloat( dblval ); break; case TIFFTAG_PLANARCONFIG: v = (uint16) va_arg(ap, uint16_vap); @@ -327,10 +337,10 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap) td->td_planarconfig = (uint16) v; break; case TIFFTAG_XPOSITION: - td->td_xposition = (float) va_arg(ap, double); + td->td_xposition = TIFFClampDoubleToFloat( va_arg(ap, double) ); break; case TIFFTAG_YPOSITION: - td->td_yposition = (float) va_arg(ap, double); + td->td_yposition = TIFFClampDoubleToFloat( va_arg(ap, double) ); break; case TIFFTAG_RESOLUTIONUNIT: v = (uint16) va_arg(ap, uint16_vap); @@ -676,7 +686,7 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap) case TIFF_SRATIONAL: case TIFF_FLOAT: { - float v2 = (float)va_arg(ap, double); + float v2 = TIFFClampDoubleToFloat(va_arg(ap, double)); _TIFFmemcpy(val, &v2, tv_size); } break; @@ -854,6 +864,34 @@ _TIFFVGetField(TIFF* tif, uint32 tag, va_list ap) if( fip == NULL ) /* cannot happen since TIFFGetField() already checks it */ return 0; + if( tag == TIFFTAG_NUMBEROFINKS ) + { + int i; + for (i = 0; i < td->td_customValueCount; i++) { + uint16 val; + TIFFTagValue *tv = td->td_customValues + i; + if (tv->info->field_tag != tag) + continue; + if( tv->value == NULL ) + return 0; + val = *(uint16 *)tv->value; + /* Truncate to SamplesPerPixel, since the */ + /* setting code for INKNAMES assume that there are SamplesPerPixel */ + /* inknames. */ + /* Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2599 */ + if( val > td->td_samplesperpixel ) + { + TIFFWarningExt(tif->tif_clientdata,"_TIFFVGetField", + "Truncating NumberOfInks from %u to %u", + val, td->td_samplesperpixel); + val = td->td_samplesperpixel; + } + *va_arg(ap, uint16*) = val; + return 1; + } + return 0; + } + /* * We want to force the custom code to be used for custom * fields even if the tag happens to match a well known diff --git a/libtiff/tif_dir.h b/libtiff/tif_dir.h index 6af5f3d..5a38076 100644 --- a/libtiff/tif_dir.h +++ b/libtiff/tif_dir.h @@ -1,4 +1,4 @@ -/* $Id: tif_dir.h,v 1.54 2011-02-18 20:53:05 fwarmerdam Exp $ */ +/* $Id: tif_dir.h,v 1.55 2017-06-01 12:44:04 erouault Exp $ */ /* * Copyright (c) 1988-1997 Sam Leffler @@ -291,6 +291,7 @@ struct _TIFFField { extern int _TIFFMergeFields(TIFF*, const TIFFField[], uint32); extern const TIFFField* _TIFFFindOrRegisterField(TIFF *, uint32, TIFFDataType); extern TIFFField* _TIFFCreateAnonField(TIFF *, uint32, TIFFDataType); +extern int _TIFFCheckFieldIsValidForCodec(TIFF *tif, ttag_t tag); #if defined(__cplusplus) } diff --git a/libtiff/tif_dirinfo.c b/libtiff/tif_dirinfo.c index 23ad002..4904f54 100644 --- a/libtiff/tif_dirinfo.c +++ b/libtiff/tif_dirinfo.c @@ -1,4 +1,4 @@ -/* $Id: tif_dirinfo.c,v 1.126 2016-11-18 02:52:13 bfriesen Exp $ */ +/* $Id: tif_dirinfo.c,v 1.127 2017-06-01 12:44:04 erouault Exp $ */ /* * Copyright (c) 1988-1997 Sam Leffler @@ -956,6 +956,109 @@ TIFFMergeFieldInfo(TIFF* tif, const TIFFFieldInfo info[], uint32 n) return 0; } +int +_TIFFCheckFieldIsValidForCodec(TIFF *tif, ttag_t tag) +{ + /* Filter out non-codec specific tags */ + switch (tag) { + /* Shared tags */ + case TIFFTAG_PREDICTOR: + /* JPEG tags */ + case TIFFTAG_JPEGTABLES: + /* OJPEG tags */ + case TIFFTAG_JPEGIFOFFSET: + case TIFFTAG_JPEGIFBYTECOUNT: + case TIFFTAG_JPEGQTABLES: + case TIFFTAG_JPEGDCTABLES: + case TIFFTAG_JPEGACTABLES: + case TIFFTAG_JPEGPROC: + case TIFFTAG_JPEGRESTARTINTERVAL: + /* CCITT* */ + case TIFFTAG_BADFAXLINES: + case TIFFTAG_CLEANFAXDATA: + case TIFFTAG_CONSECUTIVEBADFAXLINES: + case TIFFTAG_GROUP3OPTIONS: + case TIFFTAG_GROUP4OPTIONS: + break; + default: + return 1; + } + /* Check if codec specific tags are allowed for the current + * compression scheme (codec) */ + switch (tif->tif_dir.td_compression) { + case COMPRESSION_LZW: + if (tag == TIFFTAG_PREDICTOR) + return 1; + break; + case COMPRESSION_PACKBITS: + /* No codec-specific tags */ + break; + case COMPRESSION_THUNDERSCAN: + /* No codec-specific tags */ + break; + case COMPRESSION_NEXT: + /* No codec-specific tags */ + break; + case COMPRESSION_JPEG: + if (tag == TIFFTAG_JPEGTABLES) + return 1; + break; + case COMPRESSION_OJPEG: + switch (tag) { + case TIFFTAG_JPEGIFOFFSET: + case TIFFTAG_JPEGIFBYTECOUNT: + case TIFFTAG_JPEGQTABLES: + case TIFFTAG_JPEGDCTABLES: + case TIFFTAG_JPEGACTABLES: + case TIFFTAG_JPEGPROC: + case TIFFTAG_JPEGRESTARTINTERVAL: + return 1; + } + break; + case COMPRESSION_CCITTRLE: + case COMPRESSION_CCITTRLEW: + case COMPRESSION_CCITTFAX3: + case COMPRESSION_CCITTFAX4: + switch (tag) { + case TIFFTAG_BADFAXLINES: + case TIFFTAG_CLEANFAXDATA: + case TIFFTAG_CONSECUTIVEBADFAXLINES: + return 1; + case TIFFTAG_GROUP3OPTIONS: + if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX3) + return 1; + break; + case TIFFTAG_GROUP4OPTIONS: + if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX4) + return 1; + break; + } + break; + case COMPRESSION_JBIG: + /* No codec-specific tags */ + break; + case COMPRESSION_DEFLATE: + case COMPRESSION_ADOBE_DEFLATE: + if (tag == TIFFTAG_PREDICTOR) + return 1; + break; + case COMPRESSION_PIXARLOG: + if (tag == TIFFTAG_PREDICTOR) + return 1; + break; + case COMPRESSION_SGILOG: + case COMPRESSION_SGILOG24: + /* No codec-specific tags */ + break; + case COMPRESSION_LZMA: + if (tag == TIFFTAG_PREDICTOR) + return 1; + break; + + } + return 0; +} + /* vim: set ts=8 sts=8 sw=8 noet: */ /* diff --git a/libtiff/tif_dirread.c b/libtiff/tif_dirread.c index 01070f2..5e62e81 100644 --- a/libtiff/tif_dirread.c +++ b/libtiff/tif_dirread.c @@ -1,4 +1,4 @@ -/* $Id: tif_dirread.c,v 1.204 2016-11-16 15:14:15 erouault Exp $ */ +/* $Id: tif_dirread.c,v 1.218 2017-09-09 21:44:42 erouault Exp $ */ /* * Copyright (c) 1988-1997 Sam Leffler @@ -40,6 +40,8 @@ */ #include "tiffiop.h" +#include +#include #define IGNORE 0 /* tag placeholder used below */ #define FAILED_FII ((uint32) -1) @@ -635,6 +637,8 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryFloat(TIFF* tif, TIFFDirEntry* d err=TIFFReadDirEntryCheckedDouble(tif,direntry,&m); if (err!=TIFFReadDirEntryErrOk) return(err); + if ((m > FLT_MAX) || (m < FLT_MIN)) + return(TIFFReadDirEntryErrRange); *value=(float)m; return(TIFFReadDirEntryErrOk); } @@ -764,13 +768,80 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryIfd8(TIFF* tif, TIFFDirEntry* di } } -static enum TIFFReadDirEntryErr TIFFReadDirEntryArray(TIFF* tif, TIFFDirEntry* direntry, uint32* count, uint32 desttypesize, void** value) + +#define INITIAL_THRESHOLD (1024 * 1024) +#define THRESHOLD_MULTIPLIER 10 +#define MAX_THRESHOLD (THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * INITIAL_THRESHOLD) + +static enum TIFFReadDirEntryErr TIFFReadDirEntryDataAndRealloc( + TIFF* tif, uint64 offset, tmsize_t size, void** pdest) +{ +#if SIZEOF_VOIDP == 8 || SIZEOF_SIZE_T == 8 + tmsize_t threshold = INITIAL_THRESHOLD; +#endif + tmsize_t already_read = 0; + + assert( !isMapped(tif) ); + + if (!SeekOK(tif,offset)) + return(TIFFReadDirEntryErrIo); + + /* On 64 bit processes, read first a maximum of 1 MB, then 10 MB, etc */ + /* so as to avoid allocating too much memory in case the file is too */ + /* short. We could ask for the file size, but this might be */ + /* expensive with some I/O layers (think of reading a gzipped file) */ + /* Restrict to 64 bit processes, so as to avoid reallocs() */ + /* on 32 bit processes where virtual memory is scarce. */ + while( already_read < size ) + { + void* new_dest; + tmsize_t bytes_read; + tmsize_t to_read = size - already_read; +#if SIZEOF_VOIDP == 8 || SIZEOF_SIZE_T == 8 + if( to_read >= threshold && threshold < MAX_THRESHOLD ) + { + to_read = threshold; + threshold *= THRESHOLD_MULTIPLIER; + } +#endif + + new_dest = (uint8*) _TIFFrealloc( + *pdest, already_read + to_read); + if( new_dest == NULL ) + { + TIFFErrorExt(tif->tif_clientdata, tif->tif_name, + "Failed to allocate memory for %s " + "(%ld elements of %ld bytes each)", + "TIFFReadDirEntryArray", + (long) 1, (long) (already_read + to_read)); + return TIFFReadDirEntryErrAlloc; + } + *pdest = new_dest; + + bytes_read = TIFFReadFile(tif, + (char*)*pdest + already_read, to_read); + already_read += bytes_read; + if (bytes_read != to_read) { + return TIFFReadDirEntryErrIo; + } + } + return TIFFReadDirEntryErrOk; +} + +static enum TIFFReadDirEntryErr TIFFReadDirEntryArrayWithLimit( + TIFF* tif, TIFFDirEntry* direntry, uint32* count, uint32 desttypesize, + void** value, uint64 maxcount) { int typesize; uint32 datasize; void* data; + uint64 target_count64; typesize=TIFFDataWidth(direntry->tdir_type); - if ((direntry->tdir_count==0)||(typesize==0)) + + target_count64 = (direntry->tdir_count > maxcount) ? + maxcount : direntry->tdir_count; + + if ((target_count64==0)||(typesize==0)) { *value=0; return(TIFFReadDirEntryErrOk); @@ -782,17 +853,30 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryArray(TIFF* tif, TIFFDirEntry* d * in either the current data type or the dest data type. This also * avoids problems with overflow of tmsize_t on 32bit systems. */ - if ((uint64)(2147483647/typesize)tdir_count) + if ((uint64)(2147483647/typesize)tdir_count) + if ((uint64)(2147483647/desttypesize)tdir_count; + *count=(uint32)target_count64; datasize=(*count)*typesize; assert((tmsize_t)datasize>0); - data=_TIFFCheckMalloc(tif, *count, typesize, "ReadDirEntryArray"); - if (data==0) - return(TIFFReadDirEntryErrAlloc); + + if( isMapped(tif) && datasize > (uint32)tif->tif_size ) + return TIFFReadDirEntryErrIo; + + if( !isMapped(tif) && + (((tif->tif_flags&TIFF_BIGTIFF) && datasize > 8) || + (!(tif->tif_flags&TIFF_BIGTIFF) && datasize > 4)) ) + { + data = NULL; + } + else + { + data=_TIFFCheckMalloc(tif, *count, typesize, "ReadDirEntryArray"); + if (data==0) + return(TIFFReadDirEntryErrAlloc); + } if (!(tif->tif_flags&TIFF_BIGTIFF)) { if (datasize<=4) @@ -803,7 +887,10 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryArray(TIFF* tif, TIFFDirEntry* d uint32 offset = direntry->tdir_offset.toff_long; if (tif->tif_flags&TIFF_SWAB) TIFFSwabLong(&offset); - err=TIFFReadDirEntryData(tif,(uint64)offset,(tmsize_t)datasize,data); + if( isMapped(tif) ) + err=TIFFReadDirEntryData(tif,(uint64)offset,(tmsize_t)datasize,data); + else + err=TIFFReadDirEntryDataAndRealloc(tif,(uint64)offset,(tmsize_t)datasize,&data); if (err!=TIFFReadDirEntryErrOk) { _TIFFfree(data); @@ -821,7 +908,10 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryArray(TIFF* tif, TIFFDirEntry* d uint64 offset = direntry->tdir_offset.toff_long8; if (tif->tif_flags&TIFF_SWAB) TIFFSwabLong8(&offset); - err=TIFFReadDirEntryData(tif,offset,(tmsize_t)datasize,data); + if( isMapped(tif) ) + err=TIFFReadDirEntryData(tif,(uint64)offset,(tmsize_t)datasize,data); + else + err=TIFFReadDirEntryDataAndRealloc(tif,(uint64)offset,(tmsize_t)datasize,&data); if (err!=TIFFReadDirEntryErrOk) { _TIFFfree(data); @@ -833,6 +923,12 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryArray(TIFF* tif, TIFFDirEntry* d return(TIFFReadDirEntryErrOk); } +static enum TIFFReadDirEntryErr TIFFReadDirEntryArray(TIFF* tif, TIFFDirEntry* direntry, uint32* count, uint32 desttypesize, void** value) +{ + return TIFFReadDirEntryArrayWithLimit(tif, direntry, count, + desttypesize, value, ~((uint64)0)); +} + static enum TIFFReadDirEntryErr TIFFReadDirEntryByteArray(TIFF* tif, TIFFDirEntry* direntry, uint8** value) { enum TIFFReadDirEntryErr err; @@ -1862,7 +1958,8 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntrySlongArray(TIFF* tif, TIFFDirEnt return(TIFFReadDirEntryErrOk); } -static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8Array(TIFF* tif, TIFFDirEntry* direntry, uint64** value) +static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8ArrayWithLimit( + TIFF* tif, TIFFDirEntry* direntry, uint64** value, uint64 maxcount) { enum TIFFReadDirEntryErr err; uint32 count; @@ -1882,7 +1979,7 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8Array(TIFF* tif, TIFFDirEnt default: return(TIFFReadDirEntryErrType); } - err=TIFFReadDirEntryArray(tif,direntry,&count,8,&origdata); + err=TIFFReadDirEntryArrayWithLimit(tif,direntry,&count,8,&origdata,maxcount); if ((err!=TIFFReadDirEntryErrOk)||(origdata==0)) { *value=0; @@ -2028,6 +2125,11 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8Array(TIFF* tif, TIFFDirEnt return(TIFFReadDirEntryErrOk); } +static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8Array(TIFF* tif, TIFFDirEntry* direntry, uint64** value) +{ + return TIFFReadDirEntryLong8ArrayWithLimit(tif, direntry, value, ~((uint64)0)); +} + static enum TIFFReadDirEntryErr TIFFReadDirEntrySlong8Array(TIFF* tif, TIFFDirEntry* direntry, int64** value) { enum TIFFReadDirEntryErr err; @@ -2406,7 +2508,14 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryFloatArray(TIFF* tif, TIFFDirEnt ma=(double*)origdata; mb=data; for (n=0; n FLT_MAX ) + val = FLT_MAX; + else if( val < -FLT_MAX ) + val = -FLT_MAX; + *mb++=(float)val; + } } break; } @@ -2723,7 +2832,7 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryPersampleShort(TIFF* tif, TIFFDi if (direntry->tdir_count<(uint64)tif->tif_dir.td_samplesperpixel) return(TIFFReadDirEntryErrCount); err=TIFFReadDirEntryShortArray(tif,direntry,&m); - if (err!=TIFFReadDirEntryErrOk) + if (err!=TIFFReadDirEntryErrOk || m == NULL) return(err); na=m; nb=tif->tif_dir.td_samplesperpixel; @@ -2872,7 +2981,10 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedRational(TIFF* tif, TIFFD m.l = direntry->tdir_offset.toff_long8; if (tif->tif_flags&TIFF_SWAB) TIFFSwabArrayOfLong(m.i,2); - if (m.i[0]==0) + /* Not completely sure what we should do when m.i[1]==0, but some */ + /* sanitizers do not like division by 0.0: */ + /* http://bugzilla.maptools.org/show_bug.cgi?id=2644 */ + if (m.i[0]==0 || m.i[1]==0) *value=0.0; else *value=(double)m.i[0]/(double)m.i[1]; @@ -2900,7 +3012,10 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedSrational(TIFF* tif, TIFF m.l=direntry->tdir_offset.toff_long8; if (tif->tif_flags&TIFF_SWAB) TIFFSwabArrayOfLong(m.i,2); - if ((int32)m.i[0]==0) + /* Not completely sure what we should do when m.i[1]==0, but some */ + /* sanitizers do not like division by 0.0: */ + /* http://bugzilla.maptools.org/show_bug.cgi?id=2644 */ + if ((int32)m.i[0]==0 || m.i[1]==0) *value=0.0; else *value=(double)((int32)m.i[0])/(double)m.i[1]; @@ -3566,6 +3681,10 @@ TIFFReadDirectory(TIFF* tif) goto bad; dp->tdir_tag=IGNORE; break; + default: + if( !_TIFFCheckFieldIsValidForCodec(tif, dp->tdir_tag) ) + dp->tdir_tag=IGNORE; + break; } } } @@ -3724,6 +3843,14 @@ TIFFReadDirectory(TIFF* tif) _TIFFmemcpy( &(tif->tif_dir.td_stripoffset_entry), dp, sizeof(TIFFDirEntry) ); #else + if( tif->tif_dir.td_stripoffset != NULL ) + { + TIFFErrorExt(tif->tif_clientdata, module, + "tif->tif_dir.td_stripoffset is " + "already allocated. Likely duplicated " + "StripOffsets/TileOffsets tag"); + goto bad; + } if (!TIFFFetchStripThing(tif,dp,tif->tif_dir.td_nstrips,&tif->tif_dir.td_stripoffset)) goto bad; #endif @@ -3734,7 +3861,15 @@ TIFFReadDirectory(TIFF* tif) _TIFFmemcpy( &(tif->tif_dir.td_stripbytecount_entry), dp, sizeof(TIFFDirEntry) ); #else - if (!TIFFFetchStripThing(tif,dp,tif->tif_dir.td_nstrips,&tif->tif_dir.td_stripbytecount)) + if( tif->tif_dir.td_stripbytecount != NULL ) + { + TIFFErrorExt(tif->tif_clientdata, module, + "tif->tif_dir.td_stripbytecount is " + "already allocated. Likely duplicated " + "StripByteCounts/TileByteCounts tag"); + goto bad; + } + if (!TIFFFetchStripThing(tif,dp,tif->tif_dir.td_nstrips,&tif->tif_dir.td_stripbytecount)) goto bad; #endif break; @@ -3949,12 +4084,14 @@ TIFFReadDirectory(TIFF* tif) #define BYTECOUNTLOOKSBAD \ ( (tif->tif_dir.td_stripbytecount[0] == 0 && tif->tif_dir.td_stripoffset[0] != 0) || \ (tif->tif_dir.td_compression == COMPRESSION_NONE && \ - tif->tif_dir.td_stripbytecount[0] > TIFFGetFileSize(tif) - tif->tif_dir.td_stripoffset[0]) || \ + (tif->tif_dir.td_stripoffset[0] <= TIFFGetFileSize(tif) && \ + tif->tif_dir.td_stripbytecount[0] > TIFFGetFileSize(tif) - tif->tif_dir.td_stripoffset[0])) || \ (tif->tif_mode == O_RDONLY && \ tif->tif_dir.td_compression == COMPRESSION_NONE && \ tif->tif_dir.td_stripbytecount[0] < TIFFScanlineSize64(tif) * tif->tif_dir.td_imagelength) ) } else if (tif->tif_dir.td_nstrips == 1 + && !(tif->tif_flags&TIFF_ISTILED) && _TIFFFillStriles(tif) && tif->tif_dir.td_stripoffset[0] != 0 && BYTECOUNTLOOKSBAD) { @@ -4332,7 +4469,11 @@ EstimateStripByteCounts(TIFF* tif, TIFFDirEntry* dir, uint16 dircount) } space+=datasize; } - space = filesize - space; + if( filesize < space ) + /* we should perhaps return in error ? */ + space = filesize; + else + space = filesize - space; if (td->td_planarconfig == PLANARCONFIG_SEPARATE) space /= td->td_samplesperpixel; for (strip = 0; strip < td->td_nstrips; strip++) @@ -5399,28 +5540,39 @@ TIFFFetchStripThing(TIFF* tif, TIFFDirEntry* dir, uint32 nstrips, uint64** lpp) static const char module[] = "TIFFFetchStripThing"; enum TIFFReadDirEntryErr err; uint64* data; - err=TIFFReadDirEntryLong8Array(tif,dir,&data); + err=TIFFReadDirEntryLong8ArrayWithLimit(tif,dir,&data,nstrips); if (err!=TIFFReadDirEntryErrOk) { const TIFFField* fip = TIFFFieldWithTag(tif,dir->tdir_tag); TIFFReadDirEntryOutputErr(tif,err,module,fip ? fip->field_name : "unknown tagname",0); return(0); } - if (dir->tdir_count!=(uint64)nstrips) + if (dir->tdir_count<(uint64)nstrips) { uint64* resizeddata; + const TIFFField* fip = TIFFFieldWithTag(tif,dir->tdir_tag); + const char* pszMax = getenv("LIBTIFF_STRILE_ARRAY_MAX_RESIZE_COUNT"); + uint32 max_nstrips = 1000000; + if( pszMax ) + max_nstrips = (uint32) atoi(pszMax); + TIFFReadDirEntryOutputErr(tif,TIFFReadDirEntryErrCount, + module, + fip ? fip->field_name : "unknown tagname", + ( nstrips <= max_nstrips ) ); + + if( nstrips > max_nstrips ) + { + _TIFFfree(data); + return(0); + } + resizeddata=(uint64*)_TIFFCheckMalloc(tif,nstrips,sizeof(uint64),"for strip array"); if (resizeddata==0) { _TIFFfree(data); return(0); } - if (dir->tdir_count<(uint64)nstrips) - { - _TIFFmemcpy(resizeddata,data,(uint32)dir->tdir_count*sizeof(uint64)); - _TIFFmemset(resizeddata+(uint32)dir->tdir_count,0,(nstrips-(uint32)dir->tdir_count)*sizeof(uint64)); - } - else - _TIFFmemcpy(resizeddata,data,nstrips*sizeof(uint64)); + _TIFFmemcpy(resizeddata,data,(uint32)dir->tdir_count*sizeof(uint64)); + _TIFFmemset(resizeddata+(uint32)dir->tdir_count,0,(nstrips-(uint32)dir->tdir_count)*sizeof(uint64)); _TIFFfree(data); data=resizeddata; } @@ -5502,13 +5654,17 @@ ChopUpSingleUncompressedStrip(TIFF* tif) uint64 rowblockbytes; uint64 stripbytes; uint32 strip; - uint64 nstrips64; - uint32 nstrips32; + uint32 nstrips; uint32 rowsperstrip; uint64* newcounts; uint64* newoffsets; bytecount = td->td_stripbytecount[0]; + /* On a newly created file, just re-opened to be filled, we */ + /* don't want strip chop to trigger as it is going to cause issues */ + /* later ( StripOffsets and StripByteCounts improperly filled) . */ + if( bytecount == 0 && tif->tif_mode != O_RDONLY ) + return; offset = td->td_stripoffset[0]; assert(td->td_planarconfig == PLANARCONFIG_CONTIG); if ((td->td_photometric == PHOTOMETRIC_YCBCR)&& @@ -5534,18 +5690,17 @@ ChopUpSingleUncompressedStrip(TIFF* tif) return; /* - * never increase the number of strips in an image + * never increase the number of rows per strip */ if (rowsperstrip >= td->td_rowsperstrip) return; - nstrips64 = TIFFhowmany_64(bytecount, stripbytes); - if ((nstrips64==0)||(nstrips64>0xFFFFFFFF)) /* something is wonky, do nothing. */ - return; - nstrips32 = (uint32)nstrips64; + nstrips = TIFFhowmany_32(td->td_imagelength, rowsperstrip); + if( nstrips == 0 ) + return; - newcounts = (uint64*) _TIFFCheckMalloc(tif, nstrips32, sizeof (uint64), + newcounts = (uint64*) _TIFFCheckMalloc(tif, nstrips, sizeof (uint64), "for chopped \"StripByteCounts\" array"); - newoffsets = (uint64*) _TIFFCheckMalloc(tif, nstrips32, sizeof (uint64), + newoffsets = (uint64*) _TIFFCheckMalloc(tif, nstrips, sizeof (uint64), "for chopped \"StripOffsets\" array"); if (newcounts == NULL || newoffsets == NULL) { /* @@ -5562,18 +5717,18 @@ ChopUpSingleUncompressedStrip(TIFF* tif) * Fill the strip information arrays with new bytecounts and offsets * that reflect the broken-up format. */ - for (strip = 0; strip < nstrips32; strip++) { + for (strip = 0; strip < nstrips; strip++) { if (stripbytes > bytecount) stripbytes = bytecount; newcounts[strip] = stripbytes; - newoffsets[strip] = offset; + newoffsets[strip] = stripbytes ? offset : 0; offset += stripbytes; bytecount -= stripbytes; } /* * Replace old single strip info with multi-strip info. */ - td->td_stripsperimage = td->td_nstrips = nstrips32; + td->td_stripsperimage = td->td_nstrips = nstrips; TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip); _TIFFfree(td->td_stripbytecount); diff --git a/libtiff/tif_dirwrite.c b/libtiff/tif_dirwrite.c index d34f6f6..c68d6d2 100644 --- a/libtiff/tif_dirwrite.c +++ b/libtiff/tif_dirwrite.c @@ -1,4 +1,4 @@ -/* $Id: tif_dirwrite.c,v 1.83 2016-10-25 21:35:15 erouault Exp $ */ +/* $Id: tif_dirwrite.c,v 1.89 2017-08-23 13:33:42 erouault Exp $ */ /* * Copyright (c) 1988-1997 Sam Leffler @@ -30,6 +30,7 @@ * Directory Write Support Routines. */ #include "tiffiop.h" +#include #ifdef HAVE_IEEEFP #define TIFFCvtNativeToIEEEFloat(tif, n, fp) @@ -820,7 +821,12 @@ TIFFWriteDirectorySec(TIFF* tif, int isimage, int imagedone, uint64* pdiroff) TIFFDirEntry* nb; for (na=0, nb=dir; ; na++, nb++) { - assert(natif_clientdata,module, + "Cannot find SubIFD tag"); + goto bad; + } if (nb->tdir_tag==TIFFTAG_SUBIFD) break; } @@ -939,6 +945,69 @@ bad: return(0); } +static float TIFFClampDoubleToFloat( double val ) +{ + if( val > FLT_MAX ) + return FLT_MAX; + if( val < -FLT_MAX ) + return -FLT_MAX; + return (float)val; +} + +static int8 TIFFClampDoubleToInt8( double val ) +{ + if( val > 127 ) + return 127; + if( val < -128 || val != val ) + return -128; + return (int8)val; +} + +static int16 TIFFClampDoubleToInt16( double val ) +{ + if( val > 32767 ) + return 32767; + if( val < -32768 || val != val ) + return -32768; + return (int16)val; +} + +static int32 TIFFClampDoubleToInt32( double val ) +{ + if( val > 0x7FFFFFFF ) + return 0x7FFFFFFF; + if( val < -0x7FFFFFFF-1 || val != val ) + return -0x7FFFFFFF-1; + return (int32)val; +} + +static uint8 TIFFClampDoubleToUInt8( double val ) +{ + if( val < 0 ) + return 0; + if( val > 255 || val != val ) + return 255; + return (uint8)val; +} + +static uint16 TIFFClampDoubleToUInt16( double val ) +{ + if( val < 0 ) + return 0; + if( val > 65535 || val != val ) + return 65535; + return (uint16)val; +} + +static uint32 TIFFClampDoubleToUInt32( double val ) +{ + if( val < 0 ) + return 0; + if( val > 0xFFFFFFFFU || val != val ) + return 0xFFFFFFFFU; + return (uint32)val; +} + static int TIFFWriteDirectoryTagSampleformatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value) { @@ -959,7 +1028,7 @@ TIFFWriteDirectoryTagSampleformatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* di if (tif->tif_dir.td_bitspersample<=32) { for (i = 0; i < count; ++i) - ((float*)conv)[i] = (float)value[i]; + ((float*)conv)[i] = TIFFClampDoubleToFloat(value[i]); ok = TIFFWriteDirectoryTagFloatArray(tif,ndir,dir,tag,count,(float*)conv); } else @@ -971,19 +1040,19 @@ TIFFWriteDirectoryTagSampleformatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* di if (tif->tif_dir.td_bitspersample<=8) { for (i = 0; i < count; ++i) - ((int8*)conv)[i] = (int8)value[i]; + ((int8*)conv)[i] = TIFFClampDoubleToInt8(value[i]); ok = TIFFWriteDirectoryTagSbyteArray(tif,ndir,dir,tag,count,(int8*)conv); } else if (tif->tif_dir.td_bitspersample<=16) { for (i = 0; i < count; ++i) - ((int16*)conv)[i] = (int16)value[i]; + ((int16*)conv)[i] = TIFFClampDoubleToInt16(value[i]); ok = TIFFWriteDirectoryTagSshortArray(tif,ndir,dir,tag,count,(int16*)conv); } else { for (i = 0; i < count; ++i) - ((int32*)conv)[i] = (int32)value[i]; + ((int32*)conv)[i] = TIFFClampDoubleToInt32(value[i]); ok = TIFFWriteDirectoryTagSlongArray(tif,ndir,dir,tag,count,(int32*)conv); } break; @@ -991,19 +1060,19 @@ TIFFWriteDirectoryTagSampleformatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* di if (tif->tif_dir.td_bitspersample<=8) { for (i = 0; i < count; ++i) - ((uint8*)conv)[i] = (uint8)value[i]; + ((uint8*)conv)[i] = TIFFClampDoubleToUInt8(value[i]); ok = TIFFWriteDirectoryTagByteArray(tif,ndir,dir,tag,count,(uint8*)conv); } else if (tif->tif_dir.td_bitspersample<=16) { for (i = 0; i < count; ++i) - ((uint16*)conv)[i] = (uint16)value[i]; + ((uint16*)conv)[i] = TIFFClampDoubleToUInt16(value[i]); ok = TIFFWriteDirectoryTagShortArray(tif,ndir,dir,tag,count,(uint16*)conv); } else { for (i = 0; i < count; ++i) - ((uint32*)conv)[i] = (uint32)value[i]; + ((uint32*)conv)[i] = TIFFClampDoubleToUInt32(value[i]); ok = TIFFWriteDirectoryTagLongArray(tif,ndir,dir,tag,count,(uint32*)conv); } break; @@ -1880,7 +1949,14 @@ TIFFWriteDirectoryTagSubifd(TIFF* tif, uint32* ndir, TIFFDirEntry* dir) for (p=0; p < tif->tif_dir.td_nsubifd; p++) { assert(pa != 0); - assert(*pa <= 0xFFFFFFFFUL); + + /* Could happen if an classicTIFF has a SubIFD of type LONG8 (which is illegal) */ + if( *pa > 0xFFFFFFFFUL) + { + TIFFErrorExt(tif->tif_clientdata,module,"Illegal value for SubIFD tag"); + _TIFFfree(o); + return(0); + } *pb++=(uint32)(*pa++); } n=TIFFWriteDirectoryTagCheckedIfdArray(tif,ndir,dir,TIFFTAG_SUBIFD,tif->tif_dir.td_nsubifd,o); @@ -2047,7 +2123,10 @@ TIFFWriteDirectoryTagCheckedLong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, ui { uint64 m; assert(sizeof(uint64)==8); - assert(tif->tif_flags&TIFF_BIGTIFF); + if( !(tif->tif_flags&TIFF_BIGTIFF) ) { + TIFFErrorExt(tif->tif_clientdata,"TIFFWriteDirectoryTagCheckedLong8","LONG8 not allowed for ClassicTIFF"); + return(0); + } m=value; if (tif->tif_flags&TIFF_SWAB) TIFFSwabLong8(&m); @@ -2060,7 +2139,10 @@ TIFFWriteDirectoryTagCheckedLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* di { assert(count<0x20000000); assert(sizeof(uint64)==8); - assert(tif->tif_flags&TIFF_BIGTIFF); + if( !(tif->tif_flags&TIFF_BIGTIFF) ) { + TIFFErrorExt(tif->tif_clientdata,"TIFFWriteDirectoryTagCheckedLong8Array","LONG8 not allowed for ClassicTIFF"); + return(0); + } if (tif->tif_flags&TIFF_SWAB) TIFFSwabArrayOfLong8(value,count); return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_LONG8,count,count*8,value)); @@ -2072,7 +2154,10 @@ TIFFWriteDirectoryTagCheckedSlong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, u { int64 m; assert(sizeof(int64)==8); - assert(tif->tif_flags&TIFF_BIGTIFF); + if( !(tif->tif_flags&TIFF_BIGTIFF) ) { + TIFFErrorExt(tif->tif_clientdata,"TIFFWriteDirectoryTagCheckedSlong8","SLONG8 not allowed for ClassicTIFF"); + return(0); + } m=value; if (tif->tif_flags&TIFF_SWAB) TIFFSwabLong8((uint64*)(&m)); @@ -2085,7 +2170,10 @@ TIFFWriteDirectoryTagCheckedSlong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* d { assert(count<0x20000000); assert(sizeof(int64)==8); - assert(tif->tif_flags&TIFF_BIGTIFF); + if( !(tif->tif_flags&TIFF_BIGTIFF) ) { + TIFFErrorExt(tif->tif_clientdata,"TIFFWriteDirectoryTagCheckedSlong8Array","SLONG8 not allowed for ClassicTIFF"); + return(0); + } if (tif->tif_flags&TIFF_SWAB) TIFFSwabArrayOfLong8((uint64*)value,count); return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SLONG8,count,count*8,value)); @@ -2094,15 +2182,25 @@ TIFFWriteDirectoryTagCheckedSlong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* d static int TIFFWriteDirectoryTagCheckedRational(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value) { + static const char module[] = "TIFFWriteDirectoryTagCheckedRational"; uint32 m[2]; - assert(value>=0.0); assert(sizeof(uint32)==4); - if (value<=0.0) + if( value < 0 ) + { + TIFFErrorExt(tif->tif_clientdata,module,"Negative value is illegal"); + return 0; + } + else if( value != value ) + { + TIFFErrorExt(tif->tif_clientdata,module,"Not-a-number value is illegal"); + return 0; + } + else if (value==0.0) { m[0]=0; m[1]=1; } - else if (value==(double)(uint32)value) + else if (value <= 0xFFFFFFFFU && value==(double)(uint32)value) { m[0]=(uint32)value; m[1]=1; @@ -2143,12 +2241,13 @@ TIFFWriteDirectoryTagCheckedRationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* } for (na=value, nb=m, nc=0; nc= 0 && *na <= (float)0xFFFFFFFFU && + *na==(float)(uint32)(*na)) { nb[0]=(uint32)(*na); nb[1]=1; diff --git a/libtiff/tif_error.c b/libtiff/tif_error.c index 0bc8b87..47516b4 100644 --- a/libtiff/tif_error.c +++ b/libtiff/tif_error.c @@ -1,4 +1,4 @@ -/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_error.c,v 1.5 2010-03-10 18:56:48 bfriesen Exp $ */ +/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_error.c,v 1.6 2017-07-04 12:54:42 erouault Exp $ */ /* * Copyright (c) 1988-1997 Sam Leffler @@ -51,24 +51,32 @@ void TIFFError(const char* module, const char* fmt, ...) { va_list ap; - va_start(ap, fmt); - if (_TIFFerrorHandler) + if (_TIFFerrorHandler) { + va_start(ap, fmt); (*_TIFFerrorHandler)(module, fmt, ap); - if (_TIFFerrorHandlerExt) + va_end(ap); + } + if (_TIFFerrorHandlerExt) { + va_start(ap, fmt); (*_TIFFerrorHandlerExt)(0, module, fmt, ap); - va_end(ap); + va_end(ap); + } } void TIFFErrorExt(thandle_t fd, const char* module, const char* fmt, ...) { va_list ap; - va_start(ap, fmt); - if (_TIFFerrorHandler) + if (_TIFFerrorHandler) { + va_start(ap, fmt); (*_TIFFerrorHandler)(module, fmt, ap); - if (_TIFFerrorHandlerExt) + va_end(ap); + } + if (_TIFFerrorHandlerExt) { + va_start(ap, fmt); (*_TIFFerrorHandlerExt)(fd, module, fmt, ap); - va_end(ap); + va_end(ap); + } } /* diff --git a/libtiff/tif_fax3.c b/libtiff/tif_fax3.c index 16bb4d3..5fd5141 100644 --- a/libtiff/tif_fax3.c +++ b/libtiff/tif_fax3.c @@ -1,4 +1,4 @@ -/* $Id: tif_fax3.c,v 1.78 2016-09-04 21:32:56 erouault Exp $ */ +/* $Id: tif_fax3.c,v 1.81 2017-06-18 10:31:50 erouault Exp $ */ /* * Copyright (c) 1990-1997 Sam Leffler @@ -329,34 +329,64 @@ Fax3Decode2D(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s) #if SIZEOF_UNSIGNED_LONG == 8 # define FILL(n, cp) \ switch (n) { \ - case 15:(cp)[14] = 0xff; case 14:(cp)[13] = 0xff; case 13: (cp)[12] = 0xff;\ - case 12:(cp)[11] = 0xff; case 11:(cp)[10] = 0xff; case 10: (cp)[9] = 0xff;\ - case 9: (cp)[8] = 0xff; case 8: (cp)[7] = 0xff; case 7: (cp)[6] = 0xff;\ - case 6: (cp)[5] = 0xff; case 5: (cp)[4] = 0xff; case 4: (cp)[3] = 0xff;\ - case 3: (cp)[2] = 0xff; case 2: (cp)[1] = 0xff; \ - case 1: (cp)[0] = 0xff; (cp) += (n); case 0: ; \ + case 15:(cp)[14] = 0xff; /*-fallthrough*/ \ + case 14:(cp)[13] = 0xff; /*-fallthrough*/ \ + case 13:(cp)[12] = 0xff; /*-fallthrough*/ \ + case 12:(cp)[11] = 0xff; /*-fallthrough*/ \ + case 11:(cp)[10] = 0xff; /*-fallthrough*/ \ + case 10: (cp)[9] = 0xff; /*-fallthrough*/ \ + case 9: (cp)[8] = 0xff; /*-fallthrough*/ \ + case 8: (cp)[7] = 0xff; /*-fallthrough*/ \ + case 7: (cp)[6] = 0xff; /*-fallthrough*/ \ + case 6: (cp)[5] = 0xff; /*-fallthrough*/ \ + case 5: (cp)[4] = 0xff; /*-fallthrough*/ \ + case 4: (cp)[3] = 0xff; /*-fallthrough*/ \ + case 3: (cp)[2] = 0xff; /*-fallthrough*/ \ + case 2: (cp)[1] = 0xff; /*-fallthrough*/ \ + case 1: (cp)[0] = 0xff; (cp) += (n); /*-fallthrough*/ \ + case 0: ; \ } # define ZERO(n, cp) \ switch (n) { \ - case 15:(cp)[14] = 0; case 14:(cp)[13] = 0; case 13: (cp)[12] = 0; \ - case 12:(cp)[11] = 0; case 11:(cp)[10] = 0; case 10: (cp)[9] = 0; \ - case 9: (cp)[8] = 0; case 8: (cp)[7] = 0; case 7: (cp)[6] = 0; \ - case 6: (cp)[5] = 0; case 5: (cp)[4] = 0; case 4: (cp)[3] = 0; \ - case 3: (cp)[2] = 0; case 2: (cp)[1] = 0; \ - case 1: (cp)[0] = 0; (cp) += (n); case 0: ; \ + case 15:(cp)[14] = 0; /*-fallthrough*/ \ + case 14:(cp)[13] = 0; /*-fallthrough*/ \ + case 13:(cp)[12] = 0; /*-fallthrough*/ \ + case 12:(cp)[11] = 0; /*-fallthrough*/ \ + case 11:(cp)[10] = 0; /*-fallthrough*/ \ + case 10: (cp)[9] = 0; /*-fallthrough*/ \ + case 9: (cp)[8] = 0; /*-fallthrough*/ \ + case 8: (cp)[7] = 0; /*-fallthrough*/ \ + case 7: (cp)[6] = 0; /*-fallthrough*/ \ + case 6: (cp)[5] = 0; /*-fallthrough*/ \ + case 5: (cp)[4] = 0; /*-fallthrough*/ \ + case 4: (cp)[3] = 0; /*-fallthrough*/ \ + case 3: (cp)[2] = 0; /*-fallthrough*/ \ + case 2: (cp)[1] = 0; /*-fallthrough*/ \ + case 1: (cp)[0] = 0; (cp) += (n); /*-fallthrough*/ \ + case 0: ; \ } #else # define FILL(n, cp) \ switch (n) { \ - case 7: (cp)[6] = 0xff; case 6: (cp)[5] = 0xff; case 5: (cp)[4] = 0xff; \ - case 4: (cp)[3] = 0xff; case 3: (cp)[2] = 0xff; case 2: (cp)[1] = 0xff; \ - case 1: (cp)[0] = 0xff; (cp) += (n); case 0: ; \ + case 7: (cp)[6] = 0xff; /*-fallthrough*/ \ + case 6: (cp)[5] = 0xff; /*-fallthrough*/ \ + case 5: (cp)[4] = 0xff; /*-fallthrough*/ \ + case 4: (cp)[3] = 0xff; /*-fallthrough*/ \ + case 3: (cp)[2] = 0xff; /*-fallthrough*/ \ + case 2: (cp)[1] = 0xff; /*-fallthrough*/ \ + case 1: (cp)[0] = 0xff; (cp) += (n); /*-fallthrough*/ \ + case 0: ; \ } # define ZERO(n, cp) \ switch (n) { \ - case 7: (cp)[6] = 0; case 6: (cp)[5] = 0; case 5: (cp)[4] = 0; \ - case 4: (cp)[3] = 0; case 3: (cp)[2] = 0; case 2: (cp)[1] = 0; \ - case 1: (cp)[0] = 0; (cp) += (n); case 0: ; \ + case 7: (cp)[6] = 0; /*-fallthrough*/ \ + case 6: (cp)[5] = 0; /*-fallthrough*/ \ + case 5: (cp)[4] = 0; /*-fallthrough*/ \ + case 4: (cp)[3] = 0; /*-fallthrough*/ \ + case 3: (cp)[2] = 0; /*-fallthrough*/ \ + case 2: (cp)[1] = 0; /*-fallthrough*/ \ + case 1: (cp)[0] = 0; (cp) += (n); /*-fallthrough*/ \ + case 0: ; \ } #endif @@ -1013,7 +1043,11 @@ Fax3Encode2DRow(TIFF* tif, unsigned char* bp, unsigned char* rp, uint32 bits) for (;;) { b2 = finddiff2(rp, b1, bits, PIXEL(rp,b1)); if (b2 >= a1) { - int32 d = b1 - a1; + /* Naive computation triggers -fsanitize=undefined,unsigned-integer-overflow */ + /* although it is correct unless the difference between both is < 31 bit */ + /* int32 d = b1 - a1; */ + int32 d = (b1 >= a1 && b1 - a1 <= 3U) ? (int32)(b1 - a1): + (b1 < a1 && a1 - b1 <= 3U) ? -(int32)(a1 - b1) : 0x7FFFFFFF; if (!(-3 <= d && d <= 3)) { /* horizontal mode */ a2 = finddiff2(bp, a1, bits, PIXEL(bp,a1)); putcode(tif, &horizcode); @@ -1099,7 +1133,7 @@ Fax3PostEncode(TIFF* tif) static void Fax3Close(TIFF* tif) { - if ((Fax3State(tif)->mode & FAXMODE_NORTC) == 0) { + if ((Fax3State(tif)->mode & FAXMODE_NORTC) == 0 && tif->tif_rawcp) { Fax3CodecState* sp = EncoderState(tif); unsigned int code = EOL; unsigned int length = 12; @@ -1321,6 +1355,7 @@ InitCCITTFax3(TIFF* tif) "No space for state block"); return (0); } + _TIFFmemset(tif->tif_data, 0, sizeof (Fax3CodecState)); sp = Fax3State(tif); sp->rw_mode = tif->tif_mode; diff --git a/libtiff/tif_fax3.h b/libtiff/tif_fax3.h index e0b2ca6..8a43505 100644 --- a/libtiff/tif_fax3.h +++ b/libtiff/tif_fax3.h @@ -1,4 +1,4 @@ -/* $Id: tif_fax3.h,v 1.11 2016-01-23 21:20:34 erouault Exp $ */ +/* $Id: tif_fax3.h,v 1.13 2016-12-14 18:36:27 faxguy Exp $ */ /* * Copyright (c) 1990-1997 Sam Leffler @@ -81,10 +81,12 @@ extern void _TIFFFax3fillruns(unsigned char*, uint32*, uint32*, uint32); #define S_MakeUp 11 #define S_EOL 12 +/* WARNING: do not change the layout of this structure as the HylaFAX software */ +/* really depends on it. See http://bugzilla.maptools.org/show_bug.cgi?id=2636 */ typedef struct { /* state table entry */ unsigned char State; /* see above */ unsigned char Width; /* width of code in bits */ - uint16 Param; /* unsigned 16-bit run length in bits */ + uint32 Param; /* unsigned 32-bit run length in bits (holds on 16 bit actually, but cannot be changed. See above warning) */ } TIFFFaxTabEnt; extern const TIFFFaxTabEnt TIFFFaxMainTable[]; diff --git a/libtiff/tif_getimage.c b/libtiff/tif_getimage.c index 0f5e932..fc554cc 100644 --- a/libtiff/tif_getimage.c +++ b/libtiff/tif_getimage.c @@ -1,4 +1,4 @@ -/* $Id: tif_getimage.c,v 1.98 2016-11-18 02:47:45 bfriesen Exp $ */ +/* $Id: tif_getimage.c,v 1.114 2017-11-17 20:21:00 erouault Exp $ */ /* * Copyright (c) 1991-1997 Sam Leffler @@ -138,7 +138,7 @@ TIFFRGBAImageOK(TIFF* tif, char emsg[1024]) /* * TODO: if at all meaningful and useful, make more complete * support check here, or better still, refactor to let supporting - * code decide whether there is support and what meaningfull + * code decide whether there is support and what meaningful * error to return */ break; @@ -283,6 +283,13 @@ TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int stop, char emsg[1024]) img->redcmap = NULL; img->greencmap = NULL; img->bluecmap = NULL; + img->Map = NULL; + img->BWmap = NULL; + img->PALmap = NULL; + img->ycbcr = NULL; + img->cielab = NULL; + img->UaToAa = NULL; + img->Bitdepth16To8 = NULL; img->req_orientation = ORIENTATION_BOTLEFT; /* It is the default */ img->tif = tif; @@ -409,7 +416,7 @@ TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int stop, char emsg[1024]) /* * TODO: if at all meaningful and useful, make more complete * support check here, or better still, refactor to let supporting - * code decide whether there is support and what meaningfull + * code decide whether there is support and what meaningful * error to return */ break; @@ -468,13 +475,6 @@ TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int stop, char emsg[1024]) photoTag, img->photometric); goto fail_return; } - img->Map = NULL; - img->BWmap = NULL; - img->PALmap = NULL; - img->ycbcr = NULL; - img->cielab = NULL; - img->UaToAa = NULL; - img->Bitdepth16To8 = NULL; TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &img->width); TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &img->height); TIFFGetFieldDefaulted(tif, TIFFTAG_ORIENTATION, &img->orientation); @@ -494,10 +494,7 @@ TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int stop, char emsg[1024]) return 1; fail_return: - _TIFFfree( img->redcmap ); - _TIFFfree( img->greencmap ); - _TIFFfree( img->bluecmap ); - img->redcmap = img->greencmap = img->bluecmap = NULL; + TIFFRGBAImageEnd( img ); return 0; } @@ -629,7 +626,7 @@ gtTileContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) uint32 col, row, y, rowstoread; tmsize_t pos; uint32 tw, th; - unsigned char* buf; + unsigned char* buf = NULL; int32 fromskew, toskew; uint32 nrow; int ret = 1, flip; @@ -637,13 +634,14 @@ gtTileContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) int32 this_toskew, leftmost_toskew; int32 leftmost_fromskew; uint32 leftmost_tw; + tmsize_t bufsize; - buf = (unsigned char*) _TIFFmalloc(TIFFTileSize(tif)); - if (buf == 0) { - TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", "No space for tile buffer"); - return (0); + bufsize = TIFFTileSize(tif); + if (bufsize == 0) { + TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", "No space for tile buffer"); + return (0); } - _TIFFmemset(buf, 0, TIFFTileSize(tif)); + TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw); TIFFGetField(tif, TIFFTAG_TILELENGTH, &th); @@ -663,7 +661,7 @@ gtTileContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) leftmost_fromskew = img->col_offset % tw; leftmost_tw = tw - leftmost_fromskew; leftmost_toskew = toskew + leftmost_fromskew; - for (row = 0; row < h; row += nrow) + for (row = 0; ret != 0 && row < h; row += nrow) { rowstoread = th - (row + img->row_offset) % th; nrow = (row + rowstoread > h ? h - row : rowstoread); @@ -674,8 +672,9 @@ gtTileContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) col = img->col_offset; while (tocol < w) { - if (TIFFReadTile(tif, buf, col, - row+img->row_offset, 0, 0)==(tmsize_t)(-1) && img->stoponerr) + if (_TIFFReadTileAndAllocBuffer(tif, (void**) &buf, bufsize, col, + row+img->row_offset, 0, 0)==(tmsize_t)(-1) && + (buf == NULL || img->stoponerr)) { ret = 0; break; @@ -702,7 +701,7 @@ gtTileContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) this_toskew = toskew; } - y += (flip & FLIP_VERTICALLY ? -(int32) nrow : (int32) nrow); + y += ((flip & FLIP_VERTICALLY) ? -(int32) nrow : (int32) nrow); } _TIFFfree(buf); @@ -740,11 +739,11 @@ gtTileSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) uint32 col, row, y, rowstoread; tmsize_t pos; uint32 tw, th; - unsigned char* buf; - unsigned char* p0; - unsigned char* p1; - unsigned char* p2; - unsigned char* pa; + unsigned char* buf = NULL; + unsigned char* p0 = NULL; + unsigned char* p1 = NULL; + unsigned char* p2 = NULL; + unsigned char* pa = NULL; tmsize_t tilesize; tmsize_t bufsize; int32 fromskew, toskew; @@ -763,16 +762,7 @@ gtTileSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Integer overflow in %s", "gtTileSeparate"); return (0); } - buf = (unsigned char*) _TIFFmalloc(bufsize); - if (buf == 0) { - TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", "No space for tile buffer"); - return (0); - } - _TIFFmemset(buf, 0, bufsize); - p0 = buf; - p1 = p0 + tilesize; - p2 = p1 + tilesize; - pa = (alpha?(p2+tilesize):NULL); + TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw); TIFFGetField(tif, TIFFTAG_TILELENGTH, &th); @@ -792,7 +782,6 @@ gtTileSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) case PHOTOMETRIC_MINISBLACK: case PHOTOMETRIC_PALETTE: colorchannels = 1; - p2 = p1 = p0; break; default: @@ -806,7 +795,7 @@ gtTileSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) leftmost_fromskew = img->col_offset % tw; leftmost_tw = tw - leftmost_fromskew; leftmost_toskew = toskew + leftmost_fromskew; - for (row = 0; row < h; row += nrow) + for (row = 0; ret != 0 && row < h; row += nrow) { rowstoread = th - (row + img->row_offset) % th; nrow = (row + rowstoread > h ? h - row : rowstoread); @@ -817,7 +806,30 @@ gtTileSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) col = img->col_offset; while (tocol < w) { - if (TIFFReadTile(tif, p0, col, + if( buf == NULL ) + { + if (_TIFFReadTileAndAllocBuffer( + tif, (void**) &buf, bufsize, col, + row+img->row_offset,0,0)==(tmsize_t)(-1) + && (buf == NULL || img->stoponerr)) + { + ret = 0; + break; + } + p0 = buf; + if( colorchannels == 1 ) + { + p2 = p1 = p0; + pa = (alpha?(p0+3*tilesize):NULL); + } + else + { + p1 = p0 + tilesize; + p2 = p1 + tilesize; + pa = (alpha?(p2+tilesize):NULL); + } + } + else if (TIFFReadTile(tif, p0, col, row+img->row_offset,0,0)==(tmsize_t)(-1) && img->stoponerr) { ret = 0; @@ -871,7 +883,7 @@ gtTileSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) this_toskew = toskew; } - y += (flip & FLIP_VERTICALLY ?-(int32) nrow : (int32) nrow); + y += ((flip & FLIP_VERTICALLY) ?-(int32) nrow : (int32) nrow); } if (flip & FLIP_HORIZONTALLY) { @@ -908,26 +920,22 @@ gtStripContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) tileContigRoutine put = img->put.contig; uint32 row, y, nrow, nrowsub, rowstoread; tmsize_t pos; - unsigned char* buf; + unsigned char* buf = NULL; uint32 rowsperstrip; uint16 subsamplinghor,subsamplingver; uint32 imagewidth = img->width; tmsize_t scanline; int32 fromskew, toskew; int ret = 1, flip; + tmsize_t maxstripsize; TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING, &subsamplinghor, &subsamplingver); if( subsamplingver == 0 ) { TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Invalid vertical YCbCr subsampling"); return (0); } - - buf = (unsigned char*) _TIFFmalloc(TIFFStripSize(tif)); - if (buf == 0) { - TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "No space for strip buffer"); - return (0); - } - _TIFFmemset(buf, 0, TIFFStripSize(tif)); + + maxstripsize = TIFFStripSize(tif); flip = setorientation(img); if (flip & FLIP_VERTICALLY) { @@ -949,11 +957,12 @@ gtStripContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) nrowsub = nrow; if ((nrowsub%subsamplingver)!=0) nrowsub+=subsamplingver-nrowsub%subsamplingver; - if (TIFFReadEncodedStrip(tif, + if (_TIFFReadEncodedStripAndAllocBuffer(tif, TIFFComputeStrip(tif,row+img->row_offset, 0), - buf, + (void**)(&buf), + maxstripsize, ((row + img->row_offset)%rowsperstrip + nrowsub) * scanline)==(tmsize_t)(-1) - && img->stoponerr) + && (buf == NULL || img->stoponerr)) { ret = 0; break; @@ -962,7 +971,7 @@ gtStripContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) pos = ((row + img->row_offset) % rowsperstrip) * scanline + \ ((tmsize_t) img->col_offset * img->samplesperpixel); (*put)(img, raster+y*w, 0, y, w, nrow, fromskew, toskew, buf + pos); - y += (flip & FLIP_VERTICALLY ? -(int32) nrow : (int32) nrow); + y += ((flip & FLIP_VERTICALLY) ? -(int32) nrow : (int32) nrow); } if (flip & FLIP_HORIZONTALLY) { @@ -997,8 +1006,8 @@ gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) { TIFF* tif = img->tif; tileSeparateRoutine put = img->put.separate; - unsigned char *buf; - unsigned char *p0, *p1, *p2, *pa; + unsigned char *buf = NULL; + unsigned char *p0 = NULL, *p1 = NULL, *p2 = NULL, *pa = NULL; uint32 row, y, nrow, rowstoread; tmsize_t pos; tmsize_t scanline; @@ -1017,15 +1026,6 @@ gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Integer overflow in %s", "gtStripSeparate"); return (0); } - p0 = buf = (unsigned char *)_TIFFmalloc(bufsize); - if (buf == 0) { - TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "No space for tile buffer"); - return (0); - } - _TIFFmemset(buf, 0, bufsize); - p1 = p0 + stripsize; - p2 = p1 + stripsize; - pa = (alpha?(p2+stripsize):NULL); flip = setorientation(img); if (flip & FLIP_VERTICALLY) { @@ -1043,7 +1043,6 @@ gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) case PHOTOMETRIC_MINISBLACK: case PHOTOMETRIC_PALETTE: colorchannels = 1; - p2 = p1 = p0; break; default: @@ -1059,7 +1058,31 @@ gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) rowstoread = rowsperstrip - (row + img->row_offset) % rowsperstrip; nrow = (row + rowstoread > h ? h - row : rowstoread); offset_row = row + img->row_offset; - if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 0), + if( buf == NULL ) + { + if (_TIFFReadEncodedStripAndAllocBuffer( + tif, TIFFComputeStrip(tif, offset_row, 0), + (void**) &buf, bufsize, + ((row + img->row_offset)%rowsperstrip + nrow) * scanline)==(tmsize_t)(-1) + && (buf == NULL || img->stoponerr)) + { + ret = 0; + break; + } + p0 = buf; + if( colorchannels == 1 ) + { + p2 = p1 = p0; + pa = (alpha?(p0+3*stripsize):NULL); + } + else + { + p1 = p0 + stripsize; + p2 = p1 + stripsize; + pa = (alpha?(p2+stripsize):NULL); + } + } + else if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 0), p0, ((row + img->row_offset)%rowsperstrip + nrow) * scanline)==(tmsize_t)(-1) && img->stoponerr) { @@ -1097,7 +1120,7 @@ gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) ((tmsize_t) img->col_offset * img->samplesperpixel); (*put)(img, raster+y*w, 0, y, w, nrow, fromskew, toskew, p0 + pos, p1 + pos, p2 + pos, (alpha?(pa+pos):NULL)); - y += (flip & FLIP_VERTICALLY ? -(int32) nrow : (int32) nrow); + y += ((flip & FLIP_VERTICALLY) ? -(int32) nrow : (int32) nrow); } if (flip & FLIP_HORIZONTALLY) { @@ -1136,11 +1159,15 @@ gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) #define REPEAT2(op) op; op #define CASE8(x,op) \ switch (x) { \ - case 7: op; case 6: op; case 5: op; \ - case 4: op; case 3: op; case 2: op; \ + case 7: op; /*-fallthrough*/ \ + case 6: op; /*-fallthrough*/ \ + case 5: op; /*-fallthrough*/ \ + case 4: op; /*-fallthrough*/ \ + case 3: op; /*-fallthrough*/ \ + case 2: op; /*-fallthrough*/ \ case 1: op; \ } -#define CASE4(x,op) switch (x) { case 3: op; case 2: op; case 1: op; } +#define CASE4(x,op) switch (x) { case 3: op; /*-fallthrough*/ case 2: op; /*-fallthrough*/ case 1: op; } #define NOP #define UNROLL8(w, op1, op2) { \ @@ -1211,8 +1238,8 @@ DECLAREContigPutFunc(put8bitcmaptile) int samplesperpixel = img->samplesperpixel; (void) y; - while (h-- > 0) { - for (x = w; x-- > 0;) + for( ; h > 0; --h) { + for (x = w; x > 0; --x) { *cp++ = PALmap[*pp][0]; pp += samplesperpixel; @@ -1231,7 +1258,7 @@ DECLAREContigPutFunc(put4bitcmaptile) (void) x; (void) y; fromskew /= 2; - while (h-- > 0) { + for( ; h > 0; --h) { uint32* bw; UNROLL2(w, bw = PALmap[*pp++], *cp++ = *bw++); cp += toskew; @@ -1248,7 +1275,7 @@ DECLAREContigPutFunc(put2bitcmaptile) (void) x; (void) y; fromskew /= 4; - while (h-- > 0) { + for( ; h > 0; --h) { uint32* bw; UNROLL4(w, bw = PALmap[*pp++], *cp++ = *bw++); cp += toskew; @@ -1265,7 +1292,7 @@ DECLAREContigPutFunc(put1bitcmaptile) (void) x; (void) y; fromskew /= 8; - while (h-- > 0) { + for( ; h > 0; --h) { uint32* bw; UNROLL8(w, bw = PALmap[*pp++], *cp++ = *bw++); cp += toskew; @@ -1282,8 +1309,8 @@ DECLAREContigPutFunc(putgreytile) uint32** BWmap = img->BWmap; (void) y; - while (h-- > 0) { - for (x = w; x-- > 0;) + for( ; h > 0; --h) { + for (x = w; x > 0; --x) { *cp++ = BWmap[*pp][0]; pp += samplesperpixel; @@ -1302,10 +1329,10 @@ DECLAREContigPutFunc(putagreytile) uint32** BWmap = img->BWmap; (void) y; - while (h-- > 0) { - for (x = w; x-- > 0;) + for( ; h > 0; --h) { + for (x = w; x > 0; --x) { - *cp++ = BWmap[*pp][0] & (*(pp+1) << 24 | ~A1); + *cp++ = BWmap[*pp][0] & ((uint32)*(pp+1) << 24 | ~A1); pp += samplesperpixel; } cp += toskew; @@ -1322,10 +1349,10 @@ DECLAREContigPutFunc(put16bitbwtile) uint32** BWmap = img->BWmap; (void) y; - while (h-- > 0) { + for( ; h > 0; --h) { uint16 *wp = (uint16 *) pp; - for (x = w; x-- > 0;) + for (x = w; x > 0; --x) { /* use high order byte of 16bit value */ @@ -1347,7 +1374,7 @@ DECLAREContigPutFunc(put1bitbwtile) (void) x; (void) y; fromskew /= 8; - while (h-- > 0) { + for( ; h > 0; --h) { uint32* bw; UNROLL8(w, bw = BWmap[*pp++], *cp++ = *bw++); cp += toskew; @@ -1364,7 +1391,7 @@ DECLAREContigPutFunc(put2bitbwtile) (void) x; (void) y; fromskew /= 4; - while (h-- > 0) { + for( ; h > 0; --h) { uint32* bw; UNROLL4(w, bw = BWmap[*pp++], *cp++ = *bw++); cp += toskew; @@ -1381,7 +1408,7 @@ DECLAREContigPutFunc(put4bitbwtile) (void) x; (void) y; fromskew /= 2; - while (h-- > 0) { + for( ; h > 0; --h) { uint32* bw; UNROLL2(w, bw = BWmap[*pp++], *cp++ = *bw++); cp += toskew; @@ -1398,7 +1425,7 @@ DECLAREContigPutFunc(putRGBcontig8bittile) (void) x; (void) y; fromskew *= samplesperpixel; - while (h-- > 0) { + for( ; h > 0; --h) { UNROLL8(w, NOP, *cp++ = PACK(pp[0], pp[1], pp[2]); pp += samplesperpixel); @@ -1417,7 +1444,7 @@ DECLAREContigPutFunc(putRGBAAcontig8bittile) (void) x; (void) y; fromskew *= samplesperpixel; - while (h-- > 0) { + for( ; h > 0; --h) { UNROLL8(w, NOP, *cp++ = PACK4(pp[0], pp[1], pp[2], pp[3]); pp += samplesperpixel); @@ -1435,10 +1462,10 @@ DECLAREContigPutFunc(putRGBUAcontig8bittile) int samplesperpixel = img->samplesperpixel; (void) y; fromskew *= samplesperpixel; - while (h-- > 0) { + for( ; h > 0; --h) { uint32 r, g, b, a; uint8* m; - for (x = w; x-- > 0;) { + for (x = w; x > 0; --x) { a = pp[3]; m = img->UaToAa+((size_t) a<<8); r = m[pp[0]]; @@ -1461,8 +1488,8 @@ DECLAREContigPutFunc(putRGBcontig16bittile) uint16 *wp = (uint16 *)pp; (void) y; fromskew *= samplesperpixel; - while (h-- > 0) { - for (x = w; x-- > 0;) { + for( ; h > 0; --h) { + for (x = w; x > 0; --x) { *cp++ = PACK(img->Bitdepth16To8[wp[0]], img->Bitdepth16To8[wp[1]], img->Bitdepth16To8[wp[2]]); @@ -1483,8 +1510,8 @@ DECLAREContigPutFunc(putRGBAAcontig16bittile) uint16 *wp = (uint16 *)pp; (void) y; fromskew *= samplesperpixel; - while (h-- > 0) { - for (x = w; x-- > 0;) { + for( ; h > 0; --h) { + for (x = w; x > 0; --x) { *cp++ = PACK4(img->Bitdepth16To8[wp[0]], img->Bitdepth16To8[wp[1]], img->Bitdepth16To8[wp[2]], @@ -1506,10 +1533,10 @@ DECLAREContigPutFunc(putRGBUAcontig16bittile) uint16 *wp = (uint16 *)pp; (void) y; fromskew *= samplesperpixel; - while (h-- > 0) { + for( ; h > 0; --h) { uint32 r,g,b,a; uint8* m; - for (x = w; x-- > 0;) { + for (x = w; x > 0; --x) { a = img->Bitdepth16To8[wp[3]]; m = img->UaToAa+((size_t) a<<8); r = m[img->Bitdepth16To8[wp[0]]]; @@ -1535,7 +1562,7 @@ DECLAREContigPutFunc(putRGBcontig8bitCMYKtile) (void) x; (void) y; fromskew *= samplesperpixel; - while (h-- > 0) { + for( ; h > 0; --h) { UNROLL8(w, NOP, k = 255 - pp[3]; r = (k*(255-pp[0]))/255; @@ -1561,8 +1588,8 @@ DECLAREContigPutFunc(putRGBcontig8bitCMYKMaptile) (void) y; fromskew *= samplesperpixel; - while (h-- > 0) { - for (x = w; x-- > 0;) { + for( ; h > 0; --h) { + for (x = w; x > 0; --x) { k = 255 - pp[3]; r = (k*(255-pp[0]))/255; g = (k*(255-pp[1]))/255; @@ -1591,7 +1618,7 @@ static void name(\ DECLARESepPutFunc(putRGBseparate8bittile) { (void) img; (void) x; (void) y; (void) a; - while (h-- > 0) { + for( ; h > 0; --h) { UNROLL8(w, NOP, *cp++ = PACK(*r++, *g++, *b++)); SKEW(r, g, b, fromskew); cp += toskew; @@ -1604,7 +1631,7 @@ DECLARESepPutFunc(putRGBseparate8bittile) DECLARESepPutFunc(putRGBAAseparate8bittile) { (void) img; (void) x; (void) y; - while (h-- > 0) { + for( ; h > 0; --h) { UNROLL8(w, NOP, *cp++ = PACK4(*r++, *g++, *b++, *a++)); SKEW4(r, g, b, a, fromskew); cp += toskew; @@ -1617,9 +1644,9 @@ DECLARESepPutFunc(putRGBAAseparate8bittile) DECLARESepPutFunc(putCMYKseparate8bittile) { (void) img; (void) y; - while (h-- > 0) { + for( ; h > 0; --h) { uint32 rv, gv, bv, kv; - for (x = w; x-- > 0;) { + for (x = w; x > 0; --x) { kv = 255 - *a++; rv = (kv*(255-*r++))/255; gv = (kv*(255-*g++))/255; @@ -1637,10 +1664,10 @@ DECLARESepPutFunc(putCMYKseparate8bittile) DECLARESepPutFunc(putRGBUAseparate8bittile) { (void) img; (void) y; - while (h-- > 0) { + for( ; h > 0; --h) { uint32 rv, gv, bv, av; uint8* m; - for (x = w; x-- > 0;) { + for (x = w; x > 0; --x) { av = *a++; m = img->UaToAa+((size_t) av<<8); rv = m[*r++]; @@ -1662,7 +1689,7 @@ DECLARESepPutFunc(putRGBseparate16bittile) uint16 *wg = (uint16*) g; uint16 *wb = (uint16*) b; (void) img; (void) y; (void) a; - while (h-- > 0) { + for( ; h > 0; --h) { for (x = 0; x < w; x++) *cp++ = PACK(img->Bitdepth16To8[*wr++], img->Bitdepth16To8[*wg++], @@ -1682,7 +1709,7 @@ DECLARESepPutFunc(putRGBAAseparate16bittile) uint16 *wb = (uint16*) b; uint16 *wa = (uint16*) a; (void) img; (void) y; - while (h-- > 0) { + for( ; h > 0; --h) { for (x = 0; x < w; x++) *cp++ = PACK4(img->Bitdepth16To8[*wr++], img->Bitdepth16To8[*wg++], @@ -1703,10 +1730,10 @@ DECLARESepPutFunc(putRGBUAseparate16bittile) uint16 *wb = (uint16*) b; uint16 *wa = (uint16*) a; (void) img; (void) y; - while (h-- > 0) { + for( ; h > 0; --h) { uint32 r2,g2,b2,a2; uint8* m; - for (x = w; x-- > 0;) { + for (x = w; x > 0; --x) { a2 = img->Bitdepth16To8[*wa++]; m = img->UaToAa+((size_t) a2<<8); r2 = m[img->Bitdepth16To8[*wr++]]; @@ -1728,8 +1755,8 @@ DECLAREContigPutFunc(putcontig8bitCIELab) uint32 r, g, b; (void) y; fromskew *= 3; - while (h-- > 0) { - for (x = w; x-- > 0;) { + for( ; h > 0; --h) { + for (x = w; x > 0; --x) { TIFFCIELabToXYZ(img->cielab, (unsigned char)pp[0], (signed char)pp[1], @@ -1842,7 +1869,7 @@ DECLAREContigPutFunc(putcontig8bitYCbCr44tile) (void) y; /* adjust fromskew */ - fromskew = (fromskew * 18) / 4; + fromskew = (fromskew / 4) * (4*2+2); if ((h & 3) == 0 && (w & 3) == 0) { for (; h >= 4; h -= 4) { x = w>>2; @@ -1945,7 +1972,7 @@ DECLAREContigPutFunc(putcontig8bitYCbCr42tile) int32 incr = 2*toskew+w; (void) y; - fromskew = (fromskew * 10) / 4; + fromskew = (fromskew / 4) * (4*2+2); if ((w & 3) == 0 && (h & 1) == 0) { for (; h >= 2; h -= 2) { x = w>>2; @@ -2023,7 +2050,7 @@ DECLAREContigPutFunc(putcontig8bitYCbCr42tile) DECLAREContigPutFunc(putcontig8bitYCbCr41tile) { (void) y; - /* XXX adjust fromskew */ + fromskew = (fromskew / 4) * (4*1+2); do { x = w>>2; while(x>0) { @@ -2046,9 +2073,9 @@ DECLAREContigPutFunc(putcontig8bitYCbCr41tile) int32 Cr = pp[5]; switch( (w&3) ) { - case 3: YCbCrtoRGB(cp [2], pp[2]); - case 2: YCbCrtoRGB(cp [1], pp[1]); - case 1: YCbCrtoRGB(cp [0], pp[0]); + case 3: YCbCrtoRGB(cp [2], pp[2]); /*-fallthrough*/ + case 2: YCbCrtoRGB(cp [1], pp[1]); /*-fallthrough*/ + case 1: YCbCrtoRGB(cp [0], pp[0]); /*-fallthrough*/ case 0: break; } @@ -2070,7 +2097,7 @@ DECLAREContigPutFunc(putcontig8bitYCbCr22tile) uint32* cp2; int32 incr = 2*toskew+w; (void) y; - fromskew = (fromskew / 2) * 6; + fromskew = (fromskew / 2) * (2*2+2); cp2 = cp+w+toskew; while (h>=2) { x = w; @@ -2126,7 +2153,7 @@ DECLAREContigPutFunc(putcontig8bitYCbCr22tile) DECLAREContigPutFunc(putcontig8bitYCbCr21tile) { (void) y; - fromskew = (fromskew * 4) / 2; + fromskew = (fromskew / 2) * (2*1+2); do { x = w>>1; while(x>0) { @@ -2165,7 +2192,7 @@ DECLAREContigPutFunc(putcontig8bitYCbCr12tile) uint32* cp2; int32 incr = 2*toskew+w; (void) y; - fromskew = (fromskew / 2) * 4; + fromskew = (fromskew / 1) * (1 * 2 + 2); cp2 = cp+w+toskew; while (h>=2) { x = w; @@ -2201,7 +2228,7 @@ DECLAREContigPutFunc(putcontig8bitYCbCr12tile) DECLAREContigPutFunc(putcontig8bitYCbCr11tile) { (void) y; - fromskew *= 3; + fromskew = (fromskew / 1) * (1 * 1 + 2); do { x = w; /* was x = w>>1; patched 2000/09/25 warmerda@home.com */ do { @@ -2225,7 +2252,7 @@ DECLARESepPutFunc(putseparate8bitYCbCr11tile) (void) y; (void) a; /* TODO: naming of input vars is still off, change obfuscating declaration inside define, or resolve obfuscation */ - while (h-- > 0) { + for( ; h > 0; --h) { x = w; do { uint32 dr, dg, db; @@ -2238,6 +2265,11 @@ DECLARESepPutFunc(putseparate8bitYCbCr11tile) } #undef YCbCrtoRGB +static int isInRefBlackWhiteRange(float f) +{ + return f > (float)(-0x7FFFFFFF + 128) && f < (float)0x7FFFFFFF; +} + static int initYCbCrConversion(TIFFRGBAImage* img) { @@ -2262,6 +2294,31 @@ initYCbCrConversion(TIFFRGBAImage* img) TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRCOEFFICIENTS, &luma); TIFFGetFieldDefaulted(img->tif, TIFFTAG_REFERENCEBLACKWHITE, &refBlackWhite); + + /* Do some validation to avoid later issues. Detect NaN for now */ + /* and also if lumaGreen is zero since we divide by it later */ + if( luma[0] != luma[0] || + luma[1] != luma[1] || + luma[1] == 0.0 || + luma[2] != luma[2] ) + { + TIFFErrorExt(img->tif->tif_clientdata, module, + "Invalid values for YCbCrCoefficients tag"); + return (0); + } + + if( !isInRefBlackWhiteRange(refBlackWhite[0]) || + !isInRefBlackWhiteRange(refBlackWhite[1]) || + !isInRefBlackWhiteRange(refBlackWhite[2]) || + !isInRefBlackWhiteRange(refBlackWhite[3]) || + !isInRefBlackWhiteRange(refBlackWhite[4]) || + !isInRefBlackWhiteRange(refBlackWhite[5]) ) + { + TIFFErrorExt(img->tif->tif_clientdata, module, + "Invalid values for ReferenceBlackWhite tag"); + return (0); + } + if (TIFFYCbCrToRGBInit(img->ycbcr, luma, refBlackWhite) < 0) return(0); return (1); @@ -2275,6 +2332,13 @@ initCIELabConversion(TIFFRGBAImage* img) float *whitePoint; float refWhite[3]; + TIFFGetFieldDefaulted(img->tif, TIFFTAG_WHITEPOINT, &whitePoint); + if (whitePoint[1] == 0.0f ) { + TIFFErrorExt(img->tif->tif_clientdata, module, + "Invalid value for WhitePoint tag."); + return NULL; + } + if (!img->cielab) { img->cielab = (TIFFCIELabToRGB *) _TIFFmalloc(sizeof(TIFFCIELabToRGB)); @@ -2285,7 +2349,6 @@ initCIELabConversion(TIFFRGBAImage* img) } } - TIFFGetFieldDefaulted(img->tif, TIFFTAG_WHITEPOINT, &whitePoint); refWhite[1] = 100.0F; refWhite[0] = whitePoint[0] / whitePoint[1] * refWhite[1]; refWhite[2] = (1.0F - whitePoint[0] - whitePoint[1]) @@ -2816,6 +2879,13 @@ int TIFFReadRGBAStrip(TIFF* tif, uint32 row, uint32 * raster ) { + return TIFFReadRGBAStripExt(tif, row, raster, 0 ); +} + +int +TIFFReadRGBAStripExt(TIFF* tif, uint32 row, uint32 * raster, int stop_on_error) + +{ char emsg[1024] = ""; TIFFRGBAImage img; int ok; @@ -2836,7 +2906,7 @@ TIFFReadRGBAStrip(TIFF* tif, uint32 row, uint32 * raster ) return (0); } - if (TIFFRGBAImageOK(tif, emsg) && TIFFRGBAImageBegin(&img, tif, 0, emsg)) { + if (TIFFRGBAImageOK(tif, emsg) && TIFFRGBAImageBegin(&img, tif, stop_on_error, emsg)) { img.row_offset = row; img.col_offset = 0; @@ -2867,6 +2937,13 @@ int TIFFReadRGBATile(TIFF* tif, uint32 col, uint32 row, uint32 * raster) { + return TIFFReadRGBATileExt(tif, col, row, raster, 0 ); +} + + +int +TIFFReadRGBATileExt(TIFF* tif, uint32 col, uint32 row, uint32 * raster, int stop_on_error ) +{ char emsg[1024] = ""; TIFFRGBAImage img; int ok; @@ -2901,7 +2978,7 @@ TIFFReadRGBATile(TIFF* tif, uint32 col, uint32 row, uint32 * raster) */ if (!TIFFRGBAImageOK(tif, emsg) - || !TIFFRGBAImageBegin(&img, tif, 0, emsg)) { + || !TIFFRGBAImageBegin(&img, tif, stop_on_error, emsg)) { TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", emsg); return( 0 ); } diff --git a/libtiff/tif_jbig.c b/libtiff/tif_jbig.c index 37878f6..7a14dd9 100644 --- a/libtiff/tif_jbig.c +++ b/libtiff/tif_jbig.c @@ -1,4 +1,4 @@ -/* $Id: tif_jbig.c,v 1.15 2010-03-10 18:56:48 bfriesen Exp $ */ +/* $Id: tif_jbig.c,v 1.16 2017-06-26 15:20:00 erouault Exp $ */ /* * Copyright (c) 1988-1997 Sam Leffler @@ -94,6 +94,7 @@ static int JBIGDecode(TIFF* tif, uint8* buffer, tmsize_t size, uint16 s) jbg_strerror(decodeStatus) #endif ); + jbg_dec_free(&decoder); return 0; } diff --git a/libtiff/tif_jpeg.c b/libtiff/tif_jpeg.c index 70b72d8..0fbdb35 100644 --- a/libtiff/tif_jpeg.c +++ b/libtiff/tif_jpeg.c @@ -1,4 +1,4 @@ -/* $Id: tif_jpeg.c,v 1.123 2016-01-23 21:20:34 erouault Exp $ */ +/* $Id: tif_jpeg.c,v 1.134 2017-10-17 19:04:47 erouault Exp $ */ /* * Copyright (c) 1994-1997 Sam Leffler @@ -27,6 +27,8 @@ #define WIN32_LEAN_AND_MEAN #define VC_EXTRALEAN +#include + #include "tiffiop.h" #ifdef JPEG_SUPPORT @@ -47,6 +49,7 @@ int TIFFFillStrip(TIFF* tif, uint32 strip); int TIFFFillTile(TIFF* tif, uint32 tile); int TIFFReInitJPEG_12( TIFF *tif, int scheme, int is_encode ); +int TIFFJPEGIsFullStripRequired_12(TIFF* tif); /* We undefine FAR to avoid conflict with JPEG definition */ @@ -145,6 +148,8 @@ typedef struct { jpeg_error_mgr err; /* libjpeg error manager */ JMP_BUF exit_jmpbuf; /* for catching libjpeg failures */ + + struct jpeg_progress_mgr progress; /* * The following two members could be a union, but * they're small enough that it's not worth the effort. @@ -175,6 +180,7 @@ typedef struct { int jpegtablesmode; /* What to put in JPEGTables */ int ycbcrsampling_fetched; + int max_allowed_scan_number; } JPEGState; #define JState(tif) ((JPEGState*)(tif)->tif_data) @@ -235,6 +241,33 @@ TIFFjpeg_output_message(j_common_ptr cinfo) TIFFWarningExt(((JPEGState *) cinfo)->tif->tif_clientdata, "JPEGLib", "%s", buffer); } +/* Avoid the risk of denial-of-service on crafted JPEGs with an insane */ +/* number of scans. */ +/* See http://www.libjpeg-turbo.org/pmwiki/uploads/About/TwoIssueswiththeJPEGStandard.pdf */ +static void +TIFFjpeg_progress_monitor(j_common_ptr cinfo) +{ + JPEGState *sp = (JPEGState *) cinfo; /* NB: cinfo assumed first */ + if (cinfo->is_decompressor) + { + const int scan_no = + ((j_decompress_ptr)cinfo)->input_scan_number; + if (scan_no >= sp->max_allowed_scan_number) + { + TIFFErrorExt(((JPEGState *) cinfo)->tif->tif_clientdata, + "TIFFjpeg_progress_monitor", + "Scan number %d exceeds maximum scans (%d). This limit " + "can be raised through the LIBTIFF_JPEG_MAX_ALLOWED_SCAN_NUMBER " + "environment variable.", + scan_no, sp->max_allowed_scan_number); + + jpeg_abort(cinfo); /* clean up libjpeg state */ + LONGJMP(sp->exit_jmpbuf, 1); /* return to libtiff caller */ + } + } +} + + /* * Interface routines. This layer of routines exists * primarily to limit side-effects from using setjmp. @@ -337,8 +370,23 @@ TIFFjpeg_read_header(JPEGState* sp, boolean require_image) } static int +TIFFjpeg_has_multiple_scans(JPEGState* sp) +{ + return CALLJPEG(sp, 0, jpeg_has_multiple_scans(&sp->cinfo.d)); +} + +static int TIFFjpeg_start_decompress(JPEGState* sp) { + const char* sz_max_allowed_scan_number; + /* progress monitor */ + sp->cinfo.d.progress = &sp->progress; + sp->progress.progress_monitor = TIFFjpeg_progress_monitor; + sp->max_allowed_scan_number = 100; + sz_max_allowed_scan_number = getenv("LIBTIFF_JPEG_MAX_ALLOWED_SCAN_NUMBER"); + if( sz_max_allowed_scan_number ) + sp->max_allowed_scan_number = atoi(sz_max_allowed_scan_number); + return CALLVJPEG(sp, jpeg_start_decompress(&sp->cinfo.d)); } @@ -589,9 +637,8 @@ std_term_source(j_decompress_ptr cinfo) } static void -TIFFjpeg_data_src(JPEGState* sp, TIFF* tif) +TIFFjpeg_data_src(JPEGState* sp) { - (void) tif; sp->cinfo.d.src = &sp->src; sp->src.init_source = std_init_source; sp->src.fill_input_buffer = std_fill_input_buffer; @@ -617,9 +664,9 @@ tables_init_source(j_decompress_ptr cinfo) } static void -TIFFjpeg_tables_src(JPEGState* sp, TIFF* tif) +TIFFjpeg_tables_src(JPEGState* sp) { - TIFFjpeg_data_src(sp, tif); + TIFFjpeg_data_src(sp); sp->src.init_source = tables_init_source; } @@ -697,9 +744,11 @@ static int JPEGFixupTags(TIFF* tif) { #ifdef CHECK_JPEG_YCBCR_SUBSAMPLING + JPEGState* sp = JState(tif); if ((tif->tif_dir.td_photometric==PHOTOMETRIC_YCBCR)&& (tif->tif_dir.td_planarconfig==PLANARCONFIG_CONTIG)&& - (tif->tif_dir.td_samplesperpixel==3)) + (tif->tif_dir.td_samplesperpixel==3) && + !sp->ycbcrsampling_fetched) JPEGFixupTagsSubsampling(tif); #endif @@ -974,7 +1023,7 @@ JPEGSetupDecode(TIFF* tif) /* Read JPEGTables if it is present */ if (TIFFFieldSet(tif,FIELD_JPEGTABLES)) { - TIFFjpeg_tables_src(sp, tif); + TIFFjpeg_tables_src(sp); if(TIFFjpeg_read_header(sp,FALSE) != JPEG_HEADER_TABLES_ONLY) { TIFFErrorExt(tif->tif_clientdata, "JPEGSetupDecode", "Bogus JPEGTables field"); return (0); @@ -996,11 +1045,47 @@ JPEGSetupDecode(TIFF* tif) } /* Set up for reading normal data */ - TIFFjpeg_data_src(sp, tif); + TIFFjpeg_data_src(sp); tif->tif_postdecode = _TIFFNoPostDecode; /* override byte swapping */ return (1); } +/* Returns 1 if the full strip should be read, even when doing scanline per */ +/* scanline decoding. This happens when the JPEG stream uses multiple scans. */ +/* Currently only called in CHUNKY_STRIP_READ_SUPPORT mode through */ +/* scanline interface. */ +/* Only reads tif->tif_dir.td_bitspersample, tif->tif_rawdata and */ +/* tif->tif_rawcc members. */ +/* Can be called independently of the usual setup/predecode/decode states */ +int TIFFJPEGIsFullStripRequired(TIFF* tif) +{ + int ret; + JPEGState state; + +#if defined(JPEG_DUAL_MODE_8_12) && !defined(TIFFJPEGIsFullStripRequired) + if( tif->tif_dir.td_bitspersample == 12 ) + return TIFFJPEGIsFullStripRequired_12( tif ); +#endif + + memset(&state, 0, sizeof(JPEGState)); + state.tif = tif; + + TIFFjpeg_create_decompress(&state); + + TIFFjpeg_data_src(&state); + + if (TIFFjpeg_read_header(&state, TRUE) != JPEG_HEADER_OK) + { + TIFFjpeg_destroy(&state); + return (0); + } + ret = TIFFjpeg_has_multiple_scans(&state); + + TIFFjpeg_destroy(&state); + + return ret; +} + /* * Set up for decoding a strip or tile. */ @@ -1041,13 +1126,13 @@ JPEGPreDecode(TIFF* tif, uint16 s) /* * Check image parameters and set decompression parameters. */ - segment_width = td->td_imagewidth; - segment_height = td->td_imagelength - tif->tif_row; if (isTiled(tif)) { segment_width = td->td_tilewidth; segment_height = td->td_tilelength; sp->bytesperline = TIFFTileRowSize(tif); } else { + segment_width = td->td_imagewidth; + segment_height = td->td_imagelength - tif->tif_row; if (segment_height > td->td_rowsperstrip) segment_height = td->td_rowsperstrip; sp->bytesperline = TIFFScanlineSize(tif); @@ -1068,9 +1153,23 @@ JPEGPreDecode(TIFF* tif, uint16 s) segment_width, segment_height, sp->cinfo.d.image_width, sp->cinfo.d.image_height); - } - if (sp->cinfo.d.image_width > segment_width || - sp->cinfo.d.image_height > segment_height) { + } + if( sp->cinfo.d.image_width == segment_width && + sp->cinfo.d.image_height > segment_height && + tif->tif_row + segment_height == td->td_imagelength && + !isTiled(tif) ) { + /* Some files have a last strip, that should be truncated, */ + /* but their JPEG codestream has still the maximum strip */ + /* height. Warn about this as this is non compliant, but */ + /* we can safely recover from that. */ + TIFFWarningExt(tif->tif_clientdata, module, + "JPEG strip size exceeds expected dimensions," + " expected %dx%d, got %dx%d", + segment_width, segment_height, + sp->cinfo.d.image_width, sp->cinfo.d.image_height); + } + else if (sp->cinfo.d.image_width > segment_width || + sp->cinfo.d.image_height > segment_height) { /* * This case could be dangerous, if the strip or tile size has * been reported as less than the amount of data jpeg will @@ -1103,6 +1202,47 @@ JPEGPreDecode(TIFF* tif, uint16 s) return (0); } #endif + + /* In some cases, libjpeg needs to allocate a lot of memory */ + /* http://www.libjpeg-turbo.org/pmwiki/uploads/About/TwoIssueswiththeJPEGStandard.pdf */ + if( TIFFjpeg_has_multiple_scans(sp) ) + { + /* In this case libjpeg will need to allocate memory or backing */ + /* store for all coefficients */ + /* See call to jinit_d_coef_controller() from master_selection() */ + /* in libjpeg */ + toff_t nRequiredMemory = (toff_t)sp->cinfo.d.image_width * + sp->cinfo.d.image_height * + sp->cinfo.d.num_components * + ((td->td_bitspersample+7)/8); + /* BLOCK_SMOOTHING_SUPPORTED is generally defined, so we need */ + /* to replicate the logic of jinit_d_coef_controller() */ + if( sp->cinfo.d.progressive_mode ) + nRequiredMemory *= 3; + +#ifndef TIFF_LIBJPEG_LARGEST_MEM_ALLOC +#define TIFF_LIBJPEG_LARGEST_MEM_ALLOC (100 * 1024 * 1024) +#endif + + if( nRequiredMemory > TIFF_LIBJPEG_LARGEST_MEM_ALLOC && + getenv("LIBTIFF_ALLOW_LARGE_LIBJPEG_MEM_ALLOC") == NULL ) + { + TIFFErrorExt(tif->tif_clientdata, module, + "Reading this strip would require libjpeg to allocate " + "at least %u bytes. " + "This is disabled since above the %u threshold. " + "You may override this restriction by defining the " + "LIBTIFF_ALLOW_LARGE_LIBJPEG_MEM_ALLOC environment variable, " + "or recompile libtiff by defining the " + "TIFF_LIBJPEG_LARGEST_MEM_ALLOC macro to a value greater " + "than %u", + (unsigned)nRequiredMemory, + (unsigned)TIFF_LIBJPEG_LARGEST_MEM_ALLOC, + (unsigned)TIFF_LIBJPEG_LARGEST_MEM_ALLOC); + return (0); + } + } + if (td->td_planarconfig == PLANARCONFIG_CONTIG) { /* Component 0 should have expected sampling factors */ if (sp->cinfo.d.comp_info[0].h_samp_factor != sp->h_sampling || @@ -1364,10 +1504,18 @@ JPEGDecodeRaw(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s) { JPEGState *sp = JState(tif); tmsize_t nrows; + TIFFDirectory *td = &tif->tif_dir; (void) s; + nrows = sp->cinfo.d.image_height; + /* For last strip, limit number of rows to its truncated height */ + /* even if the codestream height is larger (which is not compliant, */ + /* but that we tolerate) */ + if( (uint32)nrows > td->td_imagelength - tif->tif_row && !isTiled(tif) ) + nrows = td->td_imagelength - tif->tif_row; + /* data is expected to be read in multiples of a scanline */ - if ( (nrows = sp->cinfo.d.image_height) != 0 ) { + if ( nrows != 0 ) { /* Cb,Cr both have sampling factors 1, so this is correct */ JDIMENSION clumps_per_line = sp->cinfo.d.comp_info[1].downsampled_width; @@ -1626,6 +1774,20 @@ JPEGSetupEncode(TIFF* tif) case PHOTOMETRIC_YCBCR: sp->h_sampling = td->td_ycbcrsubsampling[0]; sp->v_sampling = td->td_ycbcrsubsampling[1]; + if( sp->h_sampling == 0 || sp->v_sampling == 0 ) + { + TIFFErrorExt(tif->tif_clientdata, module, + "Invalig horizontal/vertical sampling value"); + return (0); + } + if( td->td_bitspersample > 16 ) + { + TIFFErrorExt(tif->tif_clientdata, module, + "BitsPerSample %d not allowed for JPEG", + td->td_bitspersample); + return (0); + } + /* * A ReferenceBlackWhite field *must* be present since the * default value is inappropriate for YCbCr. Fill in the @@ -2291,6 +2453,25 @@ static int JPEGInitializeLibJPEG( TIFF * tif, int decompress ) } else { if (!TIFFjpeg_create_compress(sp)) return (0); +#ifndef TIFF_JPEG_MAX_MEMORY_TO_USE +#define TIFF_JPEG_MAX_MEMORY_TO_USE (10 * 1024 * 1024) +#endif + /* libjpeg turbo 1.5.2 honours max_memory_to_use, but has no backing */ + /* store implementation, so better not set max_memory_to_use ourselves. */ + /* See https://github.com/libjpeg-turbo/libjpeg-turbo/issues/162 */ + if( sp->cinfo.c.mem->max_memory_to_use > 0 ) + { + /* This is to address bug related in ticket GDAL #1795. */ + if (getenv("JPEGMEM") == NULL) + { + /* Increase the max memory usable. This helps when creating files */ + /* with "big" tile, without using libjpeg temporary files. */ + /* For example a 512x512 tile with 3 bands */ + /* requires 1.5 MB which is above libjpeg 1MB default */ + if( sp->cinfo.c.mem->max_memory_to_use < TIFF_JPEG_MAX_MEMORY_TO_USE ) + sp->cinfo.c.mem->max_memory_to_use = TIFF_JPEG_MAX_MEMORY_TO_USE; + } + } } sp->cinfo_initialized = TRUE; diff --git a/libtiff/tif_jpeg_12.c b/libtiff/tif_jpeg_12.c index 8499e64..b458c25 100644 --- a/libtiff/tif_jpeg_12.c +++ b/libtiff/tif_jpeg_12.c @@ -4,6 +4,7 @@ #if defined(JPEG_DUAL_MODE_8_12) # define TIFFInitJPEG TIFFInitJPEG_12 +# define TIFFJPEGIsFullStripRequired TIFFJPEGIsFullStripRequired_12 int TIFFInitJPEG_12(TIFF* tif, int scheme); diff --git a/libtiff/tif_luv.c b/libtiff/tif_luv.c index ca08f30..4b25244 100644 --- a/libtiff/tif_luv.c +++ b/libtiff/tif_luv.c @@ -1,4 +1,4 @@ -/* $Id: tif_luv.c,v 1.43 2016-09-04 21:32:56 erouault Exp $ */ +/* $Id: tif_luv.c,v 1.49 2017-07-24 12:47:30 erouault Exp $ */ /* * Copyright (c) 1997 Greg Ward Larson @@ -158,6 +158,7 @@ typedef struct logLuvState LogLuvState; struct logLuvState { + int encoder_state; /* 1 if encoder correctly initialized */ int user_datafmt; /* user data format */ int encode_meth; /* encoding method */ int pixel_size; /* bytes per pixel */ @@ -472,7 +473,7 @@ LogL16Encode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) tif->tif_rawcp = op; tif->tif_rawcc = tif->tif_rawdatasize - occ; if (!TIFFFlushData1(tif)) - return (-1); + return (0); op = tif->tif_rawcp; occ = tif->tif_rawdatasize - tif->tif_rawcc; } @@ -504,7 +505,7 @@ LogL16Encode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) tif->tif_rawcp = op; tif->tif_rawcc = tif->tif_rawdatasize - occ; if (!TIFFFlushData1(tif)) - return (-1); + return (0); op = tif->tif_rawcp; occ = tif->tif_rawdatasize - tif->tif_rawcc; } @@ -564,7 +565,7 @@ LogLuvEncode24(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) tif->tif_rawcp = op; tif->tif_rawcc = tif->tif_rawdatasize - occ; if (!TIFFFlushData1(tif)) - return (-1); + return (0); op = tif->tif_rawcp; occ = tif->tif_rawdatasize - tif->tif_rawcc; } @@ -623,7 +624,7 @@ LogLuvEncode32(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) tif->tif_rawcp = op; tif->tif_rawcc = tif->tif_rawdatasize - occ; if (!TIFFFlushData1(tif)) - return (-1); + return (0); op = tif->tif_rawcp; occ = tif->tif_rawdatasize - tif->tif_rawcc; } @@ -655,7 +656,7 @@ LogLuvEncode32(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) tif->tif_rawcp = op; tif->tif_rawcc = tif->tif_rawdatasize - occ; if (!TIFFFlushData1(tif)) - return (-1); + return (0); op = tif->tif_rawcp; occ = tif->tif_rawdatasize - tif->tif_rawcc; } @@ -1263,15 +1264,16 @@ LogL16GuessDataFmt(TIFFDirectory *td) return (SGILOGDATAFMT_UNKNOWN); } + +#define TIFF_SIZE_T_MAX ((size_t) ~ ((size_t)0)) +#define TIFF_TMSIZE_T_MAX (tmsize_t)(TIFF_SIZE_T_MAX >> 1) + static tmsize_t multiply_ms(tmsize_t m1, tmsize_t m2) { - tmsize_t bytes = m1 * m2; - - if (m1 && bytes / m1 != m2) - bytes = 0; - - return bytes; + if( m1 == 0 || m2 > TIFF_TMSIZE_T_MAX / m1 ) + return 0; + return m1 * m2; } static int @@ -1312,8 +1314,10 @@ LogL16InitState(TIFF* tif) } if( isTiled(tif) ) sp->tbuflen = multiply_ms(td->td_tilewidth, td->td_tilelength); - else + else if( td->td_rowsperstrip < td->td_imagelength ) sp->tbuflen = multiply_ms(td->td_imagewidth, td->td_rowsperstrip); + else + sp->tbuflen = multiply_ms(td->td_imagewidth, td->td_imagelength); if (multiply_ms(sp->tbuflen, sizeof (int16)) == 0 || (sp->tbuf = (uint8*) _TIFFmalloc(sp->tbuflen * sizeof (int16))) == NULL) { TIFFErrorExt(tif->tif_clientdata, module, "No space for SGILog translation buffer"); @@ -1412,8 +1416,10 @@ LogLuvInitState(TIFF* tif) } if( isTiled(tif) ) sp->tbuflen = multiply_ms(td->td_tilewidth, td->td_tilelength); - else + else if( td->td_rowsperstrip < td->td_imagelength ) sp->tbuflen = multiply_ms(td->td_imagewidth, td->td_rowsperstrip); + else + sp->tbuflen = multiply_ms(td->td_imagewidth, td->td_imagelength); if (multiply_ms(sp->tbuflen, sizeof (uint32)) == 0 || (sp->tbuf = (uint8*) _TIFFmalloc(sp->tbuflen * sizeof (uint32))) == NULL) { TIFFErrorExt(tif->tif_clientdata, module, "No space for SGILog translation buffer"); @@ -1552,6 +1558,7 @@ LogLuvSetupEncode(TIFF* tif) td->td_photometric, "must be either LogLUV or LogL"); break; } + sp->encoder_state = 1; return (1); notsupported: TIFFErrorExt(tif->tif_clientdata, module, @@ -1563,19 +1570,27 @@ notsupported: static void LogLuvClose(TIFF* tif) { + LogLuvState* sp = (LogLuvState*) tif->tif_data; TIFFDirectory *td = &tif->tif_dir; + assert(sp != 0); /* * For consistency, we always want to write out the same * bitspersample and sampleformat for our TIFF file, * regardless of the data format being used by the application. * Since this routine is called after tags have been set but * before they have been recorded in the file, we reset them here. + * Note: this is really a nasty approach. See PixarLogClose */ - td->td_samplesperpixel = - (td->td_photometric == PHOTOMETRIC_LOGL) ? 1 : 3; - td->td_bitspersample = 16; - td->td_sampleformat = SAMPLEFORMAT_INT; + if( sp->encoder_state ) + { + /* See PixarLogClose. Might avoid issues with tags whose size depends + * on those below, but not completely sure this is enough. */ + td->td_samplesperpixel = + (td->td_photometric == PHOTOMETRIC_LOGL) ? 1 : 3; + td->td_bitspersample = 16; + td->td_sampleformat = SAMPLEFORMAT_INT; + } } static void diff --git a/libtiff/tif_lzw.c b/libtiff/tif_lzw.c index 240e19c..bc8f9c8 100644 --- a/libtiff/tif_lzw.c +++ b/libtiff/tif_lzw.c @@ -1,4 +1,4 @@ -/* $Id: tif_lzw.c,v 1.52 2016-09-04 21:32:56 erouault Exp $ */ +/* $Id: tif_lzw.c,v 1.57 2017-07-11 10:54:29 erouault Exp $ */ /* * Copyright (c) 1988-1997 Sam Leffler @@ -275,7 +275,8 @@ LZWPreDecode(TIFF* tif, uint16 s) /* * Check for old bit-reversed codes. */ - if (tif->tif_rawdata[0] == 0 && (tif->tif_rawdata[1] & 0x1)) { + if (tif->tif_rawcc >= 2 && + tif->tif_rawdata[0] == 0 && (tif->tif_rawdata[1] & 0x1)) { #ifdef LZW_COMPAT if (!sp->dec_decode) { TIFFWarningExt(tif->tif_clientdata, module, @@ -318,7 +319,7 @@ LZWPreDecode(TIFF* tif, uint16 s) sp->dec_restart = 0; sp->dec_nbitsmask = MAXCODE(BITS_MIN); #ifdef LZW_CHECKEOS - sp->dec_bitsleft = ((uint64)tif->tif_rawcc) << 3; + sp->dec_bitsleft = 0; #endif sp->dec_free_entp = sp->dec_codetab + CODE_FIRST; /* @@ -425,6 +426,9 @@ LZWDecode(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s) } bp = (unsigned char *)tif->tif_rawcp; +#ifdef LZW_CHECKEOS + sp->dec_bitsleft = (((uint64)tif->tif_rawcc) << 3); +#endif nbits = sp->lzw_nbits; nextdata = sp->lzw_nextdata; nextbits = sp->lzw_nextbits; @@ -549,6 +553,7 @@ LZWDecode(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s) } } + tif->tif_rawcc -= (tmsize_t)( (uint8*) bp - tif->tif_rawcp ); tif->tif_rawcp = (uint8*) bp; sp->lzw_nbits = (unsigned short) nbits; sp->lzw_nextdata = nextdata; @@ -651,6 +656,9 @@ LZWDecodeCompat(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s) } bp = (unsigned char *)tif->tif_rawcp; +#ifdef LZW_CHECKEOS + sp->dec_bitsleft = (((uint64)tif->tif_rawcc) << 3); +#endif nbits = sp->lzw_nbits; nextdata = sp->lzw_nextdata; nextbits = sp->lzw_nextbits; @@ -760,6 +768,7 @@ LZWDecodeCompat(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s) } } + tif->tif_rawcc -= (tmsize_t)( (uint8*) bp - tif->tif_rawcp ); tif->tif_rawcp = (uint8*) bp; sp->lzw_nbits = (unsigned short)nbits; sp->lzw_nextdata = nextdata; @@ -969,7 +978,8 @@ LZWEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) */ if (op > limit) { tif->tif_rawcc = (tmsize_t)(op - tif->tif_rawdata); - TIFFFlushData1(tif); + if( !TIFFFlushData1(tif) ) + return 0; op = tif->tif_rawdata; } PutNextCode(op, ent); @@ -1054,12 +1064,32 @@ LZWPostEncode(TIFF* tif) if (op > sp->enc_rawlimit) { tif->tif_rawcc = (tmsize_t)(op - tif->tif_rawdata); - TIFFFlushData1(tif); + if( !TIFFFlushData1(tif) ) + return 0; op = tif->tif_rawdata; } if (sp->enc_oldcode != (hcode_t) -1) { + int free_ent = sp->lzw_free_ent; + PutNextCode(op, sp->enc_oldcode); sp->enc_oldcode = (hcode_t) -1; + free_ent ++; + + if (free_ent == CODE_MAX-1) { + /* table is full, emit clear code and reset */ + outcount = 0; + PutNextCode(op, CODE_CLEAR); + nbits = BITS_MIN; + } else { + /* + * If the next entry is going to be too big for + * the code size, then increase it, if possible. + */ + if (free_ent > sp->lzw_maxcode) { + nbits++; + assert(nbits <= BITS_MAX); + } + } } PutNextCode(op, CODE_EOI); /* Explicit 0xff masking to make icc -check=conversions happy */ diff --git a/libtiff/tif_ojpeg.c b/libtiff/tif_ojpeg.c index 30a1812..92ed1fa 100644 --- a/libtiff/tif_ojpeg.c +++ b/libtiff/tif_ojpeg.c @@ -1,4 +1,4 @@ -/* $Id: tif_ojpeg.c,v 1.65 2016-09-04 21:32:56 erouault Exp $ */ +/* $Id: tif_ojpeg.c,v 1.69 2017-04-27 17:29:26 erouault Exp $ */ /* WARNING: The type of JPEG encapsulation defined by the TIFF Version 6.0 specification is now totally obsolete and deprecated for new applications and @@ -244,6 +244,7 @@ typedef enum { typedef struct { TIFF* tif; + int decoder_ok; #ifndef LIBJPEG_ENCAP_EXTERNAL JMP_BUF exit_jmpbuf; #endif @@ -722,6 +723,7 @@ OJPEGPreDecode(TIFF* tif, uint16 s) } sp->write_curstrile++; } + sp->decoder_ok = 1; return(1); } @@ -784,8 +786,14 @@ OJPEGPreDecodeSkipScanlines(TIFF* tif) static int OJPEGDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s) { + static const char module[]="OJPEGDecode"; OJPEGState* sp=(OJPEGState*)tif->tif_data; (void)s; + if( !sp->decoder_ok ) + { + TIFFErrorExt(tif->tif_clientdata,module,"Cannot decode: decoder not correctly initialized"); + return 0; + } if (sp->libjpeg_jpeg_query_style==0) { if (OJPEGDecodeRaw(tif,buf,cc)==0) @@ -1782,7 +1790,12 @@ OJPEGReadHeaderInfoSecTablesQTable(TIFF* tif) TIFFSeekFile(tif,sp->qtable_offset[m],SEEK_SET); p=(uint32)TIFFReadFile(tif,&ob[sizeof(uint32)+5],64); if (p!=64) + { + _TIFFfree(ob); return(0); + } + if (sp->qtable[m]!=0) + _TIFFfree(sp->qtable[m]); sp->qtable[m]=ob; sp->sof_tq[m]=m; } @@ -1846,7 +1859,12 @@ OJPEGReadHeaderInfoSecTablesDcTable(TIFF* tif) rb[sizeof(uint32)+5+n]=o[n]; p=(uint32)TIFFReadFile(tif,&(rb[sizeof(uint32)+21]),q); if (p!=q) + { + _TIFFfree(rb); return(0); + } + if (sp->dctable[m]!=0) + _TIFFfree(sp->dctable[m]); sp->dctable[m]=rb; sp->sos_tda[m]=(m<<4); } @@ -1910,7 +1928,12 @@ OJPEGReadHeaderInfoSecTablesAcTable(TIFF* tif) rb[sizeof(uint32)+5+n]=o[n]; p=(uint32)TIFFReadFile(tif,&(rb[sizeof(uint32)+21]),q); if (p!=q) + { + _TIFFfree(rb); return(0); + } + if (sp->actable[m]!=0) + _TIFFfree(sp->actable[m]); sp->actable[m]=rb; sp->sos_tda[m]=(sp->sos_tda[m]|m); } diff --git a/libtiff/tif_open.c b/libtiff/tif_open.c index 5c9036e..a7279e1 100644 --- a/libtiff/tif_open.c +++ b/libtiff/tif_open.c @@ -1,4 +1,4 @@ -/* $Id: tif_open.c,v 1.47 2016-01-23 21:20:34 erouault Exp $ */ +/* $Id: tif_open.c,v 1.48 2016-11-20 22:29:47 erouault Exp $ */ /* * Copyright (c) 1988-1997 Sam Leffler @@ -279,10 +279,10 @@ TIFFClientOpen( * Setup header and write. */ #ifdef WORDS_BIGENDIAN - tif->tif_header.common.tiff_magic = tif->tif_flags & TIFF_SWAB + tif->tif_header.common.tiff_magic = (tif->tif_flags & TIFF_SWAB) ? TIFF_LITTLEENDIAN : TIFF_BIGENDIAN; #else - tif->tif_header.common.tiff_magic = tif->tif_flags & TIFF_SWAB + tif->tif_header.common.tiff_magic = (tif->tif_flags & TIFF_SWAB) ? TIFF_BIGENDIAN : TIFF_LITTLEENDIAN; #endif if (!(tif->tif_flags&TIFF_BIGTIFF)) diff --git a/libtiff/tif_packbits.c b/libtiff/tif_packbits.c index d2a0165..18904b0 100644 --- a/libtiff/tif_packbits.c +++ b/libtiff/tif_packbits.c @@ -1,4 +1,4 @@ -/* $Id: tif_packbits.c,v 1.24 2016-09-04 21:32:56 erouault Exp $ */ +/* $Id: tif_packbits.c,v 1.26 2017-05-14 02:26:07 erouault Exp $ */ /* * Copyright (c) 1988-1997 Sam Leffler @@ -99,7 +99,7 @@ PackBitsEncode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s) slop = (long)(op - lastliteral); tif->tif_rawcc += (tmsize_t)(lastliteral - tif->tif_rawcp); if (!TIFFFlushData1(tif)) - return (-1); + return (0); op = tif->tif_rawcp; while (slop-- > 0) *op++ = *lastliteral++; @@ -107,7 +107,7 @@ PackBitsEncode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s) } else { tif->tif_rawcc += (tmsize_t)(op - tif->tif_rawcp); if (!TIFFFlushData1(tif)) - return (-1); + return (0); op = tif->tif_rawcp; } } @@ -244,6 +244,12 @@ PackBitsDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s) (unsigned long) ((tmsize_t)n - occ)); n = (long)occ; } + if( cc == 0 ) + { + TIFFWarningExt(tif->tif_clientdata, module, + "Terminating PackBitsDecode due to lack of data."); + break; + } occ -= n; b = *bp++; cc--; diff --git a/libtiff/tif_pixarlog.c b/libtiff/tif_pixarlog.c index f4af2ba..979858d 100644 --- a/libtiff/tif_pixarlog.c +++ b/libtiff/tif_pixarlog.c @@ -1,4 +1,4 @@ -/* $Id: tif_pixarlog.c,v 1.48 2016-09-23 22:12:18 erouault Exp $ */ +/* $Id: tif_pixarlog.c,v 1.54 2017-07-10 10:40:28 erouault Exp $ */ /* * Copyright (c) 1996-1997 Sam Leffler @@ -636,29 +636,27 @@ PixarLogGuessDataFmt(TIFFDirectory *td) return guess; } +#define TIFF_SIZE_T_MAX ((size_t) ~ ((size_t)0)) +#define TIFF_TMSIZE_T_MAX (tmsize_t)(TIFF_SIZE_T_MAX >> 1) + static tmsize_t multiply_ms(tmsize_t m1, tmsize_t m2) { - tmsize_t bytes = m1 * m2; - - if (m1 && bytes / m1 != m2) - bytes = 0; - - return bytes; + if( m1 == 0 || m2 > TIFF_TMSIZE_T_MAX / m1 ) + return 0; + return m1 * m2; } static tmsize_t add_ms(tmsize_t m1, tmsize_t m2) { - tmsize_t bytes = m1 + m2; - /* if either input is zero, assume overflow already occurred */ if (m1 == 0 || m2 == 0) - bytes = 0; - else if (bytes <= m1 || bytes <= m2) - bytes = 0; + return 0; + else if (m1 > TIFF_TMSIZE_T_MAX - m2) + return 0; - return bytes; + return m1 + m2; } static int @@ -675,9 +673,20 @@ PixarLogSetupDecode(TIFF* tif) TIFFDirectory *td = &tif->tif_dir; PixarLogState* sp = DecoderState(tif); tmsize_t tbuf_size; + uint32 strip_height; assert(sp != NULL); + /* This function can possibly be called several times by */ + /* PredictorSetupDecode() if this function succeeds but */ + /* PredictorSetup() fails */ + if( (sp->state & PLSTATE_INIT) != 0 ) + return 1; + + strip_height = td->td_rowsperstrip; + if( strip_height > td->td_imagelength ) + strip_height = td->td_imagelength; + /* Make sure no byte swapping happens on the data * after decompression. */ tif->tif_postdecode = _TIFFNoPostDecode; @@ -687,7 +696,7 @@ PixarLogSetupDecode(TIFF* tif) sp->stride = (td->td_planarconfig == PLANARCONFIG_CONTIG ? td->td_samplesperpixel : 1); tbuf_size = multiply_ms(multiply_ms(multiply_ms(sp->stride, td->td_imagewidth), - td->td_rowsperstrip), sizeof(uint16)); + strip_height), sizeof(uint16)); /* add one more stride in case input ends mid-stride */ tbuf_size = add_ms(tbuf_size, sizeof(uint16) * sp->stride); if (tbuf_size == 0) @@ -699,6 +708,9 @@ PixarLogSetupDecode(TIFF* tif) if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) sp->user_datafmt = PixarLogGuessDataFmt(td); if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) { + _TIFFfree(sp->tbuf); + sp->tbuf = NULL; + sp->tbuf_size = 0; TIFFErrorExt(tif->tif_clientdata, module, "PixarLog compression can't handle bits depth/data format combination (depth: %d)", td->td_bitspersample); @@ -706,6 +718,9 @@ PixarLogSetupDecode(TIFF* tif) } if (inflateInit(&sp->stream) != Z_OK) { + _TIFFfree(sp->tbuf); + sp->tbuf = NULL; + sp->tbuf_size = 0; TIFFErrorExt(tif->tif_clientdata, module, "%s", sp->stream.msg ? sp->stream.msg : "(null)"); return (0); } else { @@ -774,6 +789,10 @@ PixarLogDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s) (void) s; assert(sp != NULL); + + sp->stream.next_in = tif->tif_rawcp; + sp->stream.avail_in = (uInt) tif->tif_rawcc; + sp->stream.next_out = (unsigned char *) sp->tbuf; assert(sizeof(sp->stream.avail_out)==4); /* if this assert gets raised, we need to simplify this code to reflect a ZLib that is likely updated @@ -819,6 +838,9 @@ PixarLogDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s) return (0); } + tif->tif_rawcp = sp->stream.next_in; + tif->tif_rawcc = sp->stream.avail_in; + up = sp->tbuf; /* Swap bytes in the data if from a different endian machine. */ if (tif->tif_flags & TIFF_SWAB) @@ -1233,8 +1255,10 @@ PixarLogPostEncode(TIFF* tif) static void PixarLogClose(TIFF* tif) { + PixarLogState* sp = (PixarLogState*) tif->tif_data; TIFFDirectory *td = &tif->tif_dir; + assert(sp != 0); /* In a really sneaky (and really incorrect, and untruthful, and * troublesome, and error-prone) maneuver that completely goes against * the spirit of TIFF, and breaks TIFF, on close, we covertly @@ -1243,8 +1267,19 @@ PixarLogClose(TIFF* tif) * readers that don't know about PixarLog, or how to set * the PIXARLOGDATFMT pseudo-tag. */ - td->td_bitspersample = 8; - td->td_sampleformat = SAMPLEFORMAT_UINT; + + if (sp->state&PLSTATE_INIT) { + /* We test the state to avoid an issue such as in + * http://bugzilla.maptools.org/show_bug.cgi?id=2604 + * What appends in that case is that the bitspersample is 1 and + * a TransferFunction is set. The size of the TransferFunction + * depends on 1<td_bitspersample = 8; + td->td_sampleformat = SAMPLEFORMAT_UINT; + } } static void diff --git a/libtiff/tif_predict.c b/libtiff/tif_predict.c index 0b185d2..9ae1f57 100644 --- a/libtiff/tif_predict.c +++ b/libtiff/tif_predict.c @@ -1,4 +1,4 @@ -/* $Id: tif_predict.c,v 1.40 2016-11-04 09:19:13 erouault Exp $ */ +/* $Id: tif_predict.c,v 1.44 2017-06-18 10:31:50 erouault Exp $ */ /* * Copyright (c) 1988-1997 Sam Leffler @@ -117,6 +117,9 @@ PredictorSetupDecode(TIFF* tif) TIFFPredictorState* sp = PredictorState(tif); TIFFDirectory* td = &tif->tif_dir; + /* Note: when PredictorSetup() fails, the effets of setupdecode() */ + /* will not be "cancelled" so setupdecode() might be robust to */ + /* be called several times. */ if (!(*sp->setupdecode)(tif) || !PredictorSetup(tif)) return 0; @@ -259,11 +262,12 @@ PredictorSetupEncode(TIFF* tif) #define REPEAT4(n, op) \ switch (n) { \ - default: { tmsize_t i; for (i = n-4; i > 0; i--) { op; } } \ - case 4: op; \ - case 3: op; \ - case 2: op; \ - case 1: op; \ + default: { \ + tmsize_t i; for (i = n-4; i > 0; i--) { op; } } /*-fallthrough*/ \ + case 4: op; /*-fallthrough*/ \ + case 3: op; /*-fallthrough*/ \ + case 2: op; /*-fallthrough*/ \ + case 1: op; /*-fallthrough*/ \ case 0: ; \ } @@ -273,6 +277,7 @@ PredictorSetupEncode(TIFF* tif) /* - when storing into the byte stream, we explicitly mask with 0xff so */ /* as to make icc -check=conversions happy (not necessary by the standard) */ +TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW static int horAcc8(TIFF* tif, uint8* cp0, tmsize_t cc) { @@ -340,6 +345,7 @@ swabHorAcc16(TIFF* tif, uint8* cp0, tmsize_t cc) return horAcc16(tif, cp0, cc); } +TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW static int horAcc16(TIFF* tif, uint8* cp0, tmsize_t cc) { @@ -374,6 +380,7 @@ swabHorAcc32(TIFF* tif, uint8* cp0, tmsize_t cc) return horAcc32(tif, cp0, cc); } +TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW static int horAcc32(TIFF* tif, uint8* cp0, tmsize_t cc) { @@ -499,6 +506,7 @@ PredictorDecodeTile(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s) return 0; } +TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW static int horDiff8(TIFF* tif, uint8* cp0, tmsize_t cc) { @@ -552,6 +560,7 @@ horDiff8(TIFF* tif, uint8* cp0, tmsize_t cc) return 1; } +TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW static int horDiff16(TIFF* tif, uint8* cp0, tmsize_t cc) { @@ -591,6 +600,7 @@ swabHorDiff16(TIFF* tif, uint8* cp0, tmsize_t cc) return 1; } +TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW static int horDiff32(TIFF* tif, uint8* cp0, tmsize_t cc) { @@ -633,6 +643,7 @@ swabHorDiff32(TIFF* tif, uint8* cp0, tmsize_t cc) /* * Floating point predictor differencing routine. */ +TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW static int fpDiff(TIFF* tif, uint8* cp0, tmsize_t cc) { @@ -797,7 +808,7 @@ PredictorPrintDir(TIFF* tif, FILE* fd, long flags) case 2: fprintf(fd, "horizontal differencing "); break; case 3: fprintf(fd, "floating point predictor "); break; } - fprintf(fd, "%u (0x%x)\n", sp->predictor, sp->predictor); + fprintf(fd, "%d (0x%x)\n", sp->predictor, sp->predictor); } if (sp->printdir) (*sp->printdir)(tif, fd, flags); diff --git a/libtiff/tif_print.c b/libtiff/tif_print.c index 186f2ee..24d4b98 100644 --- a/libtiff/tif_print.c +++ b/libtiff/tif_print.c @@ -1,4 +1,4 @@ -/* $Id: tif_print.c,v 1.64 2015-12-06 22:19:56 erouault Exp $ */ +/* $Id: tif_print.c,v 1.65 2016-11-20 22:31:22 erouault Exp $ */ /* * Copyright (c) 1988-1997 Sam Leffler @@ -262,7 +262,7 @@ TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags) if (td->td_subfiletype & FILETYPE_MASK) fprintf(fd, "%stransparency mask", sep); fprintf(fd, " (%lu = 0x%lx)\n", - (long) td->td_subfiletype, (long) td->td_subfiletype); + (unsigned long) td->td_subfiletype, (long) td->td_subfiletype); } if (TIFFFieldSet(tif,FIELD_IMAGEDIMENSIONS)) { fprintf(fd, " Image Width: %lu Image Length: %lu", @@ -521,7 +521,7 @@ TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags) fprintf(fd, "\n"); n = 1L<td_bitspersample; for (l = 0; l < n; l++) - fprintf(fd, " %5lu: %5u %5u %5u\n", + fprintf(fd, " %5ld: %5u %5u %5u\n", l, td->td_colormap[0][l], td->td_colormap[1][l], @@ -544,7 +544,7 @@ TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags) n = 1L<td_bitspersample; for (l = 0; l < n; l++) { uint16 i; - fprintf(fd, " %2lu: %5u", + fprintf(fd, " %2ld: %5u", l, td->td_transferfunction[0][l]); for (i = 1; i < td->td_samplesperpixel; i++) fprintf(fd, " %5u", @@ -661,7 +661,7 @@ TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags) uint32 s; fprintf(fd, " %lu %s:\n", - (long) td->td_nstrips, + (unsigned long) td->td_nstrips, isTiled(tif) ? "Tiles" : "Strips"); for (s = 0; s < td->td_nstrips; s++) #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) diff --git a/libtiff/tif_read.c b/libtiff/tif_read.c index 8003592..2ba985a 100644 --- a/libtiff/tif_read.c +++ b/libtiff/tif_read.c @@ -1,4 +1,4 @@ -/* $Id: tif_read.c,v 1.49 2016-07-10 18:00:21 erouault Exp $ */ +/* $Id: tif_read.c,v 1.66 2017-11-17 20:21:00 erouault Exp $ */ /* * Copyright (c) 1988-1997 Sam Leffler @@ -47,6 +47,121 @@ TIFFReadRawTile1(TIFF* tif, uint32 tile, void* buf, tmsize_t size, const char* m #define NOSTRIP ((uint32)(-1)) /* undefined state */ #define NOTILE ((uint32)(-1)) /* undefined state */ +#define INITIAL_THRESHOLD (1024 * 1024) +#define THRESHOLD_MULTIPLIER 10 +#define MAX_THRESHOLD (THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * INITIAL_THRESHOLD) + +/* Read 'size' bytes in tif_rawdata buffer starting at offset 'rawdata_offset' + * Returns 1 in case of success, 0 otherwise. */ +static int TIFFReadAndRealloc( TIFF* tif, tmsize_t size, + tmsize_t rawdata_offset, + int is_strip, uint32 strip_or_tile, + const char* module ) +{ +#if SIZEOF_VOIDP == 8 || SIZEOF_SIZE_T == 8 + tmsize_t threshold = INITIAL_THRESHOLD; +#endif + tmsize_t already_read = 0; + + /* On 64 bit processes, read first a maximum of 1 MB, then 10 MB, etc */ + /* so as to avoid allocating too much memory in case the file is too */ + /* short. We could ask for the file size, but this might be */ + /* expensive with some I/O layers (think of reading a gzipped file) */ + /* Restrict to 64 bit processes, so as to avoid reallocs() */ + /* on 32 bit processes where virtual memory is scarce. */ + while( already_read < size ) + { + tmsize_t bytes_read; + tmsize_t to_read = size - already_read; +#if SIZEOF_VOIDP == 8 || SIZEOF_SIZE_T == 8 + if( to_read >= threshold && threshold < MAX_THRESHOLD && + already_read + to_read + rawdata_offset > tif->tif_rawdatasize ) + { + to_read = threshold; + threshold *= THRESHOLD_MULTIPLIER; + } +#endif + if (already_read + to_read + rawdata_offset > tif->tif_rawdatasize) { + uint8* new_rawdata; + assert((tif->tif_flags & TIFF_MYBUFFER) != 0); + tif->tif_rawdatasize = (tmsize_t)TIFFroundup_64( + (uint64)already_read + to_read + rawdata_offset, 1024); + if (tif->tif_rawdatasize==0) { + TIFFErrorExt(tif->tif_clientdata, module, + "Invalid buffer size"); + return 0; + } + new_rawdata = (uint8*) _TIFFrealloc( + tif->tif_rawdata, tif->tif_rawdatasize); + if( new_rawdata == 0 ) + { + TIFFErrorExt(tif->tif_clientdata, module, + "No space for data buffer at scanline %lu", + (unsigned long) tif->tif_row); + _TIFFfree(tif->tif_rawdata); + tif->tif_rawdata = 0; + tif->tif_rawdatasize = 0; + return 0; + } + tif->tif_rawdata = new_rawdata; + } + + bytes_read = TIFFReadFile(tif, + tif->tif_rawdata + rawdata_offset + already_read, to_read); + already_read += bytes_read; + if (bytes_read != to_read) { + memset( tif->tif_rawdata + rawdata_offset + already_read, 0, + tif->tif_rawdatasize - rawdata_offset - already_read ); +#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) + if( is_strip ) + { + TIFFErrorExt(tif->tif_clientdata, module, + "Read error at scanline %lu; got %I64u bytes, " + "expected %I64u", + (unsigned long) tif->tif_row, + (unsigned __int64) already_read, + (unsigned __int64) size); + } + else + { + TIFFErrorExt(tif->tif_clientdata, module, + "Read error at row %lu, col %lu, tile %lu; " + "got %I64u bytes, expected %I64u", + (unsigned long) tif->tif_row, + (unsigned long) tif->tif_col, + (unsigned long) strip_or_tile, + (unsigned __int64) already_read, + (unsigned __int64) size); + } +#else + if( is_strip ) + { + TIFFErrorExt(tif->tif_clientdata, module, + "Read error at scanline %lu; got %llu bytes, " + "expected %llu", + (unsigned long) tif->tif_row, + (unsigned long long) already_read, + (unsigned long long) size); + } + else + { + TIFFErrorExt(tif->tif_clientdata, module, + "Read error at row %lu, col %lu, tile %lu; " + "got %llu bytes, expected %llu", + (unsigned long) tif->tif_row, + (unsigned long) tif->tif_col, + (unsigned long) strip_or_tile, + (unsigned long long) already_read, + (unsigned long long) size); + } +#endif + return 0; + } + } + return 1; +} + + static int TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int restart ) { @@ -54,7 +169,8 @@ TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int restart ) register TIFFDirectory *td = &tif->tif_dir; tmsize_t unused_data; uint64 read_offset; - tmsize_t cc, to_read; + tmsize_t to_read; + tmsize_t read_ahead_mod; /* tmsize_t bytecountm; */ if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount) @@ -67,7 +183,14 @@ TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int restart ) */ /* bytecountm=(tmsize_t) td->td_stripbytecount[strip]; */ - if (read_ahead*2 > tif->tif_rawdatasize) { + + /* Not completely sure where the * 2 comes from, but probably for */ + /* an exponentional growth strategy of tif_rawdatasize */ + if( read_ahead < TIFF_TMSIZE_T_MAX / 2 ) + read_ahead_mod = read_ahead * 2; + else + read_ahead_mod = read_ahead; + if (read_ahead_mod > tif->tif_rawdatasize) { assert( restart ); tif->tif_curstrip = NOSTRIP; @@ -77,8 +200,6 @@ TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int restart ) (unsigned long) strip); return (0); } - if (!TIFFReadBufferSetup(tif, 0, read_ahead*2)) - return (0); } if( restart ) @@ -118,7 +239,10 @@ TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int restart ) /* ** How much do we want to read? */ - to_read = tif->tif_rawdatasize - unused_data; + if( read_ahead_mod > tif->tif_rawdatasize ) + to_read = read_ahead_mod - unused_data; + else + to_read = tif->tif_rawdatasize - unused_data; if( (uint64) to_read > td->td_stripbytecount[strip] - tif->tif_rawdataoff - tif->tif_rawdataloaded ) { @@ -127,28 +251,18 @@ TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int restart ) } assert((tif->tif_flags&TIFF_BUFFERMMAP)==0); - cc = TIFFReadFile(tif, tif->tif_rawdata + unused_data, to_read); - - if (cc != to_read) { -#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) - TIFFErrorExt(tif->tif_clientdata, module, - "Read error at scanline %lu; got %I64u bytes, expected %I64u", - (unsigned long) tif->tif_row, - (unsigned __int64) cc, - (unsigned __int64) to_read); -#else - TIFFErrorExt(tif->tif_clientdata, module, - "Read error at scanline %lu; got %llu bytes, expected %llu", - (unsigned long) tif->tif_row, - (unsigned long long) cc, - (unsigned long long) to_read); -#endif + if( !TIFFReadAndRealloc( tif, to_read, unused_data, + 1, /* is_strip */ + 0, /* strip_or_tile */ + module) ) + { return 0; } - + tif->tif_rawdataoff = tif->tif_rawdataoff + tif->tif_rawdataloaded - unused_data ; tif->tif_rawdataloaded = unused_data + to_read; + tif->tif_rawcc = tif->tif_rawdataloaded; tif->tif_rawcp = tif->tif_rawdata; if (!isFillOrder(tif, td->td_fillorder) && @@ -162,9 +276,30 @@ TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int restart ) ** restart the decoder. */ if( restart ) - return TIFFStartStrip(tif, strip); + { + +#ifdef JPEG_SUPPORT + /* A bit messy since breaks the codec abstraction. Ultimately */ + /* there should be a function pointer for that, but it seems */ + /* only JPEG is affected. */ + /* For JPEG, if there are multiple scans (can generally be known */ + /* with the read_ahead used), we need to read the whole strip */ + if( tif->tif_dir.td_compression==COMPRESSION_JPEG && + (uint64)tif->tif_rawcc < td->td_stripbytecount[strip] ) + { + if( TIFFJPEGIsFullStripRequired(tif) ) + { + return TIFFFillStrip(tif, strip); + } + } +#endif + + return TIFFStartStrip(tif, strip); + } else + { return 1; + } } /* @@ -219,7 +354,18 @@ TIFFSeek(TIFF* tif, uint32 row, uint16 sample ) if( !whole_strip ) { - read_ahead = tif->tif_scanlinesize * 16 + 5000; + /* 16 is for YCbCr mode where we may need to read 16 */ + /* lines at a time to get a decompressed line, and 5000 */ + /* is some constant value, for example for JPEG tables */ + if( tif->tif_scanlinesize < TIFF_TMSIZE_T_MAX / 16 && + tif->tif_scanlinesize * 16 < TIFF_TMSIZE_T_MAX - 5000 ) + { + read_ahead = tif->tif_scanlinesize * 16 + 5000; + } + else + { + read_ahead = tif->tif_scanlinesize; + } } /* @@ -315,18 +461,17 @@ TIFFReadScanline(TIFF* tif, void* buf, uint32 row, uint16 sample) } /* - * Read a strip of data and decompress the specified - * amount into the user-supplied buffer. + * Calculate the strip size according to the number of + * rows in the strip (check for truncated last strip on any + * of the separations). */ -tmsize_t -TIFFReadEncodedStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size) +static tmsize_t TIFFReadEncodedStripGetStripSize(TIFF* tif, uint32 strip, uint16* pplane) { static const char module[] = "TIFFReadEncodedStrip"; TIFFDirectory *td = &tif->tif_dir; uint32 rowsperstrip; uint32 stripsperplane; uint32 stripinplane; - uint16 plane; uint32 rows; tmsize_t stripsize; if (!TIFFCheckRead(tif,0)) @@ -338,23 +483,37 @@ TIFFReadEncodedStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size) (unsigned long)td->td_nstrips); return((tmsize_t)(-1)); } - /* - * Calculate the strip size according to the number of - * rows in the strip (check for truncated last strip on any - * of the separations). - */ + rowsperstrip=td->td_rowsperstrip; if (rowsperstrip>td->td_imagelength) rowsperstrip=td->td_imagelength; - stripsperplane=((td->td_imagelength+rowsperstrip-1)/rowsperstrip); + stripsperplane= TIFFhowmany_32_maxuint_compat(td->td_imagelength, rowsperstrip); stripinplane=(strip%stripsperplane); - plane=(uint16)(strip/stripsperplane); + if( pplane ) *pplane=(uint16)(strip/stripsperplane); rows=td->td_imagelength-stripinplane*rowsperstrip; if (rows>rowsperstrip) rows=rowsperstrip; stripsize=TIFFVStripSize(tif,rows); if (stripsize==0) return((tmsize_t)(-1)); + return stripsize; +} + +/* + * Read a strip of data and decompress the specified + * amount into the user-supplied buffer. + */ +tmsize_t +TIFFReadEncodedStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size) +{ + static const char module[] = "TIFFReadEncodedStrip"; + TIFFDirectory *td = &tif->tif_dir; + tmsize_t stripsize; + uint16 plane; + + stripsize=TIFFReadEncodedStripGetStripSize(tif, strip, &plane); + if (stripsize==((tmsize_t)(-1))) + return((tmsize_t)(-1)); /* shortcut to avoid an extra memcpy() */ if( td->td_compression == COMPRESSION_NONE && @@ -383,6 +542,49 @@ TIFFReadEncodedStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size) return(stripsize); } +/* Variant of TIFFReadEncodedStrip() that does + * * if *buf == NULL, *buf = _TIFFmalloc(bufsizetoalloc) only after TIFFFillStrip() has + * succeeded. This avoid excessive memory allocation in case of truncated + * file. + * * calls regular TIFFReadEncodedStrip() if *buf != NULL + */ +tmsize_t +_TIFFReadEncodedStripAndAllocBuffer(TIFF* tif, uint32 strip, + void **buf, tmsize_t bufsizetoalloc, + tmsize_t size_to_read) +{ + tmsize_t this_stripsize; + uint16 plane; + + if( *buf != NULL ) + { + return TIFFReadEncodedStrip(tif, strip, *buf, size_to_read); + } + + this_stripsize=TIFFReadEncodedStripGetStripSize(tif, strip, &plane); + if (this_stripsize==((tmsize_t)(-1))) + return((tmsize_t)(-1)); + + if ((size_to_read!=(tmsize_t)(-1))&&(size_to_readtif_clientdata, TIFFFileName(tif), "No space for strip buffer"); + return((tmsize_t)(-1)); + } + _TIFFmemset(*buf, 0, bufsizetoalloc); + + if ((*tif->tif_decodestrip)(tif,*buf,this_stripsize,plane)<=0) + return((tmsize_t)(-1)); + (*tif->tif_postdecode)(tif,*buf,this_stripsize); + return(this_stripsize); + + +} + static tmsize_t TIFFReadRawStrip1(TIFF* tif, uint32 strip, void* buf, tmsize_t size, const char* module) @@ -420,16 +622,25 @@ TIFFReadRawStrip1(TIFF* tif, uint32 strip, void* buf, tmsize_t size, return ((tmsize_t)(-1)); } } else { - tmsize_t ma,mb; + tmsize_t ma = 0; tmsize_t n; - ma=(tmsize_t)td->td_stripoffset[strip]; - mb=ma+size; - if ((td->td_stripoffset[strip] > (uint64)TIFF_TMSIZE_T_MAX)||(ma>tif->tif_size)) - n=0; - else if ((mbtif->tif_size)) - n=tif->tif_size-ma; - else - n=size; + if ((td->td_stripoffset[strip] > (uint64)TIFF_TMSIZE_T_MAX)|| + ((ma=(tmsize_t)td->td_stripoffset[strip])>tif->tif_size)) + { + n=0; + } + else if( ma > TIFF_TMSIZE_T_MAX - size ) + { + n=0; + } + else + { + tmsize_t mb=ma+size; + if (mb>tif->tif_size) + n=tif->tif_size-ma; + else + n=size; + } if (n!=size) { #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) TIFFErrorExt(tif->tif_clientdata, module, @@ -454,6 +665,43 @@ TIFFReadRawStrip1(TIFF* tif, uint32 strip, void* buf, tmsize_t size, return (size); } +static tmsize_t +TIFFReadRawStripOrTile2(TIFF* tif, uint32 strip_or_tile, int is_strip, + tmsize_t size, const char* module) +{ + TIFFDirectory *td = &tif->tif_dir; + + assert( !isMapped(tif) ); + assert((tif->tif_flags&TIFF_NOREADRAW)==0); + + if (!SeekOK(tif, td->td_stripoffset[strip_or_tile])) { + if( is_strip ) + { + TIFFErrorExt(tif->tif_clientdata, module, + "Seek error at scanline %lu, strip %lu", + (unsigned long) tif->tif_row, + (unsigned long) strip_or_tile); + } + else + { + TIFFErrorExt(tif->tif_clientdata, module, + "Seek error at row %lu, col %lu, tile %lu", + (unsigned long) tif->tif_row, + (unsigned long) tif->tif_col, + (unsigned long) strip_or_tile); + } + return ((tmsize_t)(-1)); + } + + if( !TIFFReadAndRealloc( tif, size, 0, is_strip, + strip_or_tile, module ) ) + { + return ((tmsize_t)(-1)); + } + + return (size); +} + /* * Read a strip of data from the file. */ @@ -535,26 +783,40 @@ TIFFFillStrip(TIFF* tif, uint32 strip) #endif return (0); } - if (isMapped(tif) && - (isFillOrder(tif, td->td_fillorder) - || (tif->tif_flags & TIFF_NOBITREV))) { - /* - * The image is mapped into memory and we either don't - * need to flip bits or the compression routine is - * going to handle this operation itself. In this - * case, avoid copying the raw data and instead just - * reference the data from the memory mapped file - * image. This assumes that the decompression - * routines do not modify the contents of the raw data - * buffer (if they try to, the application will get a - * fault since the file is mapped read-only). - */ - if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) { - _TIFFfree(tif->tif_rawdata); - tif->tif_rawdata = NULL; - tif->tif_rawdatasize = 0; + + /* To avoid excessive memory allocations: */ + /* Byte count should normally not be larger than a number of */ + /* times the uncompressed size plus some margin */ + if( bytecount > 1024 * 1024 ) + { + /* 10 and 4096 are just values that could be adjusted. */ + /* Hopefully they are safe enough for all codecs */ + tmsize_t stripsize = TIFFStripSize(tif); + if( stripsize != 0 && + (bytecount - 4096) / 10 > (uint64)stripsize ) + { + uint64 newbytecount = (uint64)stripsize * 10 + 4096; + if( (int64)newbytecount >= 0 ) + { +#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) + TIFFWarningExt(tif->tif_clientdata, module, + "Too large strip byte count %I64u, strip %lu. Limiting to %I64u", + (unsigned __int64) bytecount, + (unsigned long) strip, + (unsigned __int64) newbytecount); +#else + TIFFErrorExt(tif->tif_clientdata, module, + "Too large strip byte count %llu, strip %lu. Limiting to %llu", + (unsigned long long) bytecount, + (unsigned long) strip, + (unsigned long long) newbytecount); +#endif + bytecount = newbytecount; + } } - tif->tif_flags &= ~TIFF_MYBUFFER; + } + + if (isMapped(tif)) { /* * We must check for overflow, potentially causing * an OOB read. Instead of simple @@ -591,6 +853,28 @@ TIFFFillStrip(TIFF* tif, uint32 strip) tif->tif_curstrip = NOSTRIP; return (0); } + } + + if (isMapped(tif) && + (isFillOrder(tif, td->td_fillorder) + || (tif->tif_flags & TIFF_NOBITREV))) { + /* + * The image is mapped into memory and we either don't + * need to flip bits or the compression routine is + * going to handle this operation itself. In this + * case, avoid copying the raw data and instead just + * reference the data from the memory mapped file + * image. This assumes that the decompression + * routines do not modify the contents of the raw data + * buffer (if they try to, the application will get a + * fault since the file is mapped read-only). + */ + if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) { + _TIFFfree(tif->tif_rawdata); + tif->tif_rawdata = NULL; + tif->tif_rawdatasize = 0; + } + tif->tif_flags &= ~TIFF_MYBUFFER; tif->tif_rawdatasize = (tmsize_t)bytecount; tif->tif_rawdata = tif->tif_base + (tmsize_t)td->td_stripoffset[strip]; tif->tif_rawdataoff = 0; @@ -624,17 +908,36 @@ TIFFFillStrip(TIFF* tif, uint32 strip) (unsigned long) strip); return (0); } - if (!TIFFReadBufferSetup(tif, 0, bytecountm)) - return (0); } if (tif->tif_flags&TIFF_BUFFERMMAP) { tif->tif_curstrip = NOSTRIP; - if (!TIFFReadBufferSetup(tif, 0, bytecountm)) + tif->tif_rawdata = NULL; + tif->tif_rawdatasize = 0; + tif->tif_flags &= ~TIFF_BUFFERMMAP; + } + + if( isMapped(tif) ) + { + if (bytecountm > tif->tif_rawdatasize && + !TIFFReadBufferSetup(tif, 0, bytecountm)) + { + return (0); + } + if (TIFFReadRawStrip1(tif, strip, tif->tif_rawdata, + bytecountm, module) != bytecountm) + { return (0); + } } - if (TIFFReadRawStrip1(tif, strip, tif->tif_rawdata, - bytecountm, module) != bytecountm) - return (0); + else + { + if (TIFFReadRawStripOrTile2(tif, strip, 1, + bytecountm, module) != bytecountm) + { + return (0); + } + } + tif->tif_rawdataoff = 0; tif->tif_rawdataloaded = bytecountm; @@ -714,6 +1017,77 @@ TIFFReadEncodedTile(TIFF* tif, uint32 tile, void* buf, tmsize_t size) return ((tmsize_t)(-1)); } +/* Variant of TIFFReadTile() that does + * * if *buf == NULL, *buf = _TIFFmalloc(bufsizetoalloc) only after TIFFFillTile() has + * succeeded. This avoid excessive memory allocation in case of truncated + * file. + * * calls regular TIFFReadEncodedTile() if *buf != NULL + */ +tmsize_t +_TIFFReadTileAndAllocBuffer(TIFF* tif, + void **buf, tmsize_t bufsizetoalloc, + uint32 x, uint32 y, uint32 z, uint16 s) +{ + if (!TIFFCheckRead(tif, 1) || !TIFFCheckTile(tif, x, y, z, s)) + return ((tmsize_t)(-1)); + return (_TIFFReadEncodedTileAndAllocBuffer(tif, + TIFFComputeTile(tif, x, y, z, s), + buf, bufsizetoalloc, + (tmsize_t)(-1))); +} + +/* Variant of TIFFReadEncodedTile() that does + * * if *buf == NULL, *buf = _TIFFmalloc(bufsizetoalloc) only after TIFFFillTile() has + * succeeded. This avoid excessive memory allocation in case of truncated + * file. + * * calls regular TIFFReadEncodedTile() if *buf != NULL + */ +tmsize_t +_TIFFReadEncodedTileAndAllocBuffer(TIFF* tif, uint32 tile, + void **buf, tmsize_t bufsizetoalloc, + tmsize_t size_to_read) +{ + static const char module[] = "_TIFFReadEncodedTileAndAllocBuffer"; + TIFFDirectory *td = &tif->tif_dir; + tmsize_t tilesize = tif->tif_tilesize; + + if( *buf != NULL ) + { + return TIFFReadEncodedTile(tif, tile, *buf, size_to_read); + } + + if (!TIFFCheckRead(tif, 1)) + return ((tmsize_t)(-1)); + if (tile >= td->td_nstrips) { + TIFFErrorExt(tif->tif_clientdata, module, + "%lu: Tile out of range, max %lu", + (unsigned long) tile, (unsigned long) td->td_nstrips); + return ((tmsize_t)(-1)); + } + + if (!TIFFFillTile(tif,tile)) + return((tmsize_t)(-1)); + + *buf = _TIFFmalloc(bufsizetoalloc); + if (*buf == NULL) { + TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), + "No space for tile buffer"); + return((tmsize_t)(-1)); + } + _TIFFmemset(*buf, 0, bufsizetoalloc); + + if (size_to_read == (tmsize_t)(-1)) + size_to_read = tilesize; + else if (size_to_read > tilesize) + size_to_read = tilesize; + if( (*tif->tif_decodetile)(tif, + (uint8*) *buf, size_to_read, (uint16)(tile/td->td_stripsperimage))) { + (*tif->tif_postdecode)(tif, (uint8*) *buf, size_to_read); + return (size_to_read); + } else + return ((tmsize_t)(-1)); +} + static tmsize_t TIFFReadRawTile1(TIFF* tif, uint32 tile, void* buf, tmsize_t size, const char* module) { @@ -856,6 +1230,56 @@ TIFFFillTile(TIFF* tif, uint32 tile) #endif return (0); } + + /* To avoid excessive memory allocations: */ + /* Byte count should normally not be larger than a number of */ + /* times the uncompressed size plus some margin */ + if( bytecount > 1024 * 1024 ) + { + /* 10 and 4096 are just values that could be adjusted. */ + /* Hopefully they are safe enough for all codecs */ + tmsize_t stripsize = TIFFTileSize(tif); + if( stripsize != 0 && + (bytecount - 4096) / 10 > (uint64)stripsize ) + { + uint64 newbytecount = (uint64)stripsize * 10 + 4096; + if( (int64)newbytecount >= 0 ) + { +#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) + TIFFWarningExt(tif->tif_clientdata, module, + "Too large tile byte count %I64u, tile %lu. Limiting to %I64u", + (unsigned __int64) bytecount, + (unsigned long) tile, + (unsigned __int64) newbytecount); +#else + TIFFErrorExt(tif->tif_clientdata, module, + "Too large tile byte count %llu, tile %lu. Limiting to %llu", + (unsigned long long) bytecount, + (unsigned long) tile, + (unsigned long long) newbytecount); +#endif + bytecount = newbytecount; + } + } + } + + if (isMapped(tif)) { + /* + * We must check for overflow, potentially causing + * an OOB read. Instead of simple + * + * td->td_stripoffset[tile]+bytecount > tif->tif_size + * + * comparison (which can overflow) we do the following + * two comparisons: + */ + if (bytecount > (uint64)tif->tif_size || + td->td_stripoffset[tile] > (uint64)tif->tif_size - bytecount) { + tif->tif_curtile = NOTILE; + return (0); + } + } + if (isMapped(tif) && (isFillOrder(tif, td->td_fillorder) || (tif->tif_flags & TIFF_NOBITREV))) { @@ -876,20 +1300,7 @@ TIFFFillTile(TIFF* tif, uint32 tile) tif->tif_rawdatasize = 0; } tif->tif_flags &= ~TIFF_MYBUFFER; - /* - * We must check for overflow, potentially causing - * an OOB read. Instead of simple - * - * td->td_stripoffset[tile]+bytecount > tif->tif_size - * - * comparison (which can overflow) we do the following - * two comparisons: - */ - if (bytecount > (uint64)tif->tif_size || - td->td_stripoffset[tile] > (uint64)tif->tif_size - bytecount) { - tif->tif_curtile = NOTILE; - return (0); - } + tif->tif_rawdatasize = (tmsize_t)bytecount; tif->tif_rawdata = tif->tif_base + (tmsize_t)td->td_stripoffset[tile]; @@ -917,18 +1328,36 @@ TIFFFillTile(TIFF* tif, uint32 tile) (unsigned long) tile); return (0); } - if (!TIFFReadBufferSetup(tif, 0, bytecountm)) - return (0); } if (tif->tif_flags&TIFF_BUFFERMMAP) { tif->tif_curtile = NOTILE; - if (!TIFFReadBufferSetup(tif, 0, bytecountm)) + tif->tif_rawdata = NULL; + tif->tif_rawdatasize = 0; + tif->tif_flags &= ~TIFF_BUFFERMMAP; + } + + if( isMapped(tif) ) + { + if (bytecountm > tif->tif_rawdatasize && + !TIFFReadBufferSetup(tif, 0, bytecountm)) + { + return (0); + } + if (TIFFReadRawTile1(tif, tile, tif->tif_rawdata, + bytecountm, module) != bytecountm) + { return (0); + } + } + else + { + if (TIFFReadRawStripOrTile2(tif, tile, 0, + bytecountm, module) != bytecountm) + { + return (0); + } } - if (TIFFReadRawTile1(tif, tile, tif->tif_rawdata, - bytecountm, module) != bytecountm) - return (0); tif->tif_rawdataoff = 0; tif->tif_rawdataloaded = bytecountm; @@ -976,7 +1405,9 @@ TIFFReadBufferSetup(TIFF* tif, void* bp, tmsize_t size) "Invalid buffer size"); return (0); } - tif->tif_rawdata = (uint8*) _TIFFmalloc(tif->tif_rawdatasize); + /* Initialize to zero to avoid uninitialized buffers in case of */ + /* short reads (http://bugzilla.maptools.org/show_bug.cgi?id=2651) */ + tif->tif_rawdata = (uint8*) _TIFFcalloc(1, tif->tif_rawdatasize); tif->tif_flags |= TIFF_MYBUFFER; } if (tif->tif_rawdata == NULL) { @@ -1018,7 +1449,10 @@ TIFFStartStrip(TIFF* tif, uint32 strip) else { tif->tif_rawcp = tif->tif_rawdata; - tif->tif_rawcc = (tmsize_t)td->td_stripbytecount[strip]; + if( tif->tif_rawdataloaded > 0 ) + tif->tif_rawcc = tif->tif_rawdataloaded; + else + tif->tif_rawcc = (tmsize_t)td->td_stripbytecount[strip]; } return ((*tif->tif_predecode)(tif, (uint16)(strip / td->td_stripsperimage))); @@ -1065,7 +1499,10 @@ TIFFStartTile(TIFF* tif, uint32 tile) else { tif->tif_rawcp = tif->tif_rawdata; - tif->tif_rawcc = (tmsize_t)td->td_stripbytecount[tile]; + if( tif->tif_rawdataloaded > 0 ) + tif->tif_rawcc = tif->tif_rawdataloaded; + else + tif->tif_rawcc = (tmsize_t)td->td_stripbytecount[tile]; } return ((*tif->tif_predecode)(tif, (uint16)(tile/td->td_stripsperimage))); diff --git a/libtiff/tif_strip.c b/libtiff/tif_strip.c index b6098dd..6e9f2ef 100644 --- a/libtiff/tif_strip.c +++ b/libtiff/tif_strip.c @@ -1,4 +1,4 @@ -/* $Id: tif_strip.c,v 1.37 2016-11-09 23:00:49 erouault Exp $ */ +/* $Id: tif_strip.c,v 1.38 2016-12-03 11:02:15 erouault Exp $ */ /* * Copyright (c) 1991-1997 Sam Leffler @@ -63,15 +63,6 @@ TIFFNumberOfStrips(TIFF* tif) TIFFDirectory *td = &tif->tif_dir; uint32 nstrips; - /* If the value was already computed and store in td_nstrips, then return it, - since ChopUpSingleUncompressedStrip might have altered and resized the - since the td_stripbytecount and td_stripoffset arrays to the new value - after the initial affectation of td_nstrips = TIFFNumberOfStrips() in - tif_dirread.c ~line 3612. - See http://bugzilla.maptools.org/show_bug.cgi?id=2587 */ - if( td->td_nstrips ) - return td->td_nstrips; - nstrips = (td->td_rowsperstrip == (uint32) -1 ? 1 : TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip)); if (td->td_planarconfig == PLANARCONFIG_SEPARATE) diff --git a/libtiff/tif_swab.c b/libtiff/tif_swab.c index 211dc57..4b2e5f1 100644 --- a/libtiff/tif_swab.c +++ b/libtiff/tif_swab.c @@ -1,4 +1,4 @@ -/* $Id: tif_swab.c,v 1.14 2016-09-04 21:32:56 erouault Exp $ */ +/* $Id: tif_swab.c,v 1.15 2017-06-08 16:39:50 erouault Exp $ */ /* * Copyright (c) 1988-1997 Sam Leffler @@ -31,7 +31,7 @@ */ #include "tiffiop.h" -#ifndef TIFFSwabShort +#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabShort) void TIFFSwabShort(uint16* wp) { @@ -42,7 +42,7 @@ TIFFSwabShort(uint16* wp) } #endif -#ifndef TIFFSwabLong +#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabLong) void TIFFSwabLong(uint32* lp) { @@ -54,7 +54,7 @@ TIFFSwabLong(uint32* lp) } #endif -#ifndef TIFFSwabLong8 +#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabLong8) void TIFFSwabLong8(uint64* lp) { @@ -68,7 +68,7 @@ TIFFSwabLong8(uint64* lp) } #endif -#ifndef TIFFSwabArrayOfShort +#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfShort) void TIFFSwabArrayOfShort(register uint16* wp, tmsize_t n) { @@ -84,7 +84,7 @@ TIFFSwabArrayOfShort(register uint16* wp, tmsize_t n) } #endif -#ifndef TIFFSwabArrayOfTriples +#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfTriples) void TIFFSwabArrayOfTriples(register uint8* tp, tmsize_t n) { @@ -100,7 +100,7 @@ TIFFSwabArrayOfTriples(register uint8* tp, tmsize_t n) } #endif -#ifndef TIFFSwabArrayOfLong +#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfLong) void TIFFSwabArrayOfLong(register uint32* lp, tmsize_t n) { @@ -117,7 +117,7 @@ TIFFSwabArrayOfLong(register uint32* lp, tmsize_t n) } #endif -#ifndef TIFFSwabArrayOfLong8 +#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfLong8) void TIFFSwabArrayOfLong8(register uint64* lp, tmsize_t n) { @@ -136,7 +136,7 @@ TIFFSwabArrayOfLong8(register uint64* lp, tmsize_t n) } #endif -#ifndef TIFFSwabFloat +#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabFloat) void TIFFSwabFloat(float* fp) { @@ -148,7 +148,7 @@ TIFFSwabFloat(float* fp) } #endif -#ifndef TIFFSwabArrayOfFloat +#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfFloat) void TIFFSwabArrayOfFloat(register float* fp, tmsize_t n) { @@ -165,7 +165,7 @@ TIFFSwabArrayOfFloat(register float* fp, tmsize_t n) } #endif -#ifndef TIFFSwabDouble +#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabDouble) void TIFFSwabDouble(double *dp) { @@ -179,7 +179,7 @@ TIFFSwabDouble(double *dp) } #endif -#ifndef TIFFSwabArrayOfDouble +#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfDouble) void TIFFSwabArrayOfDouble(double* dp, tmsize_t n) { diff --git a/libtiff/tif_unix.c b/libtiff/tif_unix.c index 81e9d66..80c437c 100644 --- a/libtiff/tif_unix.c +++ b/libtiff/tif_unix.c @@ -1,4 +1,4 @@ -/* $Id: tif_unix.c,v 1.27 2015-08-19 02:31:04 bfriesen Exp $ */ +/* $Id: tif_unix.c,v 1.28 2017-01-11 19:02:49 erouault Exp $ */ /* * Copyright (c) 1988-1997 Sam Leffler @@ -316,6 +316,14 @@ _TIFFmalloc(tmsize_t s) return (malloc((size_t) s)); } +void* _TIFFcalloc(tmsize_t nmemb, tmsize_t siz) +{ + if( nmemb == 0 || siz == 0 ) + return ((void *) NULL); + + return calloc((size_t) nmemb, (size_t)siz); +} + void _TIFFfree(void* p) { diff --git a/libtiff/tif_warning.c b/libtiff/tif_warning.c index 423b636..dc79f14 100644 --- a/libtiff/tif_warning.c +++ b/libtiff/tif_warning.c @@ -1,4 +1,4 @@ -/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_warning.c,v 1.3 2010-03-10 18:56:49 bfriesen Exp $ */ +/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_warning.c,v 1.4 2017-07-04 12:54:42 erouault Exp $ */ /* * Copyright (c) 1988-1997 Sam Leffler @@ -51,24 +51,32 @@ void TIFFWarning(const char* module, const char* fmt, ...) { va_list ap; - va_start(ap, fmt); - if (_TIFFwarningHandler) + if (_TIFFwarningHandler) { + va_start(ap, fmt); (*_TIFFwarningHandler)(module, fmt, ap); - if (_TIFFwarningHandlerExt) + va_end(ap); + } + if (_TIFFwarningHandlerExt) { + va_start(ap, fmt); (*_TIFFwarningHandlerExt)(0, module, fmt, ap); - va_end(ap); + va_end(ap); + } } void TIFFWarningExt(thandle_t fd, const char* module, const char* fmt, ...) { va_list ap; - va_start(ap, fmt); - if (_TIFFwarningHandler) + if (_TIFFwarningHandler) { + va_start(ap, fmt); (*_TIFFwarningHandler)(module, fmt, ap); - if (_TIFFwarningHandlerExt) + va_end(ap); + } + if (_TIFFwarningHandlerExt) { + va_start(ap, fmt); (*_TIFFwarningHandlerExt)(fd, module, fmt, ap); - va_end(ap); + va_end(ap); + } } diff --git a/libtiff/tif_win32.c b/libtiff/tif_win32.c index 24b824f..090baed 100644 --- a/libtiff/tif_win32.c +++ b/libtiff/tif_win32.c @@ -1,4 +1,4 @@ -/* $Id: tif_win32.c,v 1.41 2015-08-23 20:12:44 bfriesen Exp $ */ +/* $Id: tif_win32.c,v 1.42 2017-01-11 19:02:49 erouault Exp $ */ /* * Copyright (c) 1988-1997 Sam Leffler @@ -360,6 +360,14 @@ _TIFFmalloc(tmsize_t s) return (malloc((size_t) s)); } +void* _TIFFcalloc(tmsize_t nmemb, tmsize_t siz) +{ + if( nmemb == 0 || siz == 0 ) + return ((void *) NULL); + + return calloc((size_t) nmemb, (size_t)siz); +} + void _TIFFfree(void* p) { diff --git a/libtiff/tif_write.c b/libtiff/tif_write.c index 34c4d81..4c216ec 100644 --- a/libtiff/tif_write.c +++ b/libtiff/tif_write.c @@ -1,4 +1,4 @@ -/* $Id: tif_write.c,v 1.45 2016-09-23 22:12:18 erouault Exp $ */ +/* $Id: tif_write.c,v 1.46 2016-12-03 21:57:44 erouault Exp $ */ /* * Copyright (c) 1988-1997 Sam Leffler @@ -476,22 +476,22 @@ TIFFWriteEncodedTile(TIFF* tif, uint32 tile, void* data, tmsize_t cc) sample = (uint16)(tile/td->td_stripsperimage); if (!(*tif->tif_preencode)(tif, sample)) return ((tmsize_t)(-1)); - /* swab if needed - note that source buffer will be altered */ - tif->tif_postdecode( tif, (uint8*) data, cc ); + /* swab if needed - note that source buffer will be altered */ + tif->tif_postdecode( tif, (uint8*) data, cc ); - if (!(*tif->tif_encodetile)(tif, (uint8*) data, cc, sample)) - return ((tmsize_t) -1); - if (!(*tif->tif_postencode)(tif)) - return ((tmsize_t)(-1)); - if (!isFillOrder(tif, td->td_fillorder) && - (tif->tif_flags & TIFF_NOBITREV) == 0) - TIFFReverseBits((uint8*)tif->tif_rawdata, tif->tif_rawcc); - if (tif->tif_rawcc > 0 && !TIFFAppendToStrip(tif, tile, - tif->tif_rawdata, tif->tif_rawcc)) - return ((tmsize_t)(-1)); - tif->tif_rawcc = 0; - tif->tif_rawcp = tif->tif_rawdata; - return (cc); + if (!(*tif->tif_encodetile)(tif, (uint8*) data, cc, sample)) + return ((tmsize_t) -1); + if (!(*tif->tif_postencode)(tif)) + return ((tmsize_t)(-1)); + if (!isFillOrder(tif, td->td_fillorder) && + (tif->tif_flags & TIFF_NOBITREV) == 0) + TIFFReverseBits((uint8*)tif->tif_rawdata, tif->tif_rawcc); + if (tif->tif_rawcc > 0 && !TIFFAppendToStrip(tif, tile, + tif->tif_rawdata, tif->tif_rawcc)) + return ((tmsize_t)(-1)); + tif->tif_rawcc = 0; + tif->tif_rawcp = tif->tif_rawdata; + return (cc); } /* diff --git a/libtiff/tif_zip.c b/libtiff/tif_zip.c index 8c35aea..42943fb 100644 --- a/libtiff/tif_zip.c +++ b/libtiff/tif_zip.c @@ -1,4 +1,4 @@ -/* $Id: tif_zip.c,v 1.36 2016-11-12 16:48:28 erouault Exp $ */ +/* $Id: tif_zip.c,v 1.37 2017-05-10 15:21:16 erouault Exp $ */ /* * Copyright (c) 1995-1997 Sam Leffler @@ -107,7 +107,11 @@ ZIPSetupDecode(TIFF* tif) sp->state = 0; } - if (inflateInit(&sp->stream) != Z_OK) { + /* This function can possibly be called several times by */ + /* PredictorSetupDecode() if this function succeeds but */ + /* PredictorSetup() fails */ + if ((sp->state & ZSTATE_INIT_DECODE) == 0 && + inflateInit(&sp->stream) != Z_OK) { TIFFErrorExt(tif->tif_clientdata, module, "%s", SAFE_MSG(sp)); return (0); } else { diff --git a/libtiff/tiffio.h b/libtiff/tiffio.h index 6a84d80..ef61b5c 100644 --- a/libtiff/tiffio.h +++ b/libtiff/tiffio.h @@ -1,4 +1,4 @@ -/* $Id: tiffio.h,v 1.92 2016-01-23 21:20:34 erouault Exp $ */ +/* $Id: tiffio.h,v 1.94 2017-01-11 19:02:49 erouault Exp $ */ /* * Copyright (c) 1988-1997 Sam Leffler @@ -293,6 +293,7 @@ extern TIFFCodec* TIFFGetConfiguredCODECs(void); */ extern void* _TIFFmalloc(tmsize_t s); +extern void* _TIFFcalloc(tmsize_t nmemb, tmsize_t siz); extern void* _TIFFrealloc(void* p, tmsize_t s); extern void _TIFFmemset(void* p, int v, tmsize_t c); extern void _TIFFmemcpy(void* d, const void* s, tmsize_t c); @@ -430,6 +431,8 @@ extern int TIFFReadRGBAImageOriented(TIFF*, uint32, uint32, uint32*, int, int); extern int TIFFReadRGBAStrip(TIFF*, uint32, uint32 * ); extern int TIFFReadRGBATile(TIFF*, uint32, uint32, uint32 * ); +extern int TIFFReadRGBAStripExt(TIFF*, uint32, uint32 *, int stop_on_error ); +extern int TIFFReadRGBATileExt(TIFF*, uint32, uint32, uint32 *, int stop_on_error ); extern int TIFFRGBAImageOK(TIFF*, char [1024]); extern int TIFFRGBAImageBegin(TIFFRGBAImage*, TIFF*, int, char [1024]); extern int TIFFRGBAImageGet(TIFFRGBAImage*, uint32*, uint32, uint32); diff --git a/libtiff/tiffiop.h b/libtiff/tiffiop.h index 8bcd0c1..daa291c 100644 --- a/libtiff/tiffiop.h +++ b/libtiff/tiffiop.h @@ -1,4 +1,4 @@ -/* $Id: tiffiop.h,v 1.89 2016-01-23 21:20:34 erouault Exp $ */ +/* $Id: tiffiop.h,v 1.95 2017-09-07 14:02:52 erouault Exp $ */ /* * Copyright (c) 1988-1997 Sam Leffler @@ -238,8 +238,7 @@ struct tiff { (TIFFReadFile((tif),(buf),(size))==(size)) #endif #ifndef SeekOK -#define SeekOK(tif, off) \ - (TIFFSeekFile((tif),(off),SEEK_SET)==(off)) +#define SeekOK(tif, off) _TIFFSeekOK(tif, off) #endif #ifndef WriteOK #define WriteOK(tif, buf, size) \ @@ -250,6 +249,10 @@ struct tiff { #define TIFFhowmany_32(x, y) (((uint32)x < (0xffffffff - (uint32)(y-1))) ? \ ((((uint32)(x))+(((uint32)(y))-1))/((uint32)(y))) : \ 0U) +/* Variant of TIFFhowmany_32() that doesn't return 0 if x close to MAXUINT. */ +/* Caution: TIFFhowmany_32_maxuint_compat(x,y)*y might overflow */ +#define TIFFhowmany_32_maxuint_compat(x, y) \ + (((uint32)(x) / (uint32)(y)) + ((((uint32)(x) % (uint32)(y)) != 0) ? 1 : 0)) #define TIFFhowmany8_32(x) (((x)&0x07)?((uint32)(x)>>3)+1:(uint32)(x)>>3) #define TIFFroundup_32(x, y) (TIFFhowmany_32(x,y)*(y)) #define TIFFhowmany_64(x, y) ((((uint64)(x))+(((uint64)(y))-1))/((uint64)(y))) @@ -311,6 +314,13 @@ typedef size_t TIFFIOSize_t; #define _TIFF_off_t off_t #endif +#if __clang_major__ >= 4 || (__clang_major__ == 3 && __clang_minor__ >= 8) +#define TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW __attribute__((no_sanitize("unsigned-integer-overflow"))) +#else +#define TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW +#endif + + #if defined(__cplusplus) extern "C" { #endif @@ -361,6 +371,20 @@ extern void* _TIFFCheckRealloc(TIFF*, void*, tmsize_t, tmsize_t, const char*); extern double _TIFFUInt64ToDouble(uint64); extern float _TIFFUInt64ToFloat(uint64); +extern tmsize_t +_TIFFReadEncodedStripAndAllocBuffer(TIFF* tif, uint32 strip, + void **buf, tmsize_t bufsizetoalloc, + tmsize_t size_to_read); +extern tmsize_t +_TIFFReadEncodedTileAndAllocBuffer(TIFF* tif, uint32 tile, + void **buf, tmsize_t bufsizetoalloc, + tmsize_t size_to_read); +extern tmsize_t +_TIFFReadTileAndAllocBuffer(TIFF* tif, + void **buf, tmsize_t bufsizetoalloc, + uint32 x, uint32 y, uint32 z, uint16 s); +extern int _TIFFSeekOK(TIFF* tif, toff_t off); + extern int TIFFInitDumpMode(TIFF*, int); #ifdef PACKBITS_SUPPORT extern int TIFFInitPackBits(TIFF*, int); @@ -383,6 +407,7 @@ extern int TIFFInitOJPEG(TIFF*, int); #endif #ifdef JPEG_SUPPORT extern int TIFFInitJPEG(TIFF*, int); +extern int TIFFJPEGIsFullStripRequired(TIFF*); #endif #ifdef JBIG_SUPPORT extern int TIFFInitJBIG(TIFF*, int); diff --git a/libtiff/tiffvers.h b/libtiff/tiffvers.h index fe55c72..7c41574 100644 --- a/libtiff/tiffvers.h +++ b/libtiff/tiffvers.h @@ -1,4 +1,4 @@ -#define TIFFLIB_VERSION_STR "LIBTIFF, Version 4.0.7\nCopyright (c) 1988-1996 Sam Leffler\nCopyright (c) 1991-1996 Silicon Graphics, Inc." +#define TIFFLIB_VERSION_STR "LIBTIFF, Version 4.0.9\nCopyright (c) 1988-1996 Sam Leffler\nCopyright (c) 1991-1996 Silicon Graphics, Inc." /* * This define can be used in code that requires * compilation-related definitions specific to a @@ -6,4 +6,4 @@ * version checking should be done based on the * string returned by TIFFGetVersion. */ -#define TIFFLIB_VERSION 20161119 +#define TIFFLIB_VERSION 20171118 diff --git a/m4/libtool.m4 b/m4/libtool.m4 index a3bc337..10ab284 100644 --- a/m4/libtool.m4 +++ b/m4/libtool.m4 @@ -2887,6 +2887,18 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) dynamic_linker='GNU/Linux ld.so' ;; +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + netbsd*) version_type=sunos need_lib_prefix=no @@ -3546,7 +3558,7 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) lt_cv_deplibs_check_method=pass_all ;; -netbsd*) +netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' else @@ -4424,7 +4436,7 @@ m4_if([$1], [CXX], [ ;; esac ;; - netbsd*) + netbsd* | netbsdelf*-gnu) ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise @@ -4936,6 +4948,9 @@ m4_if([$1], [CXX], [ ;; esac ;; + linux* | k*bsd*-gnu | gnu*) + _LT_TAGVAR(link_all_deplibs, $1)=no + ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; @@ -4998,6 +5013,9 @@ dnl Note also adjust exclude_expsyms for C++ above. openbsd* | bitrig*) with_gnu_ld=no ;; + linux* | k*bsd*-gnu | gnu*) + _LT_TAGVAR(link_all_deplibs, $1)=no + ;; esac _LT_TAGVAR(ld_shlibs, $1)=yes @@ -5252,7 +5270,7 @@ _LT_EOF fi ;; - netbsd*) + netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= @@ -5773,6 +5791,7 @@ _LT_EOF if test yes = "$lt_cv_irix_exported_symbol"; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' fi + _LT_TAGVAR(link_all_deplibs, $1)=no else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' @@ -5794,7 +5813,7 @@ _LT_EOF esac ;; - netbsd*) + netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else diff --git a/man/CMakeLists.txt b/man/CMakeLists.txt index 1db7556..be5e294 100644 --- a/man/CMakeLists.txt +++ b/man/CMakeLists.txt @@ -28,8 +28,6 @@ set(man1_MANS pal2rgb.1 ppm2tiff.1 raw2tiff.1 - rgb2ycbcr.1 - thumbnail.1 tiff2bw.1 tiff2pdf.1 tiff2ps.1 diff --git a/man/Makefile.am b/man/Makefile.am index 08b8749..0fe9e4d 100644 --- a/man/Makefile.am +++ b/man/Makefile.am @@ -29,8 +29,6 @@ dist_man1_MANS = \ pal2rgb.1 \ ppm2tiff.1 \ raw2tiff.1 \ - rgb2ycbcr.1 \ - thumbnail.1 \ tiff2bw.1 \ tiff2pdf.1 \ tiff2ps.1 \ diff --git a/man/Makefile.in b/man/Makefile.in index 3f19b8c..212905b 100644 --- a/man/Makefile.in +++ b/man/Makefile.in @@ -335,8 +335,6 @@ dist_man1_MANS = \ pal2rgb.1 \ ppm2tiff.1 \ raw2tiff.1 \ - rgb2ycbcr.1 \ - thumbnail.1 \ tiff2bw.1 \ tiff2pdf.1 \ tiff2ps.1 \ diff --git a/man/TIFFGetField.3tiff b/man/TIFFGetField.3tiff index bdf41a2..528019e 100644 --- a/man/TIFFGetField.3tiff +++ b/man/TIFFGetField.3tiff @@ -1,4 +1,4 @@ -.\" $Id: TIFFGetField.3tiff,v 1.7 2016-09-25 20:05:49 bfriesen Exp $ +.\" $Id: TIFFGetField.3tiff,v 1.8 2017-06-30 17:40:02 erouault Exp $ .\" .\" Copyright (c) 1988-1997 Sam Leffler .\" Copyright (c) 1991-1997 Silicon Graphics, Inc. @@ -160,7 +160,7 @@ TIFFTAG_STONITS 1 double** TIFFTAG_STRIPBYTECOUNTS 1 uint32** TIFFTAG_STRIPOFFSETS 1 uint32** TIFFTAG_SUBFILETYPE 1 uint32* -TIFFTAG_SUBIFD 2 uint16*,uint32** count & offsets array +TIFFTAG_SUBIFD 2 uint16*,uint64** count & offsets array TIFFTAG_TARGETPRINTER 1 char** TIFFTAG_THRESHHOLDING 1 uint16* TIFFTAG_TILEBYTECOUNTS 1 uint32** diff --git a/man/TIFFSetDirectory.3tiff b/man/TIFFSetDirectory.3tiff index 93faf19..0f109f6 100644 --- a/man/TIFFSetDirectory.3tiff +++ b/man/TIFFSetDirectory.3tiff @@ -1,4 +1,4 @@ -.\" $Id: TIFFSetDirectory.3tiff,v 1.3 2016-09-25 20:05:50 bfriesen Exp $ +.\" $Id: TIFFSetDirectory.3tiff,v 1.4 2017-06-30 17:40:02 erouault Exp $ .\" .\" Copyright (c) 1988-1997 Sam Leffler .\" Copyright (c) 1991-1997 Silicon Graphics, Inc. @@ -33,7 +33,7 @@ file .sp .BI "int TIFFSetDirectory(TIFF *" tif ", tdir_t " dirnum ")" .br -.BI "int TIFFSetSubDirectory(TIFF *" tif ", uint32 " diroff ")" +.BI "int TIFFSetSubDirectory(TIFF *" tif ", uint64 " diroff ")" .SH DESCRIPTION .I TIFFSetDirectory changes the current directory and reads its contents with diff --git a/man/TIFFSetField.3tiff b/man/TIFFSetField.3tiff index 1754827..695a199 100644 --- a/man/TIFFSetField.3tiff +++ b/man/TIFFSetField.3tiff @@ -1,4 +1,4 @@ -.\" $Id: TIFFSetField.3tiff,v 1.6 2016-09-25 20:05:50 bfriesen Exp $ +.\" $Id: TIFFSetField.3tiff,v 1.7 2017-06-30 17:40:02 erouault Exp $ .\" .\" Copyright (c) 1988-1997 Sam Leffler .\" Copyright (c) 1991-1997 Silicon Graphics, Inc. @@ -157,7 +157,7 @@ TIFFTAG_SMINSAMPLEVALUE 1 double TIFFTAG_SOFTWARE 1 char* TIFFTAG_STONITS 1 double \(dg TIFFTAG_SUBFILETYPE 1 uint32 -TIFFTAG_SUBIFD 2 uint16,uint32* count & offsets array +TIFFTAG_SUBIFD 2 uint16,uint64* count & offsets array TIFFTAG_TARGETPRINTER 1 char* TIFFTAG_THRESHHOLDING 1 uint16 TIFFTAG_TILEDEPTH 1 uint32 \(dg diff --git a/man/rgb2ycbcr.1 b/man/rgb2ycbcr.1 deleted file mode 100644 index e3be491..0000000 --- a/man/rgb2ycbcr.1 +++ /dev/null @@ -1,99 +0,0 @@ -.\" $Header: /cvs/maptools/cvsroot/libtiff/man/rgb2ycbcr.1,v 1.5 2016-09-25 20:05:51 bfriesen Exp $ -.\" -.\" Copyright (c) 1991-1997 Sam Leffler -.\" Copyright (c) 1991-1997 Silicon Graphics, Inc. -.\" -.\" Permission to use, copy, modify, distribute, and sell this software and -.\" its documentation for any purpose is hereby granted without fee, provided -.\" that (i) the above copyright notices and this permission notice appear in -.\" all copies of the software and related documentation, and (ii) the names of -.\" Sam Leffler and Silicon Graphics may not be used in any advertising or -.\" publicity relating to the software without the specific, prior written -.\" permission of Sam Leffler and Silicon Graphics. -.\" -.\" THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, -.\" EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY -.\" WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. -.\" -.\" IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR -.\" ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, -.\" OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -.\" WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF -.\" LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE -.\" OF THIS SOFTWARE. -.\" -.if n .po 0 -.TH RGB2YCBCR 1 "November 2, 2005" "libtiff" -.SH NAME -rgb2ycbcr \- convert non-YCbCr -.SM TIFF -images to a YCbCr -.SM TIFF -image -.SH SYNOPSIS -.B rgb2ycbcr -[ -.I options -] -.I "src1.tif src2.tif ... dst.tif" -.SH DESCRIPTION -.I rgb2ycbcr -converts -.SM RGB -color, greyscale, or bi-level -.SM TIFF -images to YCbCr images by transforming and sampling pixel data. If multiple -files are specified on the command line each source file is converted to a -separate directory in the destination file. -.PP -By default, chrominance samples are created by sampling -2 by 2 blocks of luminance values; this can be changed with the -.B \-h -and -.B \-v -options. -Output data are compressed with the -.SM PackBits -compression scheme, by default; an alternate scheme can be selected with the -.B \-c -option. -By default, output data are compressed in strips with -the number of rows in each strip selected so that the -size of a strip is never more than 8 kilobytes; -the -.B \-r -option can be used to explicitly set the number of -rows per strip. -.SH OPTIONS -.TP -.B \-c -Specify a compression scheme to use when writing image data: -.B "\-c none" -for no compression, -.B "\-c packbits" -for the PackBits compression algorithm (the default), -.B "\-c jpeg" -for the JPEG compression algorithm, -.B "\-c zip" -for the deflate compression algorithm, -and -.B "\-c lzw" -for Lempel-Ziv & Welch. -.TP -.B \-h -Set the horizontal sampling dimension to one of: 1, 2 (default), or 4. -.TP -.B \-r -Write data with a specified number of rows per strip; -by default the number of rows/strip is selected so that each strip -is approximately 8 kilobytes. -.TP -.B \-v -Set the vertical sampling dimension to one of: 1, 2 (default), or 4. -.SH "SEE ALSO" -.BR tiffinfo (1), -.BR tiffcp (1), -.BR libtiff (3) -.PP -Libtiff library home page: -.BR http://www.simplesystems.org/libtiff diff --git a/man/thumbnail.1 b/man/thumbnail.1 deleted file mode 100644 index 5ae87ed..0000000 --- a/man/thumbnail.1 +++ /dev/null @@ -1,90 +0,0 @@ -.\" $Id: thumbnail.1,v 1.3 2016-09-25 20:05:51 bfriesen Exp $ -.\" -.\" Copyright (c) 1994-1997 Sam Leffler -.\" Copyright (c) 1994-1997 Silicon Graphics, Inc. -.\" -.\" Permission to use, copy, modify, distribute, and sell this software and -.\" its documentation for any purpose is hereby granted without fee, provided -.\" that (i) the above copyright notices and this permission notice appear in -.\" all copies of the software and related documentation, and (ii) the names of -.\" Sam Leffler and Silicon Graphics may not be used in any advertising or -.\" publicity relating to the software without the specific, prior written -.\" permission of Sam Leffler and Silicon Graphics. -.\" -.\" THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, -.\" EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY -.\" WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. -.\" -.\" IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR -.\" ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, -.\" OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -.\" WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF -.\" LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE -.\" OF THIS SOFTWARE. -.\" -.if n .po 0 -.TH THUMBNAIL 1 "November 2, 2005" "libtiff" -.SH NAME -thumbnail \- create a -.SM TIFF -file with thumbnail images -.SH SYNOPSIS -.B thumbnail -[ -.I options -] -.I input.tif -.I output.tif -.SH DESCRIPTION -.I thumbnail -is a program written to show how one might use the -SubIFD tag (#330) to store thumbnail images. -.I thumbnail -copies a -.SM TIFF -Class F facsimile file to the output file -and for each image an 8-bit greyscale -.IR "thumbnail sketch" . -The output file contains the thumbnail image with the associated -full-resolution page linked below with the SubIFD tag. -.PP -By default, thumbnail images are 216 pixels wide by 274 pixels high. -Pixels are calculated by sampling and filtering the input image -with each pixel value passed through a contrast curve. -.SH OPTIONS -.TP -.B \-w -Specify the width of thumbnail images in pixels. -.TP -.B \-h -Specify the height of thumbnail images in pixels. -.TP -.B \-c -Specify a contrast curve to apply in generating the thumbnail images. -By default pixels values are passed through a linear contrast curve -that simply maps the pixel value ranges. -Alternative curves are: -.B exp50 -for a 50% exponential curve, -.B exp60 -for a 60% exponential curve, -.B exp70 -for a 70% exponential curve, -.B exp80 -for a 80% exponential curve, -.B exp90 -for a 90% exponential curve, -.B exp -for a pure exponential curve, -.B linear -for a linear curve. -.SH BUGS -There are no options to control the format of the saved thumbnail images. -.SH "SEE ALSO" -.BR tiffdump (1), -.BR tiffgt (1), -.BR tiffinfo (1), -.BR libtiff (3) -.PP -Libtiff library home page: -.BR http://www.simplesystems.org/libtiff/ diff --git a/nmake.opt b/nmake.opt index 74b9700..ec45e77 100644 --- a/nmake.opt +++ b/nmake.opt @@ -1,4 +1,4 @@ -# $Id: nmake.opt,v 1.19 2015-08-28 22:19:26 bfriesen Exp $ +# $Id: nmake.opt,v 1.20 2017-10-10 14:39:43 erouault Exp $ # # Copyright (C) 2004, Andrey Kiselev # @@ -24,6 +24,13 @@ # Compile time parameters for MS Visual C++ compiler. # You may edit this file to specify building options. +# Options: +# DEBUG - set to disable optimizations and link with debug runtimes +# +# Usage examples (see details below): +# nmake -f makefile.vc +# nmake -f makefile.vc DEBUG=1 +# # ###### Edit the following lines to choose a feature set you need. ####### # @@ -114,7 +121,11 @@ CHECK_JPEG_YCBCR_SUBSAMPLING = 1 # with no debugging information. # NOTE: /EHsc option required if you want to build the C++ stream API # +!IFDEF DEBUG +OPTFLAGS = /MDd /EHsc /W3 /D_CRT_SECURE_NO_DEPRECATE +!ELSE OPTFLAGS = /Ox /MD /EHsc /W3 /D_CRT_SECURE_NO_DEPRECATE +!ENDIF #OPTFLAGS = /Zi # diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index b9e373f..912be19 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -43,6 +43,7 @@ set(TESTSCRIPTS tiffcp-g4.sh tiffcp-logluv.sh tiffcp-thumbnail.sh + tiffcp-lzw-compat.sh tiffdump.sh tiffinfo.sh tiffcp-split.sh @@ -118,7 +119,8 @@ set(TIFFIMAGES images/palette-1c-8b.tiff images/rgb-3c-16b.tiff images/rgb-3c-8b.tiff - images/quad-tile.jpg.tiff) + images/quad-tile.jpg.tiff + images/quad-lzw-compat.tiff) set(BMPIMAGES images/palette-1c-8b.bmp @@ -185,6 +187,18 @@ target_link_libraries(custom_dir tiff port) set(TEST_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/output") file(MAKE_DIRECTORY "${TEST_OUTPUT}") +set(tiff_test_extra_args + "-DTIFFCP=$" + "-DTIFFINFO=$" + "-DTIFFSPLIT=$" + "-DLIBTIFF=$") +if(WIN32) + list(APPEND tiff_test_extra_args "-DWIN32=${WIN32}") +endif() +if(CYGWIN) + list(APPEND tiff_test_extra_args "-DCYGWIN=${CYGWIN}") +endif() + macro(tiff_test_convert name command1 command2 command3 infile outfile validate) add_test(NAME "${name}" COMMAND "${CMAKE_COMMAND}" @@ -193,9 +207,8 @@ macro(tiff_test_convert name command1 command2 command3 infile outfile validate) "-DCONVERT_COMMAND3=${command3}" "-DINFILE=${infile}" "-DOUTFILE=${outfile}" - "-DTIFFINFO=$" - "-DLIBTIFF=$" "-DVALIDATE=${validate}" + ${tiff_test_extra_args} -P "${CMAKE_CURRENT_SOURCE_DIR}/TiffTest.cmake") endmacro() @@ -205,8 +218,7 @@ macro(tiff_test_stdout name command infile outfile) "-DSTDOUT_COMMAND=${command}" "-DINFILE=${infile}" "-DOUTFILE=${outfile}" - "-DTIFFINFO=$" - "-DLIBTIFF=$" + ${tiff_test_extra_args} -P "${CMAKE_CURRENT_SOURCE_DIR}/TiffTest.cmake") endmacro() @@ -215,8 +227,7 @@ macro(tiff_test_reader name command infile) COMMAND "${CMAKE_COMMAND}" "-DREADER_COMMAND=${command}" "-DINFILE=${infile}" - "-DTIFFINFO=$" - "-DLIBTIFF=$" + ${tiff_test_extra_args} -P "${CMAKE_CURRENT_SOURCE_DIR}/TiffTest.cmake") endmacro() @@ -323,6 +334,7 @@ add_convert_test(tiffcp g31dfill "-c g3:1d:fill" "images/miniswhite-1c-1b.ti add_convert_test(tiffcp g32d "-c g3:2d" "images/miniswhite-1c-1b.tiff" FALSE) add_convert_test(tiffcp g32dfill "-c g3:2d:fill" "images/miniswhite-1c-1b.tiff" FALSE) add_convert_test(tiffcp g4 "-c g4" "images/miniswhite-1c-1b.tiff" FALSE) +add_convert_test(tiffcp none "-c none" "images/quad-lzw-compat.tiff" FALSE) add_convert_test_multi(tiffcp tiffcp "" logluv "-c none" "-c sgilog" "" "images/logluv-3c-16b.tiff" FALSE) add_convert_test_multi(tiffcp thumbnail "" thumbnail "g3:1d" "" "" @@ -344,9 +356,7 @@ add_test(NAME "tiffcp-split" "-DTESTFILES=${ESCAPED_UNCOMPRESSED}" "-DCONJOINED=${TEST_OUTPUT}/tiffcp-split-conjoined.tif" "-DSPLITFILE=${TEST_OUTPUT}/tiffcp-split-split-" - "-DTIFFCP=$" - "-DTIFFSPLIT=$" - "-DLIBTIFF=$" + ${tiff_test_extra_args} -P "${CMAKE_CURRENT_SOURCE_DIR}/TiffSplitTest.cmake") add_test(NAME "tiffcp-split-join" COMMAND "${CMAKE_COMMAND}" @@ -354,9 +364,7 @@ add_test(NAME "tiffcp-split-join" "-DCONJOINED=${TEST_OUTPUT}/tiffcp-split-join-conjoined.tif" "-DSPLITFILE=${TEST_OUTPUT}/tiffcp-split-join-split-" "-DRECONJOINED=${TEST_OUTPUT}/tiffcp-split-join-reconjoined.tif" - "-DTIFFCP=$" - "-DTIFFSPLIT=$" - "-DLIBTIFF=$" + ${tiff_test_extra_args} -P "${CMAKE_CURRENT_SOURCE_DIR}/TiffSplitTest.cmake") # PDF diff --git a/test/Makefile.am b/test/Makefile.am index df5c082..2052487 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -53,7 +53,8 @@ CLEANFILES = test_packbits.tif o-* if HAVE_JPEG JPEG_DEPENDENT_CHECK_PROG=raw_decode -JPEG_DEPENDENT_TESTSCRIPTS=tiff2rgba-quad-tile.jpg.sh +JPEG_DEPENDENT_TESTSCRIPTS=\ + tiff2rgba-quad-tile.jpg.sh else JPEG_DEPENDENT_CHECK_PROG= JPEG_DEPENDENT_TESTSCRIPTS= @@ -77,6 +78,7 @@ TESTSCRIPTS = \ tiffcp-g4.sh \ tiffcp-logluv.sh \ tiffcp-thumbnail.sh \ + tiffcp-lzw-compat.sh \ tiffdump.sh \ tiffinfo.sh \ tiffcp-split.sh \ @@ -126,6 +128,9 @@ TESTSCRIPTS = \ tiffcrop-R90-palette-1c-8b.sh \ tiffcrop-R90-rgb-3c-16b.sh \ tiffcrop-R90-rgb-3c-8b.sh \ + tiff2bw-palette-1c-8b.sh \ + tiff2bw-quad-lzw-compat.sh \ + tiff2bw-rgb-3c-8b.sh \ tiff2rgba-logluv-3c-16b.sh \ tiff2rgba-minisblack-1c-16b.sh \ tiff2rgba-minisblack-1c-8b.sh \ @@ -152,7 +157,8 @@ TIFFIMAGES = \ images/palette-1c-8b.tiff \ images/rgb-3c-16b.tiff \ images/rgb-3c-8b.tiff \ - images/quad-tile.jpg.tiff + images/quad-tile.jpg.tiff \ + images/quad-lzw-compat.tiff PNMIMAGES = \ images/minisblack-1c-8b.pgm \ @@ -207,6 +213,26 @@ memcheck: ptrcheck: $(MAKE) MEMCHECK='valgrind --tool=exp-ptrcheck --quiet $(VALGRIND_EXTRA_OPTS)' check +# tiff2bw is pretty lame so currently only the generated scripts +# tiff2bw-palette-1c-8b.sh, tiff2bw-quad-lzw-compat.sh, and +# tiff2bw-rgb-3c-8b.sh pass tests. +generate-tiff2bw-tests: + for file in $(TIFFIMAGES) ; \ + do \ + base=`basename $$file .tiff` ; \ + testscript=$(srcdir)/tiff2bw-$$base.sh ; \ + ( \ + echo "#!/bin/sh" ; \ + echo "# Generated file, master is Makefile.am" ; \ + echo ". \$${srcdir:-.}/common.sh" ; \ + echo "infile=\"\$$srcdir/$$file\"" ; \ + echo "outfile=\"o-tiff2bw-$$base.tiff\"" ; \ + echo "f_test_convert \"\$$TIFF2BW\" \$$infile \$$outfile" ; \ + echo "f_tiffinfo_validate \$$outfile" ; \ + ) > $$testscript ; \ + chmod +x $$testscript ; \ + done + generate-tiff2rgba-tests: for file in $(TIFFIMAGES) ; \ do \ @@ -303,5 +329,6 @@ generate-tiffcrop-tests: \ generate-tiffcrop-extractz14-tests generate-tests: \ + generate-tiff2bw-tests \ generate-tiff2rgba-tests \ generate-tiffcrop-tests diff --git a/test/Makefile.in b/test/Makefile.in index 92a4165..15c0147 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -413,10 +413,10 @@ AM_RECURSIVE_TARGETS = check recheck am__EXEEXT_3 = ppm2tiff_pbm.sh ppm2tiff_pgm.sh ppm2tiff_ppm.sh \ tiffcp-g3.sh tiffcp-g3-1d.sh tiffcp-g3-1d-fill.sh \ tiffcp-g3-2d.sh tiffcp-g3-2d-fill.sh tiffcp-g4.sh \ - tiffcp-logluv.sh tiffcp-thumbnail.sh tiffdump.sh tiffinfo.sh \ - tiffcp-split.sh tiffcp-split-join.sh tiff2ps-PS1.sh \ - tiff2ps-PS2.sh tiff2ps-PS3.sh tiff2ps-EPS1.sh tiff2pdf.sh \ - tiffcrop-doubleflip-logluv-3c-16b.sh \ + tiffcp-logluv.sh tiffcp-thumbnail.sh tiffcp-lzw-compat.sh \ + tiffdump.sh tiffinfo.sh tiffcp-split.sh tiffcp-split-join.sh \ + tiff2ps-PS1.sh tiff2ps-PS2.sh tiff2ps-PS3.sh tiff2ps-EPS1.sh \ + tiff2pdf.sh tiffcrop-doubleflip-logluv-3c-16b.sh \ tiffcrop-doubleflip-minisblack-1c-16b.sh \ tiffcrop-doubleflip-minisblack-1c-8b.sh \ tiffcrop-doubleflip-minisblack-2c-8b-alpha.sh \ @@ -451,8 +451,9 @@ am__EXEEXT_3 = ppm2tiff_pbm.sh ppm2tiff_pgm.sh ppm2tiff_ppm.sh \ tiffcrop-R90-miniswhite-1c-1b.sh tiffcrop-R90-palette-1c-1b.sh \ tiffcrop-R90-palette-1c-4b.sh tiffcrop-R90-palette-1c-8b.sh \ tiffcrop-R90-rgb-3c-16b.sh tiffcrop-R90-rgb-3c-8b.sh \ - tiff2rgba-logluv-3c-16b.sh tiff2rgba-minisblack-1c-16b.sh \ - tiff2rgba-minisblack-1c-8b.sh \ + tiff2bw-palette-1c-8b.sh tiff2bw-quad-lzw-compat.sh \ + tiff2bw-rgb-3c-8b.sh tiff2rgba-logluv-3c-16b.sh \ + tiff2rgba-minisblack-1c-16b.sh tiff2rgba-minisblack-1c-8b.sh \ tiff2rgba-minisblack-2c-8b-alpha.sh \ tiff2rgba-miniswhite-1c-1b.sh tiff2rgba-palette-1c-1b.sh \ tiff2rgba-palette-1c-4b.sh tiff2rgba-palette-1c-8b.sh \ @@ -653,7 +654,9 @@ CLEANFILES = test_packbits.tif o-* @HAVE_JPEG_FALSE@JPEG_DEPENDENT_CHECK_PROG = @HAVE_JPEG_TRUE@JPEG_DEPENDENT_CHECK_PROG = raw_decode @HAVE_JPEG_FALSE@JPEG_DEPENDENT_TESTSCRIPTS = -@HAVE_JPEG_TRUE@JPEG_DEPENDENT_TESTSCRIPTS = tiff2rgba-quad-tile.jpg.sh +@HAVE_JPEG_TRUE@JPEG_DEPENDENT_TESTSCRIPTS = \ +@HAVE_JPEG_TRUE@ tiff2rgba-quad-tile.jpg.sh + # Test scripts to execute TESTSCRIPTS = \ @@ -668,6 +671,7 @@ TESTSCRIPTS = \ tiffcp-g4.sh \ tiffcp-logluv.sh \ tiffcp-thumbnail.sh \ + tiffcp-lzw-compat.sh \ tiffdump.sh \ tiffinfo.sh \ tiffcp-split.sh \ @@ -717,6 +721,9 @@ TESTSCRIPTS = \ tiffcrop-R90-palette-1c-8b.sh \ tiffcrop-R90-rgb-3c-16b.sh \ tiffcrop-R90-rgb-3c-8b.sh \ + tiff2bw-palette-1c-8b.sh \ + tiff2bw-quad-lzw-compat.sh \ + tiff2bw-rgb-3c-8b.sh \ tiff2rgba-logluv-3c-16b.sh \ tiff2rgba-minisblack-1c-16b.sh \ tiff2rgba-minisblack-1c-8b.sh \ @@ -744,7 +751,8 @@ TIFFIMAGES = \ images/palette-1c-8b.tiff \ images/rgb-3c-16b.tiff \ images/rgb-3c-8b.tiff \ - images/quad-tile.jpg.tiff + images/quad-tile.jpg.tiff \ + images/quad-lzw-compat.tiff PNMIMAGES = \ images/minisblack-1c-8b.pgm \ @@ -1210,6 +1218,13 @@ tiffcp-thumbnail.sh.log: tiffcp-thumbnail.sh --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) +tiffcp-lzw-compat.sh.log: tiffcp-lzw-compat.sh + @p='tiffcp-lzw-compat.sh'; \ + b='tiffcp-lzw-compat.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) tiffdump.sh.log: tiffdump.sh @p='tiffdump.sh'; \ b='tiffdump.sh'; \ @@ -1553,6 +1568,27 @@ tiffcrop-R90-rgb-3c-8b.sh.log: tiffcrop-R90-rgb-3c-8b.sh --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) +tiff2bw-palette-1c-8b.sh.log: tiff2bw-palette-1c-8b.sh + @p='tiff2bw-palette-1c-8b.sh'; \ + b='tiff2bw-palette-1c-8b.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tiff2bw-quad-lzw-compat.sh.log: tiff2bw-quad-lzw-compat.sh + @p='tiff2bw-quad-lzw-compat.sh'; \ + b='tiff2bw-quad-lzw-compat.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +tiff2bw-rgb-3c-8b.sh.log: tiff2bw-rgb-3c-8b.sh + @p='tiff2bw-rgb-3c-8b.sh'; \ + b='tiff2bw-rgb-3c-8b.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) tiff2rgba-logluv-3c-16b.sh.log: tiff2rgba-logluv-3c-16b.sh @p='tiff2rgba-logluv-3c-16b.sh'; \ b='tiff2rgba-logluv-3c-16b.sh'; \ @@ -1826,6 +1862,26 @@ memcheck: ptrcheck: $(MAKE) MEMCHECK='valgrind --tool=exp-ptrcheck --quiet $(VALGRIND_EXTRA_OPTS)' check +# tiff2bw is pretty lame so currently only the generated scripts +# tiff2bw-palette-1c-8b.sh, tiff2bw-quad-lzw-compat.sh, and +# tiff2bw-rgb-3c-8b.sh pass tests. +generate-tiff2bw-tests: + for file in $(TIFFIMAGES) ; \ + do \ + base=`basename $$file .tiff` ; \ + testscript=$(srcdir)/tiff2bw-$$base.sh ; \ + ( \ + echo "#!/bin/sh" ; \ + echo "# Generated file, master is Makefile.am" ; \ + echo ". \$${srcdir:-.}/common.sh" ; \ + echo "infile=\"\$$srcdir/$$file\"" ; \ + echo "outfile=\"o-tiff2bw-$$base.tiff\"" ; \ + echo "f_test_convert \"\$$TIFF2BW\" \$$infile \$$outfile" ; \ + echo "f_tiffinfo_validate \$$outfile" ; \ + ) > $$testscript ; \ + chmod +x $$testscript ; \ + done + generate-tiff2rgba-tests: for file in $(TIFFIMAGES) ; \ do \ @@ -1922,6 +1978,7 @@ generate-tiffcrop-tests: \ generate-tiffcrop-extractz14-tests generate-tests: \ + generate-tiff2bw-tests \ generate-tiff2rgba-tests \ generate-tiffcrop-tests diff --git a/test/TiffTestCommon.cmake b/test/TiffTestCommon.cmake index 50a4c34..a0db678 100644 --- a/test/TiffTestCommon.cmake +++ b/test/TiffTestCommon.cmake @@ -101,3 +101,8 @@ if(WIN32) file(TO_NATIVE_PATH "${LIBTIFF_DIR}" LIBTIFF_DIR) set(ENV{PATH} "${LIBTIFF_DIR};$ENV{PATH}") endif() +if(CYGWIN) + get_filename_component(LIBTIFF_DIR "${LIBTIFF}" DIRECTORY) + file(TO_NATIVE_PATH "${LIBTIFF_DIR}" LIBTIFF_DIR) + set(ENV{PATH} "${LIBTIFF_DIR}:$ENV{PATH}") +endif() diff --git a/test/common.sh b/test/common.sh index 6f9b282..6b1380d 100644 --- a/test/common.sh +++ b/test/common.sh @@ -40,6 +40,7 @@ IMG_PALETTE_1C_8B=${IMAGES}/palette-1c-8b.tiff IMG_RGB_3C_16B=${IMAGES}/rgb-3c-16b.tiff IMG_RGB_3C_8B=${IMAGES}/rgb-3c-8b.tiff IMG_MINISBLACK_2C_8B_ALPHA=${IMAGES}/minisblack-2c-8b-alpha.tiff +IMG_QUAD_LZW_COMPAT=${IMAGES}/quad-lzw-compat.tiff IMG_MINISWHITE_1C_1B_PBM=${IMAGES}/miniswhite-1c-1b.pbm IMG_MINISBLACK_1C_8B_PGM=${IMAGES}/minisblack-1c-8b.pgm diff --git a/test/images/quad-lzw-compat.tiff b/test/images/quad-lzw-compat.tiff new file mode 100644 index 0000000000000000000000000000000000000000..ec614bf6fbc3e595fb2e6b55064716c5ae379e1a GIT binary patch literal 214342 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 z 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%0A#Y?BK-vnUA~ ze$++E8k2L3HuCH@O2Q zq{6ltux$-&+YZ}~z_y>@5F5mP4ic7tgk>NaqH@H8UNCFWawB~#+fG5X0_eH(; zCHai2@)_5}0XM_}x5NRziUV$o16sua?c#tA`HU{TcaPrto*sW-m|-x?=w*2KGrS)Y zK2MEa&y4t>*5`%T?vbCCgzM2j_-|*Cgs9a7Sk9)C_Namk56cfT$rm| zs8+J`bnHCBG2iG=Am^%Ul#n`Lj?W5uNsEl^YlLlm%#V!m^#g1lR)Do<@8pB$!Bdu6YFLsASf5@aK z3+W@06UN1}G{%|7fafV)Y_%@7mJxQ25!T2E(=oy>GQzGH7hE?kxM^JQt8u|?0|BkUd{>;WUJml4*_2z$Z^8_>o6ri*={i+x3e4FS(l;5kM(zctSMVCLO1 z==PCx`x5$}k0_VjK(x&%n(!2}*Xg*{sZy74TDee5IMpcGwMNIYI>&QL#|GV;MkD)z zk=+!&xH)|BMF!`R(cuULu7;~0R-q4@(TA<*u3mJsuNDC6Lnig1kor(UeHcM~7)O1m zpgt_7mYt!NU80uVq4p0^Q%JNFCM{V&8<5bFBWQzhw3iCn%VOGK4Q;TU#_ppfP0;3j zp^Y=K*8+?y#Y*F`%h}kUXE6Rai`Z>9`ua|;UdU9=5Z52Nm3|53dO}k8{(l@6||-r zGDmX?Ol&a={ZUH&F_k8^#9nX39F3B%Wcmwx`Wg{ERz%+rNso)CC#2Go zRCG5LU7(`lCG>B_^tDxV`)WG3n$E8N2X$p;-{&;bu@*YDg$}pSDJ^u%7P>_neYBHq zJ6dhkY9%mlAS9Hvag^UnD5WiwcfFLP3Cf_^q(XuQcu>CtQp7iSIgb&ytS@k{_vdqMF{BRqG6?I6$1bH}{VJ@f3_DPRWwv7bd$ETk`XG<~>RI=-1B?)y zU8dz#;?<{(Gi!`9&l1iJ!1Ds|YzCf}faew9c^!D(0-nDD&)dMW4S3!Go?XDR2YB8C zo)3U$FYxRKo{x<)2aGd+GtPW&ocRi`HsaMITHb5j^0&bGJ#hX#Jo%F{_6yB@M0+~qw%OuNL- zNRWOeKYwUk@eFTzC3YRv2;Rs9?=+&18V{4wcS1`{%808il|V!h#8G0> zDfcc@JOe!sX`RxDIZEY1m2N?%(J@Qum}5#VI|G&7fl`-pG;&Uf+?+Jzl*>6swH&jB zmqZ1XTFxmg=d{*rPvq2SIkh^6vqpyoqeEl(Vx5uQqU#$>M_)FhBSUBsllt2H(J!T% zda0j;w7{#(5h8!SaRu~%u}tZ_P05oR%|2$Q#q|Fg{RfN|EL@US$7CQa<8 zRK{oM@-q$j+48&`8KEZJ@_=7~k|vjiTDfRlH^De17H7~WL{-gXX@jUaGH9x$xOM;P8_g5{Xj=Z&5_j&tA1IUm9of7Cf+)=r(I>@jMW44MCaft;PAAKgMNK`|-Tr(0 zesb!+dwzBM`#5!5s;;Na&E`bxwwC6eE_?Un#>NTJa!}#Ar<{9yXmds_t?tX!-!>#C z{ChQ7Lu;I~1YFtvG4%6b{|@W+Ew=6@=8*1~@znGv7DKuF5V$sCA$D>CQ|93BQ!AzO z?5#B921Ta1`M+aRUw=${I`xJMGPxPDSCxt-HRBN0gaA^z8 z{pLAo3G!n}K(Gt|H4_9+T7c3~V>DIK4D{|UARK{mb^|ceEF~>1J{}A7zT%VwGI%xa z@sJw+tO8@KZ0%l_|9d_3AN8cs{qS^fe<$U@_TB_&)$+%)%NGt zR`tyxcX|3ZYQ=Kp_rH$P)4sblJfQ`4rdxqs_epxkpMW;!rvr^|b3)VRTjsg|i2MXk zV~GZM*IfH5_*IPq4T73$-19Cwmx(sH?p&`zK*fiKo~FtV?|Pa}f3UyXRDFN--O95| zEAD2V&rKajEHG0IQ?78!^WA_+^kkL+4k{C}JTo9*Fw1FvAGTXm`)>iV95nAq@_!}C zVehSCQV#@oW$(F^mE%-?swZdl!Gdp#ZlxJ1-P|fwx>23AuXTvc+e%XMz3L#bU?nhy zbr&y{)YyV>Rg0@ff^|sjtR0i7?z7S+MIN*ARU%Kf6V@Ux-oN8J;#LDje&;2*3;*j9po%6hWWopGqoEClQ0BW8eH5ejMy!!;RajcVjngHakY6X>eZu$$(L z)GR^qGBo2dVfNpE(Y8NkHhyZmF{|yKlNEG9oNUL%{_27H#lE;w>z~^ z{yr>0bIHD^@xXGvziZC<%o*klYtK6A&I)Lq+te9YHdV+~&g%>=Z?4(=!DD*)aRZzp zU-tXzdZiZRxzzCQ?OQVY6uI#1(h=U{ecgWbCA0>4hS$q_tiFxpl`4MY zU|3AqH9%tTo3Y6$;X1{vA<W-K-6P#6lxw4;^bjUUfE7nlQ*y`4h_|)QxbuQT)_1lp61H}~^T&%ciI5a-9 zm>cg>$5jin0dbv z690}8iO@KTYA^At7RJ!s%9V`pG+0w!b!&v#`eF9}|2tEdansF{biX5Mj#xKz>` z22XP#gPFY<*W?Bpf9tHGWfNy&raU-&vp2OZufR!S<{I|(&XG^iu)KuO*P4a^?QyL1 zf=K7)lq|CLXqUQ6v7!H7p?S zI{dfMBBHu+)%2xvD4O5Wm+tfLcbfl*^69U*pftu}+)D&CFyg(lV=(@lb5M$~jVL6j zF7`I+&ZX5W%QioDJ!8(MY>}=xk-O48{xiHKUAm@P!}fGb$m`L@iyAgl zpRb~CAF^ouLtgiZDGWa@@MXh=Kax?;6~(UE zdtg?QG~`5hgu8SMW*wADdr#-_=r}gXdn+|0=uY_DJ5aH|l&{g|xoBsro5NLW%ZdB0W~N|IB0u_g z1;c&p5ghkFA8pQy9WsOC&PEVLwgt00MwaoeNBM`b{#I2egI$kt!J@G(_U1f6iSY`Uz&GUEIV-1}n zO+xWDV%hYZ5v$Bw6IXYbd>m}7yAtolRqQJ0z!pItd0!aSe|ilI3id4#Tp7;&Q5sKl zSSnrC_^D$eR6EKTm9E%cbAP2Y^_Zd3P1*&U%M+HL)DOAaPDAXoRd$*aRv;{0@~@@! z$RWQ^VuP}GOJ%}hV~q9OCs{NQlVNYz88;`so@SpCq=&HER3iH~K8C)jw{G4>$=>4{Z=KZYUwNTP^G3NnUG|ciGxD%lbW% zvi0GwIa;z+eKx5fUipr@c5!EP`9CRUOZ&COozV@=%f}Nf0tc1L=ISSDy3B-t5pI4! zr>f|7fE53;Kcov z#7*<;bSo5=ClpxPB}8w}`HqO+P%FUKK>gqUc^RbaoV-8%5`B zq6-q~6NbRb{-2O$lKB{#DiiGnk^92a_ZwFo2#<4`q>M44>3ryo6mpJ(mZwAXDrjvp zWaxzwdd+VPpHjV#VuY6UM}Z(zq@wZra=lN5jC)Ku{WxKF0{5vTc&EaVd2MsGrnyzPe>LEpk^9%m-0SrI^?LtvCjSOJ zpwWn5FwNJQ<~J+dFDl(HYXh!m1Fq=H}`+1Aa9H+|~!^^#N`AfOc&_hc=)~ z8_=V4zh|0%-)MG#;JqgQenR|6@Bc*R{#5S&OtX2=H1~ym?kj?4G|S$TL0sCK&8_Cq(0!3 zIPkPS@H9?klO)x+35y9a_$#v4k{M1kE{)=B%K-DWScp`X{^DrkVHX4nUrDB^(u*qg@;}G_lNuQ9?BX-i4U8Hj@fVROR9dwKzzPYt@XvJd=MO?w^nQ6cF43z%C4D7U_5z1G`x6Rw8ygV)7`*g%wKS zF@~tpz(1wUtiq=)6ba4&X_H=ZIo#|kMx)5oC@FQ#O{&8v6%VG(E}=zs(3X6o`H(T* zY;0LHW}Sc?R$+-H*rpb2dn=aQhp~Dw*$`G1$eRGX36uXMBXAPeei8?L!WC1XYDy-Z z61RNDTlR}ns+TbQ8PU6BqCIl{PfF(lVz)!`xH2;2#D~Tt&}bZ#oC@))Ap2&>x))kL z1Zl0|wL;h+femr+iCyrrube2vKWzwJ`G?tXSeq7sq$!XScWN`69j>?s8ic4e5{*)z z%Zo#S0d<~0U-78ZBdPC7sBe3zW!5x2l4f&_c9@JUE5(9pC<5K}O>q|P!&Zl9Q*0tB zY6T^sn6kWz@}|V|OV!LY16wI3RNkR)-|woJ8V4yTYrMBEf8w~VjYB7Cm_o*5d1R2=tp=~XvA#v??E%OQk22HVMoI81CTuT+mrG!6JS>yk zy4B`$T*mE${7ZY`3&ZfE*GIMbxz#%F8q?e}xPKksot697%iPat{m<+D8wqif$zO*D zwBP|3jre6Fe#JEZnrZ%Z)BKxC_g|Fmzbf5tE8X>``E928cTDp;O!K>pcn=^S|B-# zOX|fz4Pr^7Owxoan#1u+O34+i^g5AxlSuuQNWD#@wh^g!h}6z-ygMB4kyqc7Ngn8{ z4M5Q=4(ivc9*0xia)O?UcRtg)4~heyn*v@a-CvpfUupe^0B>05JxcI~EWkLyeJ@+M z{?;RyxuZf}pe7;NLL^&(JTF0>w;|8TXzQ-^X$rLC=z#}U7vI(`Zq+Sr*ZXwneY*5! zx2n%Qz0U)JYhXCE3%O4S?tqN@n~eKh#(k;b8a3Qu4R_SQeS zcdCljN@ev@orkE-Od6j@d!y=j-{STJaGvUTYiy)nFVn_)Y1@ZrZzpI@WNg$8E0bcI zA~8G_+gOa*T*Cx?*n~AbB8a|hC!Kwf?nMSwN1TJiDYnh7XTP;L&IpkB0>+_*)h1-Uf$^z&wk8MhHvxA(5An z7&1CL9$i_B;?t*weWHa}VAcZcn*Ao8G|IAjS;GF$(r)hWxs&e6`y6+7kW+_rxaI+I{~9&8TvOq*gH6|;`%SjTm& zO5k`3n7z%rWmOy-iesIQRj*?;m}@D;tR@qq*<^buoOwmdye6M{)8zOo;OONW+GS3i zMqW?2S$yaB8&^Hi#SJpzjWXdlLo|i2Ja&+=9oMFs{C5-Xdkx&5Oq~6IeZXXU$iz(3 zxhcg?Dg!&i$jb`%{D)M5JLln^`9yl5Ss@E|F4o1BFlHTL%qlZ&IBME3--+|B6^=0f zt6$7G420)~@IsM@709=Aa~~~oxD7cxj7;#+>7l3~9<`}Q4|SlE6DZe}TGsawXsKgE z)ag>1JWf1 zdrfeGj5J&SQz(5X06DM%NlQS|b|R`$gi(z!T97?`$ev*&&ju|JpccNUMHG5?Cwe#o zEh$AyE}|vK-y}51+;m(bUnj zw4Jn@CA6I_G@CZsg<)FZ1TC9~oruB=>6mlXE*|bupm!>gZzwi7mf*}%9qWkBp-j1H z{}XP7!7Gi;**QE{S-Sb8%>6VWK8*)xP4lbt0X2-kGkUyE>wXs3o>K;$*W!)1LG*U@;P`ZR>|imO@gG~T|15YOWGOrCm3|&T z*V=SV>#{;Of(kSAzb*jGc|kHRKHRa;?r*@ggv95>W(kU{$zy<(SwJV6rhm)>%?z_B zyuW;WO&%CnQs}+A>CuhIPfK3pGr@){Y0s?617o(voy)0pEB`I#UBbCy^)k2p$2M;~ zeL}IPGvIjAmh!VSa`^TZzwW2@n^rVFpewiM-uy^1J}}Ll5A@GScoPOvmG@dn@}?a( z{6J%d75I2W63yN8Q&lv3`;R;Zyw~wa_X6NCyew-B=(^|HueSh#hX*!OK_Li=p9%b} zQJ~SW)WId&$V!*84@uKqD_2(!xc&q*iyds5Nx(gk@x>Bo34e13YlXFC($a#=Y2YH4 zr1vq$&+{4JueR63YNv$Pq7_n`*S^cwwjq%CZ_$1(J!c}(<3CxG;oPCRy$Z7zeV1I_Rl1+(?kYaS z{YFuyg8;}8*orE6**sMRKhKA}S}-UnIp$LNV+j=8zP=@Q!<8-ZgKmYupcb$tC~~Pv zJP)~4EB<-O#d8B!^0r@aK!4a;M+(p1d^NEyKk3%eFFz!-RxF}A1Bd<*(U$;=QD5o$ zot-~Hs*9Fs^o|wNz`_G}-?r^}5uWI98-#aN?Y&i&6TCn7PM0hA#)LuIfK_+1N`P{gC>XYsRMS6R+!|dPZs;4t14yZL1&^fi{1Q<};XYy!BUlqOp>8r&L zBFb~n^*qgmDHi&li(m^XyQXirC;N2@y1&1@VlOrEUX0a`TOS{|MRS{48I{ALzWK$# zm~+6tLXaCmKIU>Pf`8og$~v-oL&?&p5w~4COVk%DV_f<|!lG^OuB?%VEb%NlwtLB% z`ZLmFZyRoPEQ!6K>pS+o`I_kXhfDhSrjJ(#itgpzXuOs`15A-`&C>r(o=@n}i+rIs zJK?7Aia>Bv)G~Wy|LmrDHmiJh{Ft!cZ_7H1z&Wv7cCw;AsHY0uK;{ZTfT2&A`LeQ3 z!f_c3nS8H1;=8uTh0#0>%xqn_wA;gmTNNg|)&?7Pt9(xFyXU?p-DNO~ysx^xBR*w_ zYkM-DQ~cI4iGKyLxy(RYiQ`U=jAN4)wp-M%jIG<9qc|2IwdoNL3hrUMBxhPe0q z#jCK3mF+X$g`x8X$n^dPBR*ep^A~!IQ=T!wzSR3Cm@?f_Qe5?{6Z&KBA3nj~a@&X+ z?J7^kPNd^Zwa}~=db^F}_2}C~ExP+NW~|7+KcJd@&A4=?e+~NZgKG9K#)4V?pHNk* z8@G~awJE#RE?(ZrtqjOc(!?E0jH%lWWSxn}g?5{ky4e>NhbGijakqMO+UH)kif?Il z+RoiLeZjj<*{!(KJM@TyzfISn?%t!RpxePr;|(0XR3v0Tl8JD}f=dAWOl)yp#>j=H z_E_2a@SW_XT{(9o)!Q|j?LF^S2{K#x%us1YvHXS0eGyy`u1YBTR^b|)0pHt979QtP z-Ib$oEo+OdOup0%#z1Z~wn=pRtbMBY=X*>@;dQDHM0H|8z1PU%hq4mi@%X~lc!BP> z+!b>(r)YS30x=}M?>{4`=uyQ;!kY?*K%xYb-CgErADaU`YnJXA)j7&`=d60sx^iEA zd&DQR*89Zf$L!T4>0V=rQ}rE++jog1O&pF7`$B-J+LW!gV`t>D@( zOY5u$n}atJt#&^i*l1JzHgofQ-tpzRZno8SS(}&e>{sMkv8p4oHm{kmi;;)2k5y$Q zZ4(}g_1(zHdz%%1NHQyqTgNp?tQyNnE}J2>y+vDg#8rihTt)(8W^?>=1+lI|d!5>^ zrYqFNTjh4b@{ zF1{mk6P{k8e`l@x<6f}x5{&Ow{agIUG>w#WCIXzZ6^kr2;Ut%p;2g_8!%~(Q=e%a1 zi=ELEa(G|!sSUUrw~*JFs3|^{bjHfw&=6X9CE~jL!0T}TLnHhzBe_l?ZSza_?I;@G zdSdB}Wj2L_!G(c5@$#j=+lc-Mel1OB7S0&+ss%2qmXQLZDqLAxR$H!(i3?nH%aXlA z9TK~d$ysx)iQRP5(sCzn-n#A-PRskO4+nTRH*{m%7Mtu3xxAb4*B)}4g0kNqVIEDo zRclwb(`s#XarqWyk$pn5)hb;C^DIzK=TBJu`72K^_ib`G*V{^wKG66PE3Na61rKGf zgg37vD=Qc>xA8jIZu_vHQXl5-G7K9I@_n?#I*(yK@~kjEJei*~cULu0npzZD+a24+sTecrkDMsfKXGa8RY$_eXiZB7;E59cobOWbFuSaK`G zhOzVqkNZ-jH+>l^A+94vCS3?a#d<;**bYGC-%GLDrGAxPM*b$^|V^05tb(^ zQ|z?KR^yeVz%9y$ubz`$_}wolytGZ=bKviJcF*`&e{uV+H~W4F9B#p$UT@z$sadyR zTh3wDM~g?7fEZZS?aMNg;(lgkY*00*f8ED_s6(<2hLTQ4PL12XUu^kHR5~}hqKlPB zLi2cNp%5*MKnvqgjRIxOvAaRo-6ZUOA?$uN&SXQNm9T3g?Ai&t5-ZRN?7IFh6x3tR z1!=kWwcH0O$OW^WK=WH}^h5ibL8VRCV zk6#jVuIXKF8S&djyj{%c6mxp?_kDMSx`y+U-t_=j zeaOT})0=H{E-G16Cc{0O5tWO(sDVqqa(01uwuuR63*jj#JXR&Jc*H#h?98%erOxq` z%xvVe)5`3sWp-y|cC|9QdYN4r$=dAtDP^LXIOSM1_o~e4hLU?rJnL5(R}Y-q3Fi*w z>>i!-ecZ)B;E%#x2IMY-`Y5B=5`<&ss)i4G*UyHzKwtPQm$Aak`P2mMVF-WHOMb@Z z9n`ZA=~-z?rc%F9r59!x{4-6$Z262_Vuo68mnX9;(0S)Iub-{jIu!|LE8y&OctHtl z;&FpS&Vz}}FT6CnIOj7m=Q^2lz0A2m=G;g)Hxb-s;C#^_xFX}40TDN3PWDe+?Kj(X znCyBq_78whFAzT_%v*M*Ib!;jacBX%<)74w+q^sEYswYDAEID~8=p<9?}-E6cj=>JHY z3Uo&?s;EL0&8VUmRScnu2~?>EkQ_& zmC#mI*_y|^&Q-Lsi?q@a8hMIVXoJ0sbUD9;A<&U#mmI!y%&t6q#sd{xSOagH77*07 z@FZ@1O36GeXC2IR(F%}lLS%;oX_og(h`tmVI*Y8ngE)*L9%NMNj^e&3KMLjV zLN^~pnKdZ09c7N7%uguOhRPIBnL*Ueo2dLuD*p%-zeJUGQ9XvK4z@IV7g~;#re8s8 z*-2|ErR^{`Sah*o$XTyUOd}C648-Rd?$eLgS6Y+3Ws6!e;HGw1F#-E-3apg{)>>F^ z=|!F$V_(#;FKgIWHSFse_Dv1@7Y+NihOO7I+cfMu8g_?<-K}BwXxN}3*kWs7uPpFo zyWNty3aA+-T(FcP`cz)2Pd=j@-=4|%Uog=sn20^1i(4=$H>71IC+>1)?WhM8D zlIskE>ssy&EtkulpEra~k8bAHbKA7sb}jdg%&9}k?NV~PmE0aB_pZ+AzRu}^&gr2+ zU@!>!fO9{=eMC4vkvTsF-UER947d#HoL}f?zZ9u= zy|lX|;T2Ci1gts=NJfLo`ZeU89$ezSY$j;1G}i>jgMHq_!1Y9XL5iliAx*M`8 zfh4sMXoJpV&n^buiB{kU!7Vokj_RC_DOcsT!ei#-`~;jwLJFBkVJo+&mwVPMqD`~T z>qSVLom!OKOG@4QbaX)rx}Xoum_R=QW(3QOEHU1P4uq^w^_3CN_lRZ~3LC^^Fv#RO#|35sPxTp{!!2y#e( zwq-(vrO=fssH+WX?}I9byl1yKmIAvnE%$%-!DEWsHpRE!55eyz;P)hC0Uuc)GDqvv zG9L@h83gBbP8Wb~YElox=$Hb{i;Dw>nOEcN^t$l&_YrkrXLgf$$ZG zV>&Zqm))vX#JU%W9YVA=s8)b(6rvlM4Gp}8Gg||1$O3Q50)LSO-Znm{v!K=qsC7Zq zZNl?-*!hjcW-7$bc7E)KdRDJ;2`k+e$o?5cl$Fw|J;g5#{>?u)R|_dmr{A>@k{!YA zY(?iMKeH2U#&Mnh34Lf~c=FX~vu?}ODw$O{vzlPn$k?@dcAbfR));tBENPIMK8H13o$$Ut}6N0@m)87^cIl*3Z%FH$!km7fV5r7?@;o)l>BbJnkqpxV*<>ZQ5P&DuGHkG-3VrLV*m z#bX&+*wR{T))OocrY{%K*Cx}S-K6_c0sKFqi*!yJO>D6|wnUd*V#qEv@=6)}BLu%p z#xGa$kIFqX?*tpGU~V&9+7J5;!&inj00vSjMDo(R&WbC4C)$~LmGl^JxQo>E4Z%7m48FZ^mfd44f z6Hd8Or+mQL_LBLb1ls%HM~^)zl<|%MzjK7&1;Fn@;dk-yyAt?a2mEdVPG%rW5}q~y zv+F#wX0h1~VAl>X?1J{aHR*>_0nyOs90)Q*E9&aiOdm}t>m5#y2ANF{WCMYzvM(3qoiA0cI5 zy~glje2j(C96#!38yCrbx-|(6&p>7r7#P6LY?v&7_XNSY;V?fI&d-I-CjP?X8CRr? zs}jR&62lstabdYdNB|-aN91vcJQtCdAyFMj)CdwajokRfh!AT$&c)qeaSvGB3l{eg zhW&)$AkG+)7~YmLMx+cM5*Pa_Q)bvdtexqu6cg$s+tMeK(O2%~E0;uz9>j=AeKv1^TjT`RG! zmsmH*-LK2to8|5;a`zjAdmG_?lW->p_YS#xm)yNu?%qp3)+ezZ0B(Z{_Au^xTj)MQ zXO1eDY!ARX7fNP*VLT?58vMQAEEoP?PSyWkjh)TvoF(FCrfVygrA`v^(> z0TF`GW8wC*{l4Pmw!nTDN&W_rt`6g!Ceh!b(tz!YuaP8am~`!KuTBzSOOvjz3>_xX zcYLy647S}NiFSOx`k*Q5U18hc?IBlig!Dh>*)F_iol&~y{CDoFd2lO=bME}khT1zr z>lZrxJ|qx~je4v>{Dj1 zUJvBA4M06*7Es%h2)E_q&RXD~kGN7h$Pc{I+$U*q5>W4v84rsa$K5nKur|QfL3LvhoGXcLzl*^gKp+zHn(m*UIB-QgadT z{G)f4BPgJhExJ?CFdT1PnMea~GOB1PbN0QhroljVk_yz06mVQEjiv*w1TBy#APLO_ zfw<2Q;H9%b+5t_L_nUL988_EE=K=Tay4nX8C81%3mX*6S`#Fk({6|)GN&IuxL^e6Z zhB!|Su_dmOL+t80_~-2FM#$&pU7iRloL~8g|IlHVrbrjn6|p`evhVSAKNfJADiDMW zZO0d+#7t=&TY(=6UAz>iR%76CA{i{>sovZoPlzn$OajR*XYjhjui9xQ>Cz@?h(U^9 zVmTR@FE!EB>Q92RzE-WY{yqyJ@PL5KPmj&z&Rx;ZPPNesXM>2+a?6uzBl^Pq4~;&z z@=xaXMJCv9Y_y3i3*2WL`D@@lJOAF%a(n;L+E4Q~zAAk_Kk%PUD!3^iOL>0GG6DZI zPz=d#OUS@kxOHl3!GgpOd5ccAIF;$L65k&@xzo+JKl-%FoME=kvw6jXB7>QNoMPX9 z`=7~qb5?TC*!Zu^uHf#5ErFaLVOyB;{Hv|7ZW0350EEbDz#_!DCduR6r|T)2NaVv; zrT@-%{ZJd{;QGJ7@3)Ef_8FhMxBZmyxp%{w4u;Y!Q!`209*E2N( zyYbJYCNv@5vGnihQ{)wiD%)uz|Jeij43f8(k2@nsq-Dt5*yFt^hOuFTx6%6Qq;)$( z^FuaxGuKZftveE$|I>z9to4lKbt$2S;TvWduV0b8?sRB=R7kfmGgaHW(mgv`)NNwW zq3vBCaC(L#LN%uD6twe(9R$%P;sPI5rE&81l+ePkf?igod+)X!hDqd!DC57PlYcIn zFy6M)(&X(~pQx(o3(*^1n#^?c9<7Zj-sP2S`fWNnynVt>qGdfh-FUf?RvsQFnh-Vw zp1ktV-2A}WZF8Bm8hnTB)NJaBwNkInxxRu^1~rM^&&4AP^%84Wd3mz?svc(WW6t<{ zozP$Nrkl28qHGO-3~cQ6Y_cNY>XNV>m#j_g=nFZVvX7Jp->!3tB)No`rnMAHlWKB=5M4pu6H+>h+;UMxIz!G^HxPO zf_9zwb@oJoFMX%p=ko3d`%q)Q2u)>Sh1j<)%!Sv@r0Z3^MFS+PzV_eNwe&PJ$zHf~So4J!}Dci`Hlx|7K# z+BNj#3<_0e)ID+ax>K2-NR$WOeX}P+YjfU^B9BOVw+{SuQt~~1etb$F?&6W+ZrmAl zQq5rRtEA$NWM9phiJQiRO8qCd<%tR{B>SPt$VuPAua7LhzwE&KSFb1$1?HSCFAubS zW3X~%QqKC4^7Yn`(aM~poNeyTn|(3n@v)v~hdSziQqfo|O?@WQ-0LF@P8kamwPjT` zPCK7VO!=f+-UIH;eLP#{_^Md5<1_`FK z#(d+2LDs(;czbwH29n&?fm4P(J7$3`6D}KE<{J&3>zUa`;%)|SjD(%DWP3>ETRhT+oK9xODwYr}hq(Sov`tmvAu&8RIiakNLi&#`JNI>1c)yGJf{v<^knSc$g1 zns^x};=Z4;Ylsi+T#V<>U#(3Z=4yY!7h2ugQg+~h@8bpZ`&dV_JJn)M>m-Supk7(( zvwuQs%hDQTpf$}FfhDKcRrMG~rzUNRVq|afdTzw%_x9Sy$lmJJ&1C%L?Ule_ zgnFG|F&uroWQ^?UFbkA zj35^nmeMI>0=K;2h+c3a=-X`cZ3+6e2K{pc{c{5SlZ4GMuo*|}i#zru z0Q736A`B+HfKcqGfGU4VRIIbER+SGQ~4K3nCIz?3u=R6g{NG_DHSd$ z1HuZS;G$emE#Y3qov$jK6-sWMXh8$8XaW{3z@iOU+yoXKz@iIS^a6`M(SkuGcUa-9 z#GN&FgK@clq6O{&!2{uvM-tD+JnJWFgJ*QcGYL}#SQE0~Nj!2&%70Frd?Dh$l-Rr^ zB3=k<$}NFrG*d4pC!nj9mwekB$tGKF-NoA(Qh$mdkzY9p*P4_6CVqX#B_78@IK6N21{8;GmN7x z)JU{A>w}oA**yay&~lfgp*Ft7Z7sTVtfzDWKkM{MZQnAfN6o3fxKkOS)Y&oA#02WH za;he0zjTy(mjVg(pg|`HctJfukXIa(nh1H9LM!Va>NwOi1^In|mXqNG4t(4RKCX$4 z#KFgN;p1iS@ht zuAbPU6WFqPY<7tsd6fAM9RDQcKYP8%7pJ7w7#Ao^3dM`hNf)0778h_U&104;oa2+Z zft<5*IyU&l!PGqX^Z~(TnadTS;3{xa0Jj>ETP+aQ0bzs6rBUT_9SE8gZY>J88w$5p zgoU(~g=dSx^M=B+P2t(D@Vu$;Bov;V3ePTu zXOG0QSK`?x(j0ZsrM0MQ7y57t9oNT%Y)t5cfwdZ~RtO|QwYf`$c#VTewO+aQ${=W> z96CAy9VNks%;Eh3@cwvsPYJxI1Ku+M=QEM~g-HI-NdA5#{|u6U9m&6kX*eyEPD>~RGI@m8dI4C+eBszFobZ|t-925RWWs@-PN&e$F%9&4;%%@7GrX4w< zWKOC4U(i>-0<1TH^^V8+oySp&R(~L@Kg)u@(og?`A0GyQqH=L~OJ#;ZdZkc9CzLV` zX_Mg_d>HbC+hgIZc=%fhtknf)kHB9h;4cg$*Aba5l#xfc_bZ&cvfL+2~9Onp=Z@89~2jM1#W-y3M3pS)R@M*dpwAwJ5UIOjcQrfFKv=klPa0}f_VY;hQ zbrYs_L}w$oa`V%oEoXS_0AYm5EeAh7GL_WOG3m%_} z>u};;5^=A{1=l28IRxr(=SGEdlft=0;oPQhzNv8TP&jufoO=|`w{YhH^}-xV~OAXY3%7o?BFa~pb;&bP0Quetobxc4;m+sb|;@= z!mifI*36FD&YsaJCsXYdSrXJ&TUMID7lG+f!ARp-r>i|P zWu95mi`fdNT=5bO*DznZ*{s)=Gu-azUe9&?Mrvh`6o5tsS^&)Z9*$OOL|s7T^xZmkdiUjw(FI z)t>j&29Jb{XF}$4`s%j|{)`v{N}bE*?Q2%IgxMrvwn&&aB+NDm^QJ_TsbqFYm|YrfhJ@KGVfM+H{YvJb zk~ySg-c~Y4G#E%Fb6m;1`+vZ(D*s3H)sN|`pVC)9Q)RsUIV6S8c_~``ny`Kgj=$I3 z|LLb^6#S2%_Y2_sjYl4n1d~;4pj?#xiW(jX8RkHGosjMf6g&%t*s!(-9JCiskB3R6 zaCo5anZt8HH@!(U6x-x9X(MUHB@?TnPNH^%lWL9R+zZ^6_#nE>s|hkmJmVj7^h z9>}f}${vMylTgMC^i&Jp&wv@`@EUhGF${Ly13P;y>5DV*BqLrNWTpOq#X)Y9gnL86 zZIf_sO1OlC+a=-lNVvD;f_@QqP$(D%!rMS_NC)iDGIZU8@#C@e*%+e++uwmb9mfu8 z%1NKGY%f7KN^sHwHit#=fJ}6}ki|j^lyK(i< zU6J`iVfPad@l0+zrO10Fv3*BBspgUQc9^%Sz_IKt2Lb!AEdQv8f1GD?oNg13M<&ou zpWtzll|L}9DRQGUIwPH6WYYDrc-Glsr(Bt5p7dhA!s(1~Nr7<5S->p>f+Cg61t2Wu zardt=CKBUTc?fd*jNP|zFN?TWMchA!OuU>BuOP%L4k2<8Prg#qPRNRrm(1dJi6pz) zoCYPHky>DsXB|*8m)U`xoVofS(?*QyTGt`3@ZXadI^hM-U!9QS6R3R}IwWNT>cJv5 z9LtBpJ%5P6fJnMelDCkCe#!yc(ma2~} zcfzP^v4l7*Fc%9CrzB$k0Q&!pP@TKB3=&pE0KpuJs-GoY(+yGvHbk?eL34u+Mp&TI z%Q-bGZ`*FPV}Z@{W17c5A;h)9w&?Gdpes>|!mbd#xa~t0{4@O_^W*x5D(Z4Z+*W?@ z9S(Osboxfliq!1kIoMvAhQ0< zNR-c`2RpX?T2^zqw{X+j=*p|vy*`UKzur~c>`qb+L(*UT0Lane=$GgbLR_(5OP-q zFGR2Fg<~)~?gf7>pHtx^@=1ijm_j2f)&Oy4_C55hzyB7JVtCV&k9YjDo<08RpZTnh zN^_mnSTG>7j=JlFZ!-gg6d(DG)FqmzvLI$5KF=xG&{ICQ1TaZ$Mw62mJJK zi|-q2%`Ddf8MM8ypcmS4VOz||4!P0@-c_btKd`&i3NUyRW|29^75?e!<}G zHj)I{)vRnx-{02yd2k1zu=I=W-awK%mRsmQe@8VY9LuLS|B(J$#p&QMr)UhOZr{g0c6a+LLCso>})ieSOw zIQ{1f=Vv-G79VY{t6lPfI&RY^|7B&utlqSVNfW2un1DIVi5h1!lfOuWwUll{1(o!f z0P~A;a=7fPHj~fU3dgWOPQ#)=3oaPybeor>UXa?N$rK-*p9kctKDS0ZTlKj;;(x0? z6A@;9pS%3l41MhJ`^E2LpV!Qs4};dvGNx~{%>3C0{@$AT$0G#=)K2S+xY+HX`iWn! zCgN`^C-&Ca;WlJ2s!clZlLnMcWA`cF2&&-ljX5PiNpK0hOa&f)a-QThCwj0}5<{g5KX$zBgj z_w8bjDSVwRV>44D!r2cu3@*S&v6Lf}`6}rum(!%0mb|k0uav76|6NNX>M1-mE5ogl zBt67>IX7iQqwlM9c4@kYkLi7v2e#2U0-2s+r&gp(w%r;vY(UbR^|SA^aggtXpl9W* z?dwZ^U0={^Se-g+M?^>AMwiP*zc%;mkW3ebv_>&Q`pkD7ayR`+`I1>r(%zLYZ4%m= z%=*=)cSpu_VYrK(@s$AW9j7}?qRM-XE8~;fOWjSj%aTn>s(rRynLfMYy_M$6THkAZ=fAr%h1q4IkKP8c&wc&P0#6%ade40WyNUUJHa2DGFvv4S>EsSU2wNF zvwbIL`QxVSg}6o8FT`updE{GZ67`~M$=7trIHL-U*6W&ejC`f~tsZIM#Bss2@#+(m`aOSZZC@H%C@S|cxMDtQ$I6K-L9LdC zzXtT|*kFF{9x>@$djOlaH5~bQBEh*uJUl;eDt-K$$4?!2CeI@%WB=SKr+yXcB$z_C zuHXcZEABYwT*_R%m*V;CzS1R(INeuXrnS#;#EnO1Q$KI zv(wT&g}g0R;}V8T$n*FTy4?CBZgM}rR9ac}#Af%IH213H{g+>}?WFhM?;RcoYVZs8 z84HoAJ01rcMNj7yoJ3x}NH};yJlCP%9`f?v&L=|@?GFhZt)aYAtRcJPnXGuX2-X^7 z&4iJecSh%!gGZ?7sw_+Mc)t zPc@JaUK4M%e{PljW|)1ro){;;oog9;zjJH7k~#02HxfV6DSkiOABe`< z{SKh|Y|i0fu+g^Gm^lIjMg(iJMlL4X0pwMK9ZZb?aQL0yusEtPzX5%WeJB0CFI(|>CAzIlz zl;Dpg#!qB+&%}1mgvJxHwUZ+A=gPG&rRJ}t6#YPo5r5qufITBw_X&i56|;{C!^0QS zEtNLsMY;wPG-km1Vw@uvaY`hdQW-}xh*A!im14$4X>_$n|B@*9iX`}|ELfqms+Dr< z72HMzw@JxuR&sABxot}BO(mC5ayymWZY8%@!7b1R{Zj6r(rQ>1d|MJcA_^WA>5q%_ z?uZ%p0P{W_qvUZON;r>2oX0rlsc3!EC$k%OHm^%zAE$>%fo+0t@d+gfh^cI4NL3Cs zyM}7tOZ9zC)zydYSU`Fn(28{s77I1!Ksu#RYb`_?g^DJif2N^g2K*-%E^&m*1K{!) zxI7;IyA-ahfh$ATSVfrBh)wFmCVyR=U!IMWmmq(4B0ZBx$uv^JK#LvG?*V90JX%RXDQE(lgCoitL@T~YKyk^W;9GHvFF_GXSwUDx7r)#3`_&WmbEl}K1Ea=j#Sy{y`KRqlF?a8)S1 zYk)>@b*m?qHQ;WILbvNew`Q?hi`eak*sWFU)-KjuP0sgH&|VJO>xA}tqTS(WcO3dH z5&c$%5?$z)akPbk-L}LUJh9qv?6AVQGNADLS)sKC`AO*f9R{=Z!;0K~2JZiHLL z;Pxq)h}+c=>h|ca+dvR96pqZqAv1}{NG>u~hm3V0V`IqJ2gGLa5`wp+gSX^O?w*-& zbS4fRN<{l863wdCw=tBUU@hUrK&EXtQ|z;DI>N4j5peYVj|HDRz)nnodc2iSi|*3E$MPcp}^O5rgf zY5AcfW=T>pkt7$bFTpvbB2Jn5NIB2HLY#I{#H>;nRm&KcrO{VJ`qxCkHIm?3NpQU^ zxKS3|B;__sxvf%eo0NM~$|a=SPARubY1JbOz9kFpmjn;;xI?1g+ai6XG>k_htNtfR@bWJQmtKQL>*Z*b9Z}%LiBuU3^4rt0%L)zn^NEL*3Xw<#bZ* zRZjLskgqkQ>jbd^A;VZmF9AZzAgmT@9))x!A*~rmD`EBKF5@zlS%t!^Qf+)uZT#+@ z$)6vOS(+a&F-J<=kv}7l;uxg31SzgTibs&*Y2-TzEiy+7-BGPDR3`yFQ-U^+qIo22 zg$1S;i1{aBx@AB35py+9l0zF>N8_EQRdmwGCc18$by20`yhT0^i)=%zwLLtk{6MO6 zEcLEt=A@jOSVP_0L6uBU^-0iN24vv~IR`-QVUTAmv^W>?DTRb}(7`*9#}wo{1NoBS zLwfKbKD^2UUKI%MkA?T=!23(#{hhGCh9pf!{MktS9d3if>bk_LSz^^96SOI~?Q$zZ zGixDt>Ba@UI0DWE4~n_Na;I}mR_q{FU`=B(j-C+mKYHAn2x z(V2mw6wXynaJvtz*a%;VgRdpR-KSwi8C=^1&l-mtreFgt7bH z6Mu*+L>WTVA>YQ3Z&S#(56JbQWgWz_PTws$Kki_-2$aMsF z9R;p;q%kFOhZ9GJ<@)mRa)&Bn@g?ATSuH6NQTAg1uVrk=X>yJL?7KgE#JW~HAqZNS z1C5RUFf?}c_>~iWm4sgv;dhD0x++e)23R$KRR>rNfYk_CO@P$`ST_Kx4X`vB#haR# zB4Bj_RySbv09G$x^#N8tU=0G+5MbRFrzv@?Q65W^Iln{r-6j0)5q=K{zegG{fsFH% zupZN*jd5vX0-9YAZDB0!ZXWHoi?rWv(QKw@HXL1N4_)UlUFRHKt1jKvx45RR^9Eee zSK1jSLV9(O?iA$z2{L5EE1coH02oVvn{!~e6xQj4btYjgJw%I*koX8G5Fv#jqy*%9 zHuAj$`QCwiA3?rPAm7c~KfX2VP?>eA%%~f;lfqC^EJ{j1Nu?;M7S-xRwMNlaGNz-4 z>98@FkHLW$7KUN5SY9^9J-zl3ZvI5c^Z$gg^k_cTG*gcs@DY0-M}0lxcRcnVAbdvV z_)(Sq6}LU6c06%}e4Y&3>A~~Za2_9C<^yMKhHb*(g|YCW9JsOy-dh9j7=evQh;@K| zok+hy6x=8ZZjuDINP=4>!EKV@o04Ec65J^X?&5KKM8UnH;69Q5fJlExq&JMO+`+)o zqSMA?oI4WET^V0!+JeP`=!`38z9p#h?M}{$^YSQ>5U#W2(>Gg*%iz25(!=^!OMksg%H0;$E)f1CFxbt zC`=-29_+*6+=rK+JS3GOq)w!80x6tEwDeFNHmVbd!eJYiT9r$= z6;f`c+@(sc!H!s6mRntwTV0b|)yS=CsYUBQ@%q+h2}PPYMxJ(E zoObC%VTEePMR4v(5myuZKB(gU^8nU;1=s2$v$#lu6Vl*`7_3EZ??Y}UBezc@EoDec z7t%6@v`ir_ACQ<|T|4BiopRSM)y^K(&R*5dK9Os`$aPR899BziD~d;WpT^ZfIo-tl ze_!Q6vvliV-ENrm3RX}M-HV^rjeaulLT;}|TEdZ*L}W`I(oPv%KyqvQ&o#OU{?Q1l z#Mt0pZ(V!juDx>CK8b6*E*QjJ Dj?60$W|Cg4jYm`b6<}3sSO{DwvnDpXKAPlA8 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 literal 0 HcmV?d00001 diff --git a/test/tiff2bw-palette-1c-8b.sh b/test/tiff2bw-palette-1c-8b.sh new file mode 100755 index 0000000..45fe63b --- /dev/null +++ b/test/tiff2bw-palette-1c-8b.sh @@ -0,0 +1,7 @@ +#!/bin/sh +# Generated file, master is Makefile.am +. ${srcdir:-.}/common.sh +infile="$srcdir/images/palette-1c-8b.tiff" +outfile="o-tiff2bw-palette-1c-8b.tiff" +f_test_convert "$TIFF2BW" $infile $outfile +f_tiffinfo_validate $outfile diff --git a/test/tiff2bw-quad-lzw-compat.sh b/test/tiff2bw-quad-lzw-compat.sh new file mode 100755 index 0000000..bf5d5c9 --- /dev/null +++ b/test/tiff2bw-quad-lzw-compat.sh @@ -0,0 +1,7 @@ +#!/bin/sh +# Generated file, master is Makefile.am +. ${srcdir:-.}/common.sh +infile="$srcdir/images/quad-lzw-compat.tiff" +outfile="o-tiff2bw-quad-lzw-compat.tiff" +f_test_convert "$TIFF2BW" $infile $outfile +f_tiffinfo_validate $outfile diff --git a/test/tiff2bw-rgb-3c-8b.sh b/test/tiff2bw-rgb-3c-8b.sh new file mode 100755 index 0000000..8379f5a --- /dev/null +++ b/test/tiff2bw-rgb-3c-8b.sh @@ -0,0 +1,7 @@ +#!/bin/sh +# Generated file, master is Makefile.am +. ${srcdir:-.}/common.sh +infile="$srcdir/images/rgb-3c-8b.tiff" +outfile="o-tiff2bw-rgb-3c-8b.tiff" +f_test_convert "$TIFF2BW" $infile $outfile +f_tiffinfo_validate $outfile diff --git a/test/tiffcp-lzw-compat.sh b/test/tiffcp-lzw-compat.sh new file mode 100755 index 0000000..bfc8d84 --- /dev/null +++ b/test/tiffcp-lzw-compat.sh @@ -0,0 +1,6 @@ +#!/bin/sh +# +# Basic sanity check for tiffcp with LZW Old-LZW decompression +# +. ${srcdir:-.}/common.sh +f_test_convert "${TIFFCP} -c none" "${IMG_QUAD_LZW_COMPAT}" "o-tiffcp-lzw-compat.tiff" \ No newline at end of file diff --git a/tools/fax2tiff.c b/tools/fax2tiff.c index e00de52..f23374e 100644 --- a/tools/fax2tiff.c +++ b/tools/fax2tiff.c @@ -1,4 +1,4 @@ -/* $Id: fax2tiff.c,v 1.25 2016-10-25 22:22:45 erouault Exp $ */ +/* $Id: fax2tiff.c,v 1.28 2017-10-29 18:28:45 bfriesen Exp $ */ /* * Copyright (c) 1990-1997 Sam Leffler @@ -370,6 +370,10 @@ copyFaxFile(TIFF* tifin, TIFF* tifout) int ok; tifin->tif_rawdatasize = (tmsize_t)TIFFGetFileSize(tifin); + if (tifin->tif_rawdatasize == 0) { + TIFFError(tifin->tif_name, "Empty input file"); + return (0); + } tifin->tif_rawdata = _TIFFmalloc(tifin->tif_rawdatasize); if (tifin->tif_rawdata == NULL) { TIFFError(tifin->tif_name, "Not enough memory"); diff --git a/tools/raw2tiff.c b/tools/raw2tiff.c index 7298e80..083e9ee 100644 --- a/tools/raw2tiff.c +++ b/tools/raw2tiff.c @@ -1,4 +1,4 @@ -/* $Id: raw2tiff.c,v 1.28 2015-08-19 02:31:04 bfriesen Exp $ +/* $Id: raw2tiff.c,v 1.29 2017-01-14 13:12:33 erouault Exp $ * * Project: libtiff tools * Purpose: Convert raw byte sequences in TIFF images @@ -408,8 +408,14 @@ guessSize(int fd, TIFFDataType dtype, _TIFF_off_t hdr_size, uint32 nbands, } else if (*width == 0 && *length == 0) { unsigned int fail = 0; fprintf(stderr, "Image width and height are not specified.\n"); + w = (uint32) sqrt(imagesize / longt); + if( w == 0 ) + { + fprintf(stderr, "Too small image size.\n"); + return -1; + } - for (w = (uint32) sqrt(imagesize / longt); + for (; w < sqrt(imagesize * longt); w++) { if (imagesize % w == 0) { diff --git a/tools/tiff2bw.c b/tools/tiff2bw.c index 743f455..dad54af 100644 --- a/tools/tiff2bw.c +++ b/tools/tiff2bw.c @@ -1,4 +1,4 @@ -/* $Id: tiff2bw.c,v 1.19 2016-08-15 22:01:31 erouault Exp $ */ +/* $Id: tiff2bw.c,v 1.21 2017-11-01 13:41:58 bfriesen Exp $ */ /* * Copyright (c) 1988-1997 Sam Leffler @@ -131,6 +131,11 @@ main(int argc, char* argv[]) extern int optind; extern char *optarg; #endif + + in = (TIFF *) NULL; + out = (TIFF *) NULL; + inbuf = (unsigned char *) NULL; + outbuf = (unsigned char *) NULL; while ((c = getopt(argc, argv, "c:r:R:G:B:")) != -1) switch (c) { @@ -165,24 +170,24 @@ main(int argc, char* argv[]) fprintf(stderr, "%s: Bad photometric; can only handle RGB and Palette images.\n", argv[optind]); - return (-1); + goto tiff2bw_error; } TIFFGetField(in, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel); if (samplesperpixel != 1 && samplesperpixel != 3) { fprintf(stderr, "%s: Bad samples/pixel %u.\n", argv[optind], samplesperpixel); - return (-1); + goto tiff2bw_error; } if( photometric == PHOTOMETRIC_RGB && samplesperpixel != 3) { fprintf(stderr, "%s: Bad samples/pixel %u for PHOTOMETRIC_RGB.\n", argv[optind], samplesperpixel); - return (-1); + goto tiff2bw_error; } TIFFGetField(in, TIFFTAG_BITSPERSAMPLE, &bitspersample); if (bitspersample != 8) { fprintf(stderr, " %s: Sorry, only handle 8-bit samples.\n", argv[optind]); - return (-1); + goto tiff2bw_error; } TIFFGetField(in, TIFFTAG_IMAGEWIDTH, &w); TIFFGetField(in, TIFFTAG_IMAGELENGTH, &h); @@ -190,7 +195,9 @@ main(int argc, char* argv[]) out = TIFFOpen(argv[optind+1], "w"); if (out == NULL) - return (-1); + { + goto tiff2bw_error; + } TIFFSetField(out, TIFFTAG_IMAGEWIDTH, w); TIFFSetField(out, TIFFTAG_IMAGELENGTH, h); TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, 8); @@ -264,7 +271,7 @@ main(int argc, char* argv[]) for (s = 0; s < 3; s++) if (TIFFReadScanline(in, inbuf+s*rowsize, row, s) < 0) - return (-1); + goto tiff2bw_error; compresssep(outbuf, inbuf, inbuf+rowsize, inbuf+2*rowsize, w); if (TIFFWriteScanline(out, outbuf, row, 0) < 0) @@ -273,8 +280,24 @@ main(int argc, char* argv[]) break; } #undef pack + if (inbuf) + _TIFFfree(inbuf); + if (outbuf) + _TIFFfree(outbuf); + TIFFClose(in); TIFFClose(out); return (0); + + tiff2bw_error: + if (inbuf) + _TIFFfree(inbuf); + if (outbuf) + _TIFFfree(outbuf); + if (out) + TIFFClose(out); + if (in) + TIFFClose(in); + return (-1); } static int diff --git a/tools/tiff2pdf.c b/tools/tiff2pdf.c index fe8a6ea..454befb 100644 --- a/tools/tiff2pdf.c +++ b/tools/tiff2pdf.c @@ -1,4 +1,4 @@ -/* $Id: tiff2pdf.c,v 1.97 2016-11-11 21:28:24 erouault Exp $ +/* $Id: tiff2pdf.c,v 1.103 2017-10-29 18:50:41 bfriesen Exp $ * * tiff2pdf - converts a TIFF image to a PDF document * @@ -1737,7 +1737,12 @@ void t2p_read_tiff_data(T2P* t2p, TIFF* input){ return; t2p->pdf_transcode = T2P_TRANSCODE_ENCODE; - if(t2p->pdf_nopassthrough==0){ + /* It seems that T2P_TRANSCODE_RAW mode doesn't support separate->contig */ + /* conversion. At least t2p_read_tiff_size and t2p_read_tiff_size_tile */ + /* do not take into account the number of samples, and thus */ + /* that can cause heap buffer overflows such as in */ + /* http://bugzilla.maptools.org/show_bug.cgi?id=2715 */ + if(t2p->pdf_nopassthrough==0 && t2p->tiff_planar!=PLANARCONFIG_SEPARATE){ #ifdef CCITT_SUPPORT if(t2p->tiff_compression==COMPRESSION_CCITTFAX4 ){ @@ -2895,7 +2900,8 @@ tsize_t t2p_readwrite_pdf_image_tile(T2P* t2p, TIFF* input, TIFF* output, ttile_ return(0); } if(TIFFGetField(input, TIFFTAG_JPEGTABLES, &count, &jpt) != 0) { - if (count >= 4) { + if (count > 4) { + int retTIFFReadRawTile; /* Ignore EOI marker of JpegTables */ _TIFFmemcpy(buffer, jpt, count - 2); bufferoffset += count - 2; @@ -2903,22 +2909,23 @@ tsize_t t2p_readwrite_pdf_image_tile(T2P* t2p, TIFF* input, TIFF* output, ttile_ table_end[0] = buffer[bufferoffset-2]; table_end[1] = buffer[bufferoffset-1]; xuint32 = bufferoffset; - bufferoffset -= 2; - bufferoffset += TIFFReadRawTile( + bufferoffset -= 2; + retTIFFReadRawTile= TIFFReadRawTile( input, tile, (tdata_t) &(((unsigned char*)buffer)[bufferoffset]), -1); + if( retTIFFReadRawTile < 0 ) + { + _TIFFfree(buffer); + t2p->t2p_error = T2P_ERR_ERROR; + return(0); + } + bufferoffset += retTIFFReadRawTile; /* Overwrite SOI marker of image scan with previously */ /* saved end of JpegTables */ buffer[xuint32-2]=table_end[0]; buffer[xuint32-1]=table_end[1]; - } else { - bufferoffset += TIFFReadRawTile( - input, - tile, - (tdata_t) &(((unsigned char*)buffer)[bufferoffset]), - -1); } } t2pWriteFile(output, (tdata_t) buffer, bufferoffset); @@ -3593,7 +3600,8 @@ void t2p_tile_collapse_left( edgescanwidth = (scanwidth * edgetilewidth + (tilewidth - 1))/ tilewidth; for(i=0;itiff_width*t2p->tiff_length; component_count=t2p->tiff_samplesperpixel; + data_size=TIFFSafeMultiply(size_t,sample_count,component_count); + if( (data_size == 0U) || (t2p->tiff_datasize < 0) || + (data_size > (size_t) t2p->tiff_datasize) ) + { + TIFFError(TIFF2PDF_MODULE, + "Error: sample_count * component_count > t2p->tiff_datasize"); + t2p->t2p_error = T2P_ERR_ERROR; + return 1; + } for(i=sample_count;i>0;i--){ palette_offset=buffer[i-1] * component_count; diff --git a/tools/tiff2ps.c b/tools/tiff2ps.c index 82a5d84..f1f0b37 100644 --- a/tools/tiff2ps.c +++ b/tools/tiff2ps.c @@ -1,4 +1,4 @@ -/* $Id: tiff2ps.c,v 1.54 2015-06-21 01:09:10 bfriesen Exp $ */ +/* $Id: tiff2ps.c,v 1.56 2017-04-27 15:46:22 erouault Exp $ */ /* * Copyright (c) 1988-1997 Sam Leffler @@ -466,10 +466,16 @@ main(int argc, char* argv[]) if (tif != NULL) { if (dirnum != -1 && !TIFFSetDirectory(tif, (tdir_t)dirnum)) + { + TIFFClose(tif); return (-1); + } else if (diroff != 0 && !TIFFSetSubDirectory(tif, diroff)) + { + TIFFClose(tif); return (-1); + } np = TIFF2PS(output, tif, pageWidth, pageHeight, leftmargin, bottommargin, centered); if (np < 0) @@ -2440,6 +2446,11 @@ PSDataColorContig(FILE* fd, TIFF* tif, uint32 w, uint32 h, int nc) unsigned char *cp, c; (void) w; + if( es <= 0 ) + { + TIFFError(filename, "Inconsistent value of es: %d", es); + return; + } tf_buf = (unsigned char *) _TIFFmalloc(tf_bytesperrow); if (tf_buf == NULL) { TIFFError(filename, "No space for scanline buffer"); @@ -2692,7 +2703,7 @@ PSDataBW(FILE* fd, TIFF* tif, uint32 w, uint32 h) if (alpha) { int adjust; - while (cc-- > 0) { + while (cc-- > 1) { DOBREAK(breaklen, 1, fd); /* * For images with alpha, matte against diff --git a/tools/tiffcp.c b/tools/tiffcp.c index 338a3d1..489459a 100644 --- a/tools/tiffcp.c +++ b/tools/tiffcp.c @@ -1,4 +1,4 @@ -/* $Id: tiffcp.c,v 1.55 2016-10-08 15:54:57 erouault Exp $ */ +/* $Id: tiffcp.c,v 1.61 2017-01-11 19:26:14 erouault Exp $ */ /* * Copyright (c) 1988-1997 Sam Leffler @@ -45,7 +45,6 @@ #include #include -#include #ifdef HAVE_UNISTD_H # include @@ -592,7 +591,7 @@ static copyFunc pickCopyFunc(TIFF*, TIFF*, uint16, uint16); static int tiffcp(TIFF* in, TIFF* out) { - uint16 bitspersample, samplesperpixel = 1; + uint16 bitspersample = 1, samplesperpixel = 1; uint16 input_compression, input_photometric = PHOTOMETRIC_MINISBLACK; copyFunc cf; uint32 width, length; @@ -985,7 +984,7 @@ DECLAREcpFunc(cpDecodedStrips) tstrip_t s, ns = TIFFNumberOfStrips(in); uint32 row = 0; _TIFFmemset(buf, 0, stripsize); - for (s = 0; s < ns; s++) { + for (s = 0; s < ns && row < imagelength; s++) { tsize_t cc = (row + rowsperstrip > imagelength) ? TIFFVStripSize(in, imagelength - row) : stripsize; if (TIFFReadEncodedStrip(in, s, buf, cc) < 0 @@ -1068,6 +1067,16 @@ DECLAREcpFunc(cpContig2SeparateByRow) register uint32 n; uint32 row; tsample_t s; + uint16 bps = 0; + + (void) TIFFGetField(in, TIFFTAG_BITSPERSAMPLE, &bps); + if( bps != 8 ) + { + TIFFError(TIFFFileName(in), + "Error, can only handle BitsPerSample=8 in %s", + "cpContig2SeparateByRow"); + return 0; + } inbuf = _TIFFmalloc(scanlinesizein); outbuf = _TIFFmalloc(scanlinesizeout); @@ -1121,6 +1130,16 @@ DECLAREcpFunc(cpSeparate2ContigByRow) register uint32 n; uint32 row; tsample_t s; + uint16 bps = 0; + + (void) TIFFGetField(in, TIFFTAG_BITSPERSAMPLE, &bps); + if( bps != 8 ) + { + TIFFError(TIFFFileName(in), + "Error, can only handle BitsPerSample=8 in %s", + "cpSeparate2ContigByRow"); + return 0; + } inbuf = _TIFFmalloc(scanlinesizein); outbuf = _TIFFmalloc(scanlinesizeout); @@ -1163,7 +1182,7 @@ bad: static void cpStripToTile(uint8* out, uint8* in, - uint32 rows, uint32 cols, int outskew, int inskew) + uint32 rows, uint32 cols, int outskew, int64 inskew) { while (rows-- > 0) { uint32 j = cols; @@ -1320,7 +1339,7 @@ DECLAREreadFunc(readContigTilesIntoBuffer) tdata_t tilebuf; uint32 imagew = TIFFScanlineSize(in); uint32 tilew = TIFFTileRowSize(in); - int iskew = imagew - tilew; + int64 iskew = (int64)imagew - (int64)tilew; uint8* bufp = (uint8*) buf; uint32 tw, tl; uint32 row; @@ -1348,7 +1367,7 @@ DECLAREreadFunc(readContigTilesIntoBuffer) status = 0; goto done; } - if (colb + tilew > imagew) { + if (colb > iskew) { uint32 width = imagew - colb; uint32 oskew = tilew - width; cpStripToTile(bufp + colb, @@ -1378,7 +1397,7 @@ DECLAREreadFunc(readSeparateTilesIntoBuffer) uint8* bufp = (uint8*) buf; uint32 tw, tl; uint32 row; - uint16 bps, bytes_per_sample; + uint16 bps = 0, bytes_per_sample; tilebuf = _TIFFmalloc(tilesize); if (tilebuf == 0) @@ -1387,7 +1406,18 @@ DECLAREreadFunc(readSeparateTilesIntoBuffer) (void) TIFFGetField(in, TIFFTAG_TILEWIDTH, &tw); (void) TIFFGetField(in, TIFFTAG_TILELENGTH, &tl); (void) TIFFGetField(in, TIFFTAG_BITSPERSAMPLE, &bps); - assert( bps % 8 == 0 ); + if( bps == 0 ) + { + TIFFError(TIFFFileName(in), "Error, cannot read BitsPerSample"); + status = 0; + goto done; + } + if( (bps % 8) != 0 ) + { + TIFFError(TIFFFileName(in), "Error, cannot handle BitsPerSample that is not a multiple of 8"); + status = 0; + goto done; + } bytes_per_sample = bps/8; for (row = 0; row < imagelength; row += tl) { @@ -1563,7 +1593,7 @@ DECLAREwriteFunc(writeBufferToSeparateTiles) uint8* bufp = (uint8*) buf; uint32 tl, tw; uint32 row; - uint16 bps, bytes_per_sample; + uint16 bps = 0, bytes_per_sample; obuf = _TIFFmalloc(TIFFTileSize(out)); if (obuf == NULL) @@ -1572,7 +1602,18 @@ DECLAREwriteFunc(writeBufferToSeparateTiles) (void) TIFFGetField(out, TIFFTAG_TILELENGTH, &tl); (void) TIFFGetField(out, TIFFTAG_TILEWIDTH, &tw); (void) TIFFGetField(out, TIFFTAG_BITSPERSAMPLE, &bps); - assert( bps % 8 == 0 ); + if( bps == 0 ) + { + TIFFError(TIFFFileName(out), "Error, cannot read BitsPerSample"); + _TIFFfree(obuf); + return 0; + } + if( (bps % 8) != 0 ) + { + TIFFError(TIFFFileName(out), "Error, cannot handle BitsPerSample that is not a multiple of 8"); + _TIFFfree(obuf); + return 0; + } bytes_per_sample = bps/8; for (row = 0; row < imagelength; row += tl) { @@ -1763,7 +1804,7 @@ pickCopyFunc(TIFF* in, TIFF* out, uint16 bitspersample, uint16 samplesperpixel) uint32 w, l, tw, tl; int bychunk; - (void) TIFFGetField(in, TIFFTAG_PLANARCONFIG, &shortv); + (void) TIFFGetFieldDefaulted(in, TIFFTAG_PLANARCONFIG, &shortv); if (shortv != config && bitspersample != 8 && samplesperpixel > 1) { fprintf(stderr, "%s: Cannot handle different planar configuration w/ bits/sample != 8\n", diff --git a/tools/tiffcrop.c b/tools/tiffcrop.c index 722b132..c69177e 100644 --- a/tools/tiffcrop.c +++ b/tools/tiffcrop.c @@ -1,4 +1,4 @@ -/* $Id: tiffcrop.c,v 1.46 2016-11-18 14:58:46 erouault Exp $ */ +/* $Id: tiffcrop.c,v 1.50 2017-01-11 12:51:59 erouault Exp $ */ /* tiffcrop.c -- a port of tiffcp.c extended to include manipulations of * the image data through additional options listed below @@ -1164,7 +1164,7 @@ writeBufferToSeparateStrips (TIFF* out, uint8* buf, tdata_t obuf; (void) TIFFGetFieldDefaulted(out, TIFFTAG_ROWSPERSTRIP, &rowsperstrip); - (void) TIFFGetField(out, TIFFTAG_BITSPERSAMPLE, &bps); + (void) TIFFGetFieldDefaulted(out, TIFFTAG_BITSPERSAMPLE, &bps); bytes_per_sample = (bps + 7) / 8; if( width == 0 || (uint32)bps * (uint32)spp > TIFF_UINT32_MAX / width || @@ -3698,7 +3698,7 @@ static int readContigStripsIntoBuffer (TIFF* in, uint8* buf) (unsigned long) strip, (unsigned long)rows); return 0; } - bufp += bytes_read; + bufp += stripsize; } return 1; @@ -4760,7 +4760,7 @@ static int readSeparateStripsIntoBuffer (TIFF *in, uint8 *obuf, uint32 length, int i, bytes_per_sample, bytes_per_pixel, shift_width, result = 1; uint32 j; int32 bytes_read = 0; - uint16 bps, planar; + uint16 bps = 0, planar; uint32 nstrips; uint32 strips_per_sample; uint32 src_rowsize, dst_rowsize, rows_processed, rps; @@ -4780,7 +4780,7 @@ static int readSeparateStripsIntoBuffer (TIFF *in, uint8 *obuf, uint32 length, } memset (srcbuffs, '\0', sizeof(srcbuffs)); - TIFFGetField(in, TIFFTAG_BITSPERSAMPLE, &bps); + TIFFGetFieldDefaulted(in, TIFFTAG_BITSPERSAMPLE, &bps); TIFFGetFieldDefaulted(in, TIFFTAG_PLANARCONFIG, &planar); TIFFGetFieldDefaulted(in, TIFFTAG_ROWSPERSTRIP, &rps); if (rps > length) @@ -4815,10 +4815,17 @@ static int readSeparateStripsIntoBuffer (TIFF *in, uint8 *obuf, uint32 length, nstrips = TIFFNumberOfStrips(in); strips_per_sample = nstrips /spp; + /* Add 3 padding bytes for combineSeparateSamples32bits */ + if( (size_t) stripsize > 0xFFFFFFFFU - 3U ) + { + TIFFError("readSeparateStripsIntoBuffer", "Integer overflow when calculating buffer size."); + exit(-1); + } + for (s = 0; (s < spp) && (s < MAX_SAMPLES); s++) { srcbuffs[s] = NULL; - buff = _TIFFmalloc(stripsize); + buff = _TIFFmalloc(stripsize + 3); if (!buff) { TIFFError ("readSeparateStripsIntoBuffer", @@ -4827,6 +4834,9 @@ static int readSeparateStripsIntoBuffer (TIFF *in, uint8 *obuf, uint32 length, _TIFFfree (srcbuffs[i]); return 0; } + buff[stripsize] = 0; + buff[stripsize+1] = 0; + buff[stripsize+2] = 0; srcbuffs[s] = buff; } @@ -7986,7 +7996,6 @@ writeCroppedImage(TIFF *in, TIFF *out, struct image_data *image, if (!TIFFWriteDirectory(out)) { TIFFError("","Failed to write IFD for page number %d", pagenum); - TIFFClose(out); return (-1); } diff --git a/tools/tiffinfo.c b/tools/tiffinfo.c index b02c7d4..4d58055 100644 --- a/tools/tiffinfo.c +++ b/tools/tiffinfo.c @@ -1,4 +1,4 @@ -/* $Id: tiffinfo.c,v 1.25 2016-11-12 20:06:05 bfriesen Exp $ */ +/* $Id: tiffinfo.c,v 1.26 2016-12-03 14:18:49 erouault Exp $ */ /* * Copyright (c) 1988-1997 Sam Leffler @@ -417,7 +417,7 @@ TIFFReadRawData(TIFF* tif, int bitrev) uint64* stripbc=NULL; TIFFGetField(tif, TIFFTAG_STRIPBYTECOUNTS, &stripbc); - if (nstrips > 0) { + if (stripbc != NULL && nstrips > 0) { uint32 bufsize = (uint32) stripbc[0]; tdata_t buf = _TIFFmalloc(bufsize); tstrip_t s; diff --git a/tools/tiffset.c b/tools/tiffset.c index 7044d2b..894c9f1 100644 --- a/tools/tiffset.c +++ b/tools/tiffset.c @@ -1,5 +1,5 @@ /****************************************************************************** - * $Id: tiffset.c,v 1.18 2012-12-04 03:02:37 bfriesen Exp $ + * $Id: tiffset.c,v 1.19 2017-10-01 17:38:12 erouault Exp $ * * Project: libtiff tools * Purpose: Mainline for setting metadata in existing TIFF files. @@ -155,7 +155,7 @@ main(int argc, char* argv[]) return 4; } - if (wc > 1) { + if (wc > 1 || TIFFFieldWriteCount(fip) == TIFF_VARIABLE) { int i, size; void *array; -- 2.7.4