diff --git a/src/fuzz/populate_corpora.py b/src/fuzz/populate_corpora.py index 4c85905a7c..afcac7f4bb 100644 --- a/src/fuzz/populate_corpora.py +++ b/src/fuzz/populate_corpora.py @@ -144,6 +144,7 @@ def _find_images_root() -> Path: ("../oiio-images/targa", ["tga", "TGA"]), ], "tiff": [ + ("testsuite/tiff-misc/src", ["tif", "tiff"]), ("../oiio-images", ["tif", "tiff"]), ("../oiio-images/libtiffpic",["tif", "tiff"]), ("testsuite/tiff-suite/src", ["tif", "tiff"]), diff --git a/src/tiff.imageio/tiffinput.cpp b/src/tiff.imageio/tiffinput.cpp index a9f90a91fc..fdfcd4e77d 100644 --- a/src/tiff.imageio/tiffinput.cpp +++ b/src/tiff.imageio/tiffinput.cpp @@ -1962,7 +1962,7 @@ TIFFInput::read_native_scanline_locked(int subimage, int miplevel, int y, } // Make sure there's enough scratch space - int nvals = m_spec.width * m_inputchannels; + imagesize_t nvals = imagesize_t(m_spec.width) * m_inputchannels; if (m_photometric == PHOTOMETRIC_PALETTE && m_bitspersample > 8) m_scratch.resize(nvals * 2); // special case for 16 bit palette else @@ -2279,6 +2279,7 @@ TIFFInput::read_native_scanlines(int subimage, int miplevel, int ybegin, read_raw_strips ? "Raw" : "Encoded", y, err.size() ? err.c_str() : "unknown error"); ok = false; + break; // failed strip read -- bail, don't decompress } auto out = this; auto uncompress_etc = [=, &ok](int /*id*/) { @@ -2345,7 +2346,7 @@ TIFFInput::read_native_scanlines(int subimage, int miplevel, int ybegin, // If we have left over scanlines, read them serially m_next_scanline = y - m_spec.y; - for (; y < yend; ++y) { + for (; ok && y < yend; ++y) { if (!read_native_scanline_locked(subimage, miplevel, y, data)) { ok = false; break; diff --git a/testsuite/tiff-misc/ref/out-libtiff403-b.txt b/testsuite/tiff-misc/ref/out-libtiff403-b.txt index 64188cf31d..3bd70e1779 100644 --- a/testsuite/tiff-misc/ref/out-libtiff403-b.txt +++ b/testsuite/tiff-misc/ref/out-libtiff403-b.txt @@ -58,5 +58,8 @@ src/crash-cmyk-1bit.tif : 73 x 43, 3 channel, uint1 tiff tiff:PhotometricInterpretation: 5 tiff:PlanarConfiguration: 1 tiff:RowsPerStrip: 28 +oiiotool ERROR: read : "src/crash-rawstrip-offset-past-eof.tif": TIFFReadRawStrip failed reading line y=0: Read error at scanline 4294967295; got 0 bytes, expected 28 +Full command line was: +> oiiotool --oiioattrib try_all_readers 0 src/crash-rawstrip-offset-past-eof.tif -o out.exr Comparing "check1.tif" and "ref/check1.tif" PASS diff --git a/testsuite/tiff-misc/ref/out-libtiff403-c.txt b/testsuite/tiff-misc/ref/out-libtiff403-c.txt index 0add5ff244..de0d58c72d 100644 --- a/testsuite/tiff-misc/ref/out-libtiff403-c.txt +++ b/testsuite/tiff-misc/ref/out-libtiff403-c.txt @@ -58,5 +58,8 @@ src/crash-cmyk-1bit.tif : 73 x 43, 3 channel, uint1 tiff tiff:PhotometricInterpretation: 5 tiff:PlanarConfiguration: 1 tiff:RowsPerStrip: 28 +oiiotool ERROR: read : "src/crash-rawstrip-offset-past-eof.tif": TIFFReadRawStrip failed reading line y=0: Read error at scanline 4294967295; got 0 bytes, expected 28 +Full command line was: +> oiiotool --oiioattrib try_all_readers 0 src/crash-rawstrip-offset-past-eof.tif -o out.exr Comparing "check1.tif" and "ref/check1.tif" PASS diff --git a/testsuite/tiff-misc/ref/out-libtiff403.txt b/testsuite/tiff-misc/ref/out-libtiff403.txt index 643ca1b8cf..0837fc8a11 100644 --- a/testsuite/tiff-misc/ref/out-libtiff403.txt +++ b/testsuite/tiff-misc/ref/out-libtiff403.txt @@ -58,5 +58,8 @@ src/crash-cmyk-1bit.tif : 73 x 43, 3 channel, uint1 tiff tiff:PhotometricInterpretation: 5 tiff:PlanarConfiguration: 1 tiff:RowsPerStrip: 28 +oiiotool ERROR: read : "src/crash-rawstrip-offset-past-eof.tif": TIFFReadRawStrip failed reading line y=0: Read error at scanline 4294967295; got 0 bytes, expected 28 +Full command line was: +> oiiotool --oiioattrib try_all_readers 0 src/crash-rawstrip-offset-past-eof.tif -o out.exr Comparing "check1.tif" and "ref/check1.tif" PASS diff --git a/testsuite/tiff-misc/ref/out-libtiff409.txt b/testsuite/tiff-misc/ref/out-libtiff409.txt index 8cd8867ea7..678ab158e8 100644 --- a/testsuite/tiff-misc/ref/out-libtiff409.txt +++ b/testsuite/tiff-misc/ref/out-libtiff409.txt @@ -58,5 +58,8 @@ src/crash-cmyk-1bit.tif : 73 x 43, 3 channel, uint1 tiff tiff:PhotometricInterpretation: 5 tiff:PlanarConfiguration: 1 tiff:RowsPerStrip: 28 +oiiotool ERROR: read : "src/crash-rawstrip-offset-past-eof.tif": TIFFReadRawStrip failed reading line y=0: Read error at scanline 4294967295; got 0 bytes, expected 28 +Full command line was: +> oiiotool --oiioattrib try_all_readers 0 src/crash-rawstrip-offset-past-eof.tif -o out.exr Comparing "check1.tif" and "ref/check1.tif" PASS diff --git a/testsuite/tiff-misc/ref/out-libtiff410.txt b/testsuite/tiff-misc/ref/out-libtiff410.txt index 5f08284b0c..567ac0d5af 100644 --- a/testsuite/tiff-misc/ref/out-libtiff410.txt +++ b/testsuite/tiff-misc/ref/out-libtiff410.txt @@ -58,5 +58,8 @@ src/crash-cmyk-1bit.tif : 73 x 43, 3 channel, uint1 tiff tiff:PhotometricInterpretation: 5 tiff:PlanarConfiguration: 1 tiff:RowsPerStrip: 28 +oiiotool ERROR: read : "src/crash-rawstrip-offset-past-eof.tif": TIFFReadRawStrip failed reading line y=0: Read error at scanline 4294967295; got 0 bytes, expected 28 +Full command line was: +> oiiotool --oiioattrib try_all_readers 0 src/crash-rawstrip-offset-past-eof.tif -o out.exr Comparing "check1.tif" and "ref/check1.tif" PASS diff --git a/testsuite/tiff-misc/ref/out-libtiff430.txt b/testsuite/tiff-misc/ref/out-libtiff430.txt index 73d139c156..65307292ff 100644 --- a/testsuite/tiff-misc/ref/out-libtiff430.txt +++ b/testsuite/tiff-misc/ref/out-libtiff430.txt @@ -73,5 +73,8 @@ src/crash-cmyk-1bit.tif : 73 x 43, 3 channel, uint1 tiff tiff:PhotometricInterpretation: 5 tiff:PlanarConfiguration: 1 tiff:RowsPerStrip: 28 +oiiotool ERROR: read : "src/crash-rawstrip-offset-past-eof.tif": TIFFReadRawStrip failed reading line y=0: Read error at scanline 4294967295; got 0 bytes, expected 28 +Full command line was: +> oiiotool --oiioattrib try_all_readers 0 src/crash-rawstrip-offset-past-eof.tif -o out.exr Comparing "check1.tif" and "ref/check1.tif" PASS diff --git a/testsuite/tiff-misc/ref/out-libtiff470-b.txt b/testsuite/tiff-misc/ref/out-libtiff470-b.txt index 6bebe2b474..168a14b43c 100644 --- a/testsuite/tiff-misc/ref/out-libtiff470-b.txt +++ b/testsuite/tiff-misc/ref/out-libtiff470-b.txt @@ -73,5 +73,8 @@ src/crash-cmyk-1bit.tif : 73 x 43, 3 channel, uint1 tiff tiff:PhotometricInterpretation: 5 tiff:PlanarConfiguration: 1 tiff:RowsPerStrip: 28 +oiiotool ERROR: read : "src/crash-rawstrip-offset-past-eof.tif": TIFFReadRawStrip failed reading line y=0: Read error at scanline 4294967295; got 0 bytes, expected 28 +Full command line was: +> oiiotool --oiioattrib try_all_readers 0 src/crash-rawstrip-offset-past-eof.tif -o out.exr Comparing "check1.tif" and "ref/check1.tif" PASS diff --git a/testsuite/tiff-misc/ref/out-libtiff470-c.txt b/testsuite/tiff-misc/ref/out-libtiff470-c.txt index 61dc38ee9d..f00e9c69b7 100644 --- a/testsuite/tiff-misc/ref/out-libtiff470-c.txt +++ b/testsuite/tiff-misc/ref/out-libtiff470-c.txt @@ -73,5 +73,8 @@ src/crash-cmyk-1bit.tif : 73 x 43, 3 channel, uint1 tiff tiff:PhotometricInterpretation: 5 tiff:PlanarConfiguration: 1 tiff:RowsPerStrip: 28 +oiiotool ERROR: read : "src/crash-rawstrip-offset-past-eof.tif": TIFFReadRawStrip failed reading line y=0: Read error at scanline 4294967295; got 0 bytes, expected 28 +Full command line was: +> oiiotool --oiioattrib try_all_readers 0 src/crash-rawstrip-offset-past-eof.tif -o out.exr Comparing "check1.tif" and "ref/check1.tif" PASS diff --git a/testsuite/tiff-misc/ref/out-libtiff470.txt b/testsuite/tiff-misc/ref/out-libtiff470.txt index a86c32046d..ec4bcd9899 100644 --- a/testsuite/tiff-misc/ref/out-libtiff470.txt +++ b/testsuite/tiff-misc/ref/out-libtiff470.txt @@ -73,5 +73,8 @@ src/crash-cmyk-1bit.tif : 73 x 43, 3 channel, uint1 tiff tiff:PhotometricInterpretation: 5 tiff:PlanarConfiguration: 1 tiff:RowsPerStrip: 28 +oiiotool ERROR: read : "src/crash-rawstrip-offset-past-eof.tif": TIFFReadRawStrip failed reading line y=0: Read error at scanline 4294967295; got 0 bytes, expected 28 +Full command line was: +> oiiotool --oiioattrib try_all_readers 0 src/crash-rawstrip-offset-past-eof.tif -o out.exr Comparing "check1.tif" and "ref/check1.tif" PASS diff --git a/testsuite/tiff-misc/ref/out.txt b/testsuite/tiff-misc/ref/out.txt index 707d956136..d641064155 100644 --- a/testsuite/tiff-misc/ref/out.txt +++ b/testsuite/tiff-misc/ref/out.txt @@ -58,5 +58,8 @@ src/crash-cmyk-1bit.tif : 73 x 43, 3 channel, uint1 tiff tiff:PhotometricInterpretation: 5 tiff:PlanarConfiguration: 1 tiff:RowsPerStrip: 28 +oiiotool ERROR: read : "src/crash-rawstrip-offset-past-eof.tif": TIFFReadRawStrip failed reading line y=0: Read error at scanline 4294967295; got 0 bytes, expected 28 +Full command line was: +> oiiotool --oiioattrib try_all_readers 0 src/crash-rawstrip-offset-past-eof.tif -o out.exr Comparing "check1.tif" and "ref/check1.tif" PASS diff --git a/testsuite/tiff-misc/run.py b/testsuite/tiff-misc/run.py index 434223de79..4dd434f37c 100755 --- a/testsuite/tiff-misc/run.py +++ b/testsuite/tiff-misc/run.py @@ -40,4 +40,9 @@ # causing a heap buffer overflow. command += info_command ("src/crash-cmyk-1bit.tif", safematch=True) +# Regression: a valid DEFLATE TIFF whose StripOffsets[0] points past EOF must +# be rejected cleanly during the pixel read (not read out of bounds). Placed +# last so its output appends at the tail of every libtiff-version ref variant. +command += oiiotool ("--oiioattrib try_all_readers 0 src/crash-rawstrip-offset-past-eof.tif -o out.exr", failureok = True) + outputs = [ "check1.tif", "out.txt" ] diff --git a/testsuite/tiff-misc/src/crash-rawstrip-offset-past-eof.tif b/testsuite/tiff-misc/src/crash-rawstrip-offset-past-eof.tif new file mode 100644 index 0000000000..f2726fc6a8 Binary files /dev/null and b/testsuite/tiff-misc/src/crash-rawstrip-offset-past-eof.tif differ