Compare commits

...

24 Commits
main ... 8.1.x

Author SHA1 Message Date
Andrew Murray
88bd672daf 8.1.2 version bump 2021-03-06 13:38:55 +11:00
Andrew Murray
d3486362da Update CHANGES.rst [ci skip] 2021-03-06 13:37:58 +11:00
Andrew Murray
2a66fa7f2e Added release notes for 8.1.2 2021-03-06 13:37:58 +11:00
Andrew Murray
608bf4fef5 Lint fix 2021-03-06 13:37:58 +11:00
Eric Soroos
756fff3312 Fix Memory DOS in Icns, Ico and Blp Image Plugins
Some container plugins that could contain images of other formats,
such as the ICNS format, did not properly check the reported size of
the contained image. These images could cause arbitrariliy large
memory allocations.

This is fixed for all locations where individual *ImageFile classes
are created without going through the usual Image.open method.
2021-03-06 13:37:58 +11:00
Hugo van Kemenade
886ad5a90e Fix filename spelling
Co-authored-by: Andrew Murray <3112309+radarhere@users.noreply.github.com>
2021-03-06 13:37:58 +11:00
Andrew Murray
0907fb13f4 Expanded "OOB" to "out-of-bounds" [ci skip] 2021-03-06 13:37:58 +11:00
heitbaum
c60c09280b CHANGES.rst: update dates 2021-03-06 13:37:58 +11:00
Andrew Murray
8fb5e5035b Added more CVE numbers [ci skip] 2021-03-05 22:05:03 +11:00
Andrew Murray
a10d2c950a Updated spelling [ci skip]
Co-authored-by: Hugo van Kemenade <hugovk@users.noreply.github.com>
2021-03-05 22:04:55 +11:00
Andrew Murray
4bdc0da7ca Corrected list of relevant dependencies [ci skip] 2021-03-05 22:04:47 +11:00
Hugo van Kemenade
20c0e1a19e Update release notes formatting, links, spelling 2021-03-05 22:04:36 +11:00
Andrew Murray
741d8744a5 8.1.1 version bump 2021-03-01 19:24:03 +11:00
Andrew Murray
179cd1c8f9 Added 8.1.1 release notes to index 2021-03-01 19:23:56 +11:00
Andrew Murray
7d296653da Update CHANGES.rst [ci skip] 2021-03-01 19:15:48 +11:00
Eric Soroos
d25036fca7 Credits 2021-03-01 19:09:20 +11:00
Eric Soroos
973a4c333a Release notes for 8.1.1 2021-03-01 19:09:14 +11:00
Hugo van Kemenade
521dab94c7 Use more specific regex chars to prevent ReDoS
* CVE-2021-25292
2021-03-01 19:08:58 +11:00
Eric Soroos
8b8076bdcb Fix for CVE-2021-25291
* Invalid tile boundaries lead to OOB Read in TiffDecode.c, in TiffReadRGBATile
* Check the tile validity before attempting to read.
2021-03-01 19:08:52 +11:00
Eric Soroos
e25be1e33d Fix negative size read in TiffDecode.c
* Caught by oss-fuzz runs
* CVE-2021-25290
2021-03-01 19:08:39 +11:00
Eric Soroos
f891baa604 Fix OOB read in SgiRleDecode.c
* From Pillow 4.3.0->8.1.0
* CVE-2021-25293
2021-03-01 19:08:26 +11:00
Eric Soroos
cbfdde7b1f Incorrect error code checking in TiffDecode.c
* since Pillow 8.1.0
* CVE-2021-25289
2021-03-01 19:08:17 +11:00
Andrew Murray
2ba5eb1cd9 PyModule_AddObject fix for Python 3.10 2021-03-01 19:08:11 +11:00
Andrew Murray
a0a5b7a01d Added import test 2021-03-01 19:08:05 +11:00
39 changed files with 240 additions and 45 deletions

View File

@ -45,6 +45,7 @@ test_script:
- cd c:\pillow
- '%PYTHON%\%EXECUTABLE% -m pip install pytest pytest-cov'
- c:\"Program Files (x86)"\"Windows Kits"\10\Debuggers\x86\gflags.exe /p /enable %PYTHON%\%EXECUTABLE%
- '%PYTHON%\%EXECUTABLE% -c "from PIL import Image"'
- '%PYTHON%\%EXECUTABLE% -m pytest -vx --cov PIL --cov Tests --cov-report term --cov-report xml Tests'
#- '%PYTHON%\%EXECUTABLE% test-installed.py -v -s %TEST_OPTIONS%' TODO TEST_OPTIONS with pytest?

View File

@ -2,4 +2,6 @@
set -e
python -bb -m pytest -v -x -W always --cov PIL --cov Tests --cov-report term Tests
python3 -c "from PIL import Image"
python3 -bb -m pytest -v -x -W always --cov PIL --cov Tests --cov-report term Tests

View File

@ -273,6 +273,7 @@ jobs:
- name: Test Pillow
run: |
python3 selftest.py --installed
python3 -c "from PIL import Image"
python3 -m pytest -vx --cov PIL --cov Tests --cov-report term --cov-report xml Tests
- name: Upload coverage

View File

@ -2,7 +2,34 @@
Changelog (Pillow)
==================
8.1.0 (2020-01-02)
8.1.2 (2021-03-06)
------------------
- Fix Memory DOS in BLP (CVE-2021-27921), ICNS (CVE-2021-27922) and ICO (CVE-2021-27923) Image Plugins
[wiredfool]
8.1.1 (2021-03-01)
------------------
- Use more specific regex chars to prevent ReDoS. CVE-2021-25292
[hugovk]
- Fix OOB Read in TiffDecode.c, and check the tile validity before reading. CVE-2021-25291
[wiredfool]
- Fix negative size read in TiffDecode.c. CVE-2021-25290
[wiredfool]
- Fix OOB read in SgiRleDecode.c. CVE-2021-25293
[wiredfool]
- Incorrect error code checking in TiffDecode.c. CVE-2021-25289
[wiredfool]
- PyModule_AddObject fix for Python 3.10 #5194
[radarhere]
8.1.0 (2021-01-02)
------------------
- Fix TIFF OOB Write error. CVE-2020-35654 #5175

View File

@ -139,3 +139,11 @@ def test_not_an_icns_file():
with io.BytesIO(b"invalid\n") as fp:
with pytest.raises(SyntaxError):
IcnsImagePlugin.IcnsFile(fp)
def test_icns_decompression_bomb():
with pytest.raises(Image.DecompressionBombError):
im = Image.open(
"Tests/images/oom-8ed3316a4109213ca96fb8a256a0bfefdece1461.icns"
)
im.load()

View File

@ -11,6 +11,13 @@ from PIL import Image
"Tests/images/sgi_crash.bin",
"Tests/images/crash-6b7f2244da6d0ae297ee0754a424213444e92778.sgi",
"Tests/images/ossfuzz-5730089102868480.sgi",
"Tests/images/crash-754d9c7ec485ffb76a90eeaab191ef69a2a3a3cd.sgi",
"Tests/images/crash-465703f71a0f0094873a3e0e82c9f798161171b8.sgi",
"Tests/images/crash-64834657ee604b8797bf99eac6a194c124a9a8ba.sgi",
"Tests/images/crash-abcf1c97b8fe42a6c68f1fb0b978530c98d57ced.sgi",
"Tests/images/crash-b82e64d4f3f76d7465b6af535283029eda211259.sgi",
"Tests/images/crash-c1b2595b8b0b92cc5f38b6635e98e3a119ade807.sgi",
"Tests/images/crash-db8bfa78b19721225425530c5946217720d7df4e.sgi",
],
)
def test_crashes(test_file):

View File

@ -24,6 +24,15 @@ from .helper import on_ci
"Tests/images/crash_1.tif",
"Tests/images/crash_2.tif",
"Tests/images/crash-2020-10-test.tif",
"Tests/images/crash-0c7e0e8e11ce787078f00b5b0ca409a167f070e0.tif",
"Tests/images/crash-0e16d3bfb83be87356d026d66919deaefca44dac.tif",
"Tests/images/crash-1152ec2d1a1a71395b6f2ce6721c38924d025bf3.tif",
"Tests/images/crash-1185209cf7655b5aed8ae5e77784dfdd18ab59e9.tif",
"Tests/images/crash-338516dbd2f0e83caddb8ce256c22db3bd6dc40f.tif",
"Tests/images/crash-4f085cc12ece8cde18758d42608bed6a2a2cfb1c.tif",
"Tests/images/crash-86214e58da443d2b80820cff9677a38a33dcbbca.tif",
"Tests/images/crash-f46f5b2f43c370fe65706c11449f567ecc345e74.tif",
"Tests/images/crash-63b1dffefc8c075ddc606c0a2f5fdc15ece78863.tif",
],
)
@pytest.mark.filterwarnings("ignore:Possibly corrupt EXIF data")

View File

@ -312,3 +312,7 @@ def setup(app):
app.add_js_file("js/script.js")
app.add_css_file("css/dark.css")
app.add_css_file("css/light.css")
# GitHub repo for sphinx-issues
issues_github_path = "python-pillow/Pillow"

View File

@ -74,7 +74,7 @@ Security
This release includes security fixes.
* :cve:`CVE-2020-10177` Fix multiple OOB reads in FLI decoding
* :cve:`CVE-2020-10177` Fix multiple out-of-bounds reads in FLI decoding
* :cve:`CVE-2020-10378` Fix bounds overflow in PCX decoding
* :cve:`CVE-2020-10379` Fix two buffer overflows in TIFF decoding
* :cve:`CVE-2020-10994` Fix bounds overflow in JPEG 2000 decoding

View File

@ -18,7 +18,7 @@ vulnerability introduced in FreeType 2.6 (:cve:`CVE-2020-15999`).
Makefile
^^^^^^^^
The 'install-venv' target has been deprecated.
The ``install-venv`` target has been deprecated.
API Additions
=============
@ -46,17 +46,18 @@ The PCX image decoder used the reported image stride to calculate the row buffer
rather than calculating it from the image size. This issue dates back to the PIL fork.
Thanks to Google's `OSS-Fuzz`_ project for finding this.
* :cve:`CVE-2020-35654` Fix TIFF OOB Write error
* :cve:`CVE-2020-35654` Fix TIFF out-of-bounds write error
OOB Write in TiffDecode.c when reading corrupt YCbCr files in some LibTIFF versions
(4.1.0/Ubuntu 20.04, but not 4.0.9/Ubuntu 18.04). In some cases LibTIFF's
interpretation of the file is different when reading in RGBA mode, leading to an Out of
bounds write in TiffDecode.c. This potentially affects Pillow versions from 6.0.0 to
8.0.1, depending on the version of LibTIFF. This was reported through `Tidelift`_.
Out-of-bounds write in ``TiffDecode.c`` when reading corrupt YCbCr files in some
LibTIFF versions (4.1.0/Ubuntu 20.04, but not 4.0.9/Ubuntu 18.04). In some cases
LibTIFF's interpretation of the file is different when reading in RGBA mode, leading to
an out-of-bounds write in ``TiffDecode.c``. This potentially affects Pillow versions
from 6.0.0 to 8.0.1, depending on the version of LibTIFF. This was reported through
`Tidelift`_.
* :cve:`CVE-2020-35655` Fix for SGI Decode buffer overrun
4 byte read overflow in SGIRleDecode.c, where the code was not correctly checking the
4 byte read overflow in ``SgiRleDecode.c``, where the code was not correctly checking the
offsets and length tables. Independently reported through `Tidelift`_ and Google's
`OSS-Fuzz`_. This vulnerability covers Pillow versions 4.3.0->8.0.1.
@ -75,7 +76,7 @@ Other Changes
Makefile
^^^^^^^^
The 'co' target has been removed.
The ``co`` target has been removed.
PyPy wheels
^^^^^^^^^^^

View File

@ -0,0 +1,27 @@
8.1.1
-----
Security
========
:cve:`CVE-2021-25289`: The previous fix for :cve:`CVE-2020-35654` was insufficient
due to incorrect error checking in ``TiffDecode.c``.
:cve:`CVE-2021-25290`: In ``TiffDecode.c``, there is a negative-offset ``memcpy``
with an invalid size.
:cve:`CVE-2021-25291`: In ``TiffDecode.c``, invalid tile boundaries could lead to
an out-of-bounds read in ``TIFFReadRGBATile``.
:cve:`CVE-2021-25292`: The PDF parser has a catastrophic backtracking regex
that could be used as a DOS attack.
:cve:`CVE-2021-25293`: There is an out-of-bounds read in ``SgiRleDecode.c``,
since Pillow 4.3.0.
Other Changes
=============
A crash with the feature flags for libimagequant, libjpeg-turbo, WebP and XCB on
unreleased Python 3.10 has been fixed (:issue:`5193`).

View File

@ -0,0 +1,12 @@
8.1.2
-----
Security
========
There is an exhaustion of memory DOS in the BLP (:cve:`CVE-2021-27921`),
ICNS (:cve:`CVE-2021-27922`) and ICO (:cve:`CVE-2021-27923`) container formats
where Pillow did not properly check the reported size of the contained image.
These images could cause arbitrarily large memory allocations. This was reported
by Jiayi Lin, Luke Shaffer, Xinran Xie, and Akshay Ajayan of
`Arizona State University <https://www.asu.edu/>`_.

View File

@ -14,6 +14,8 @@ expected to be backported to earlier versions.
.. toctree::
:maxdepth: 2
8.1.2
8.1.1
8.1.0
8.0.1
8.0.0

View File

@ -353,6 +353,7 @@ class BLP1Decoder(_BLPBaseDecoder):
data = jpeg_header + data
data = BytesIO(data)
image = JpegImageFile(data)
Image._decompression_bomb_check(image.size)
self.tile = image.tile # :/
self.fd = image.fp
self.mode = image.mode

View File

@ -105,6 +105,7 @@ def read_png_or_jpeg2000(fobj, start_length, size):
if sig[:8] == b"\x89PNG\x0d\x0a\x1a\x0a":
fobj.seek(start)
im = PngImagePlugin.PngImageFile(fobj)
Image._decompression_bomb_check(im.size)
return {"RGBA": im}
elif (
sig[:4] == b"\xff\x4f\xff\x51"
@ -121,6 +122,7 @@ def read_png_or_jpeg2000(fobj, start_length, size):
jp2kstream = fobj.read(length)
f = io.BytesIO(jp2kstream)
im = Jpeg2KImagePlugin.Jpeg2KImageFile(f)
Image._decompression_bomb_check(im.size)
if im.mode != "RGBA":
im = im.convert("RGBA")
return {"RGBA": im}

View File

@ -178,6 +178,7 @@ class IcoFile:
if data[:8] == PngImagePlugin._MAGIC:
# png frame
im = PngImagePlugin.PngImageFile(self.buf)
Image._decompression_bomb_check(im.size)
else:
# XOR + AND mask bmp frame
im = BmpImagePlugin.DibImageFile(self.buf)

View File

@ -580,8 +580,9 @@ class PdfParser:
whitespace_or_hex = br"[\000\011\012\014\015\0400-9a-fA-F]"
whitespace_optional = whitespace + b"*"
whitespace_mandatory = whitespace + b"+"
whitespace_optional_no_nl = br"[\000\011\014\015\040]*" # no "\012" aka "\n"
newline_only = br"[\r\n]+"
newline = whitespace_optional + newline_only + whitespace_optional
newline = whitespace_optional_no_nl + newline_only + whitespace_optional_no_nl
re_trailer_end = re.compile(
whitespace_mandatory
+ br"trailer"

View File

@ -1,2 +1,2 @@
# Master version for Pillow
__version__ = "8.1.0"
__version__ = "8.1.2"

View File

@ -4172,26 +4172,33 @@ setup_module(PyObject* m) {
}
#endif
PyObject *have_libjpegturbo;
#ifdef LIBJPEG_TURBO_VERSION
PyModule_AddObject(m, "HAVE_LIBJPEGTURBO", Py_True);
#define tostr1(a) #a
#define tostr(a) tostr1(a)
PyDict_SetItemString(d, "libjpeg_turbo_version", PyUnicode_FromString(tostr(LIBJPEG_TURBO_VERSION)));
#undef tostr
#undef tostr1
have_libjpegturbo = Py_True;
#define tostr1(a) #a
#define tostr(a) tostr1(a)
PyDict_SetItemString(
d, "libjpeg_turbo_version", PyUnicode_FromString(tostr(LIBJPEG_TURBO_VERSION)));
#undef tostr
#undef tostr1
#else
PyModule_AddObject(m, "HAVE_LIBJPEGTURBO", Py_False);
have_libjpegturbo = Py_False;
#endif
Py_INCREF(have_libjpegturbo);
PyModule_AddObject(m, "HAVE_LIBJPEGTURBO", have_libjpegturbo);
PyObject *have_libimagequant;
#ifdef HAVE_LIBIMAGEQUANT
PyModule_AddObject(m, "HAVE_LIBIMAGEQUANT", Py_True);
have_libimagequant = Py_True;
{
extern const char* ImagingImageQuantVersion(void);
PyDict_SetItemString(d, "imagequant_version", PyUnicode_FromString(ImagingImageQuantVersion()));
}
#else
PyModule_AddObject(m, "HAVE_LIBIMAGEQUANT", Py_False);
have_libimagequant = Py_False;
#endif
Py_INCREF(have_libimagequant);
PyModule_AddObject(m, "HAVE_LIBIMAGEQUANT", have_libimagequant);
#ifdef HAVE_LIBZ
/* zip encoding strategies */
@ -4222,11 +4229,14 @@ setup_module(PyObject* m) {
}
#endif
PyObject *have_xcb;
#ifdef HAVE_XCB
PyModule_AddObject(m, "HAVE_XCB", Py_True);
have_xcb = Py_True;
#else
PyModule_AddObject(m, "HAVE_XCB", Py_False);
have_xcb = Py_False;
#endif
Py_INCREF(have_xcb);
PyModule_AddObject(m, "HAVE_XCB", have_xcb);
PyDict_SetItemString(d, "PILLOW_VERSION", PyUnicode_FromString(version));

View File

@ -861,19 +861,25 @@ static PyMethodDef webpMethods[] =
};
void addMuxFlagToModule(PyObject* m) {
PyObject *have_webpmux;
#ifdef HAVE_WEBPMUX
PyModule_AddObject(m, "HAVE_WEBPMUX", Py_True);
have_webpmux = Py_True;
#else
PyModule_AddObject(m, "HAVE_WEBPMUX", Py_False);
have_webpmux = Py_False;
#endif
Py_INCREF(have_webpmux);
PyModule_AddObject(m, "HAVE_WEBPMUX", have_webpmux);
}
void addAnimFlagToModule(PyObject* m) {
void addAnimFlagToModule(PyObject *m) {
PyObject *have_webpanim;
#ifdef HAVE_WEBPANIM
PyModule_AddObject(m, "HAVE_WEBPANIM", Py_True);
have_webpanim = Py_True;
#else
PyModule_AddObject(m, "HAVE_WEBPANIM", Py_False);
have_webpanim = Py_False;
#endif
Py_INCREF(have_webpanim);
PyModule_AddObject(m, "HAVE_WEBPANIM", have_webpanim);
}
void addTransparencyFlagToModule(PyObject* m) {

View File

@ -25,13 +25,59 @@ static void read4B(UINT32* dest, UINT8* buf)
*dest = (UINT32)((buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]);
}
static int expandrow(UINT8* dest, UINT8* src, int n, int z, int xsize)
/*
SgiRleDecoding is done in a single channel row oriented set of RLE chunks.
* The file is arranged as
- SGI Header
- Rle Offset Table
- Rle Length Table
- Scanline Data
* Each RLE atom is c->bpc bytes wide (1 or 2)
* Each RLE Chunk is [specifier atom] [ 1 or n data atoms ]
* Copy Atoms are a byte with the high bit set, and the low 7 are
the number of bytes to copy from the source to the
destination. e.g.
CBBBBBBBB or 0CHLHLHLHLHLHL (B=byte, H/L = Hi low bytes)
* Run atoms do not have the high bit set, and the low 7 bits are
the number of copies of the next atom to copy to the
destination. e.g.:
RB -> BBBBB or RHL -> HLHLHLHLHL
The upshot of this is, there is no way to determine the required
length of the input buffer from reloffset and rlelength without
going through the data at that scan line.
Furthermore, there's no requirement that individual scan lines
pointed to from the rleoffset table are in any sort of order or
used only once, or even disjoint. There's also no requirement that
all of the data in the scan line area of the image file be used
*/
static int expandrow(UINT8* dest, UINT8* src, int n, int z, int xsize, UINT8* end_of_buffer)
{
/*
* n here is the number of rlechunks
* z is the number of channels, for calculating the interleave
* offset to go to RGBA style pixels
* xsize is the row width
* end_of_buffer is the address of the end of the input buffer
*/
UINT8 pixel, count;
int x = 0;
for (;n > 0; n--)
{
if (src > end_of_buffer) {
return -1;
}
pixel = *src++;
if (n == 1 && pixel != 0) {
return n;
@ -45,6 +91,9 @@ static int expandrow(UINT8* dest, UINT8* src, int n, int z, int xsize)
}
x += count;
if (pixel & RLE_COPY_FLAG) {
if (src + count > end_of_buffer) {
return -1;
}
while(count--) {
*dest = *src++;
dest += z;
@ -52,6 +101,9 @@ static int expandrow(UINT8* dest, UINT8* src, int n, int z, int xsize)
}
else {
if (src > end_of_buffer) {
return -1;
}
pixel = *src++;
while (count--) {
*dest = pixel;
@ -63,14 +115,16 @@ static int expandrow(UINT8* dest, UINT8* src, int n, int z, int xsize)
return 0;
}
static int expandrow2(UINT8* dest, const UINT8* src, int n, int z, int xsize)
static int expandrow2(UINT8* dest, const UINT8* src, int n, int z, int xsize, UINT8* end_of_buffer)
{
UINT8 pixel, count;
int x = 0;
for (;n > 0; n--)
{
if (src + 1 > end_of_buffer) {
return -1;
}
pixel = src[1];
src+=2;
if (n == 1 && pixel != 0) {
@ -85,6 +139,9 @@ static int expandrow2(UINT8* dest, const UINT8* src, int n, int z, int xsize)
}
x += count;
if (pixel & RLE_COPY_FLAG) {
if (src + 2 * count > end_of_buffer) {
return -1;
}
while(count--) {
memcpy(dest, src, 2);
src += 2;
@ -92,6 +149,9 @@ static int expandrow2(UINT8* dest, const UINT8* src, int n, int z, int xsize)
}
}
else {
if (src + 2 > end_of_buffer) {
return -1;
}
while (count--) {
memcpy(dest, src, 2);
dest += z * 2;
@ -141,7 +201,10 @@ ImagingSgiRleDecode(Imaging im, ImagingCodecState state,
return -1;
}
_imaging_seek_pyFd(state->fd, SGI_HEADER_SIZE, SEEK_SET);
_imaging_read_pyFd(state->fd, (char*)ptr, c->bufsize);
if (_imaging_read_pyFd(state->fd, (char*)ptr, c->bufsize) != c->bufsize) {
state->errcode = IMAGING_CODEC_UNKNOWN;
return -1;
}
/* decoder initialization */
@ -175,8 +238,6 @@ ImagingSgiRleDecode(Imaging im, ImagingCodecState state,
read4B(&c->lengthtab[c->tabindex], &ptr[c->bufindex]);
}
state->count += c->tablen * sizeof(UINT32) * 2;
/* read compressed rows */
for (c->rowno = 0; c->rowno < im->ysize; c->rowno++, state->y += state->ystep)
{
@ -184,19 +245,21 @@ ImagingSgiRleDecode(Imaging im, ImagingCodecState state,
{
c->rleoffset = c->starttab[c->rowno + c->channo * im->ysize];
c->rlelength = c->lengthtab[c->rowno + c->channo * im->ysize];
c->rleoffset -= SGI_HEADER_SIZE;
if (c->rleoffset + c->rlelength > c->bufsize) {
// Check for underflow of rleoffset-SGI_HEADER_SIZE
if (c->rleoffset < SGI_HEADER_SIZE) {
state->errcode = IMAGING_CODEC_OVERRUN;
goto sgi_finish_decode;
}
c->rleoffset -= SGI_HEADER_SIZE;
/* row decompression */
if (c->bpc ==1) {
status = expandrow(&state->buffer[c->channo], &ptr[c->rleoffset], c->rlelength, im->bands, im->xsize);
status = expandrow(&state->buffer[c->channo], &ptr[c->rleoffset], c->rlelength, im->bands, im->xsize, &ptr[c->bufsize-1]);
}
else {
status = expandrow2(&state->buffer[c->channo * 2], &ptr[c->rleoffset], c->rlelength, im->bands, im->xsize);
status = expandrow2(&state->buffer[c->channo * 2], &ptr[c->rleoffset], c->rlelength, im->bands, im->xsize, &ptr[c->bufsize-1]);
}
if (status == -1) {
state->errcode = IMAGING_CODEC_OVERRUN;
@ -205,7 +268,6 @@ ImagingSgiRleDecode(Imaging im, ImagingCodecState state,
goto sgi_finish_decode;
}
state->count += c->rlelength;
}
/* store decompressed data in image */
@ -213,8 +275,6 @@ ImagingSgiRleDecode(Imaging im, ImagingCodecState state,
}
c->bufsize++;
sgi_finish_decode: ;
free(c->starttab);
@ -224,5 +284,5 @@ sgi_finish_decode: ;
state->errcode=err;
return -1;
}
return state->count - c->bufsize;
return 0;
}

View File

@ -47,6 +47,10 @@ tsize_t _tiffReadProc(thandle_t hdata, tdata_t buf, tsize_t size) {
TRACE(("_tiffReadProc: %d \n", (int)size));
dump_state(state);
if (state->loc > state->eof) {
TIFFError("_tiffReadProc", "Invalid Read at loc %d, eof: %d", state->loc, state->eof);
return 0;
}
to_read = min(size, min(state->size, (tsize_t)state->eof) - (tsize_t)state->loc);
TRACE(("to_read: %d\n", (int)to_read));
@ -250,7 +254,7 @@ int _decodeStripYCbCr(Imaging im, ImagingCodecState state, TIFF *tiff) {
img.row_offset = state->y;
rows_to_read = min(rows_per_strip, img.height - state->y);
if (TIFFRGBAImageGet(&img, (UINT32 *)state->buffer, img.width, rows_to_read) == -1) {
if (!TIFFRGBAImageGet(&img, (UINT32 *)state->buffer, img.width, rows_to_read)) {
TRACE(("Decode Error, y: %d\n", state->y ));
state->errcode = IMAGING_CODEC_BROKEN;
goto decodeycbcr_err;
@ -475,6 +479,15 @@ int ImagingLibTiffDecode(Imaging im, ImagingCodecState state, UINT8* buffer, Py_
for (y = state->yoff; y < state->ysize; y += tile_length) {
for (x = state->xoff; x < state->xsize; x += tile_width) {
/* Sanity Check. Apparently in some cases, the TiffReadRGBA* functions
have a different view of the size of the tiff than we're getting from
other functions. So, we need to check here.
*/
if (!TIFFCheckTile(tiff, x, y, 0, 0)) {
TRACE(("Check Tile Error, Tile at %dx%d\n", x, y));
state->errcode = IMAGING_CODEC_BROKEN;
goto decode_err;
}
if (isYCbCr) {
/* To avoid dealing with YCbCr subsampling, let libtiff handle it */
if (!TIFFReadRGBATile(tiff, x, y, (UINT32 *)state->buffer)) {