Compare commits
30 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a45c8583ff | ||
|
|
83efad4875 | ||
|
|
4820f79e01 | ||
|
|
4e2def2539 | ||
|
|
a79b65c47c | ||
|
|
93b22b846e | ||
|
|
a09acd0dec | ||
|
|
774e53bb13 | ||
|
|
8892aecfbf | ||
|
|
46c35f06b1 | ||
|
|
f269b49cff | ||
|
|
cc04ee7b5c | ||
|
|
48908c94e8 | ||
|
|
c8d620416f | ||
|
|
bde3e9cfc9 | ||
|
|
c77171fea2 | ||
|
|
9fa34ecc2e | ||
|
|
738bbd2641 | ||
|
|
71ffb52320 | ||
|
|
fe38d93250 | ||
|
|
a9126faa7a | ||
|
|
89d6c84ba0 | ||
|
|
fe8ba74f93 | ||
|
|
7a0a2e966c | ||
|
|
6e0f07bbe3 | ||
|
|
39d26d3f90 | ||
|
|
ee9e21aff1 | ||
|
|
efcfb91b71 | ||
|
|
f97c4ddb0a | ||
|
|
b78edcc9e4 |
@ -18,6 +18,8 @@ environment:
|
||||
PIP_DIR: bin
|
||||
VENV: YES
|
||||
- PYTHON: C:/Python27-x64
|
||||
- PYTHON: C:/Python38
|
||||
- PYTHON: C:/Python38-x64
|
||||
- PYTHON: C:/Python37
|
||||
- PYTHON: C:/Python27
|
||||
- PYTHON: C:/Python37-x64
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
parameters:
|
||||
docker: '' # defaults for any parameters that aren't specified
|
||||
dockerTag: 'master'
|
||||
dockerTag: '6.2.x'
|
||||
name: ''
|
||||
vmImage: 'Ubuntu-16.04'
|
||||
|
||||
|
||||
30
.travis.yml
30
.travis.yml
@ -20,6 +20,9 @@ matrix:
|
||||
name: "PyPy2 Xenial"
|
||||
- python: "pypy3"
|
||||
name: "PyPy3 Xenial"
|
||||
- python: "3.8"
|
||||
name: "3.8 Xenial"
|
||||
services: xvfb
|
||||
- python: '3.7'
|
||||
name: "3.7 Xenial"
|
||||
- python: '2.7'
|
||||
@ -33,20 +36,19 @@ matrix:
|
||||
- python: '3.5'
|
||||
name: "3.5 Xenial PYTHONOPTIMIZE=2"
|
||||
env: PYTHONOPTIMIZE=2
|
||||
- python: "3.8-dev"
|
||||
name: "3.8-dev Xenial"
|
||||
- env: DOCKER="alpine" DOCKER_TAG="master"
|
||||
- env: DOCKER="arch" DOCKER_TAG="master" # contains PyQt5
|
||||
- env: DOCKER="ubuntu-16.04-xenial-amd64" DOCKER_TAG="master"
|
||||
- env: DOCKER="ubuntu-18.04-bionic-amd64" DOCKER_TAG="master"
|
||||
- env: DOCKER="debian-9-stretch-x86" DOCKER_TAG="master"
|
||||
- env: DOCKER="debian-10-buster-x86" DOCKER_TAG="master"
|
||||
- env: DOCKER="centos-6-amd64" DOCKER_TAG="master"
|
||||
- env: DOCKER="centos-7-amd64" DOCKER_TAG="master"
|
||||
- env: DOCKER="amazon-1-amd64" DOCKER_TAG="master"
|
||||
- env: DOCKER="amazon-2-amd64" DOCKER_TAG="master"
|
||||
- env: DOCKER="fedora-29-amd64" DOCKER_TAG="master"
|
||||
- env: DOCKER="fedora-30-amd64" DOCKER_TAG="master"
|
||||
- env: DOCKER="alpine" DOCKER_TAG="6.2.x"
|
||||
- env: DOCKER="arch" DOCKER_TAG="6.2.x" # contains PyQt5
|
||||
- env: DOCKER="ubuntu-16.04-xenial-amd64" DOCKER_TAG="6.2.x"
|
||||
- env: DOCKER="ubuntu-18.04-bionic-amd64" DOCKER_TAG="6.2.x"
|
||||
- env: DOCKER="debian-9-stretch-x86" DOCKER_TAG="6.2.x"
|
||||
- env: DOCKER="debian-10-buster-x86" DOCKER_TAG="6.2.x"
|
||||
- env: DOCKER="centos-6-amd64" DOCKER_TAG="6.2.x"
|
||||
- env: DOCKER="centos-7-amd64" DOCKER_TAG="6.2.x"
|
||||
- env: DOCKER="centos-8-amd64" DOCKER_TAG="master"
|
||||
- env: DOCKER="amazon-1-amd64" DOCKER_TAG="6.2.x"
|
||||
- env: DOCKER="amazon-2-amd64" DOCKER_TAG="6.2.x"
|
||||
- env: DOCKER="fedora-30-amd64" DOCKER_TAG="6.2.x"
|
||||
- env: DOCKER="fedora-31-amd64" DOCKER_TAG="6.2.x"
|
||||
|
||||
services:
|
||||
- docker
|
||||
|
||||
26
CHANGES.rst
26
CHANGES.rst
@ -2,11 +2,35 @@
|
||||
Changelog (Pillow)
|
||||
==================
|
||||
|
||||
6.2.0 (2019-10-01)
|
||||
6.2.2 (2020-01-02)
|
||||
------------------
|
||||
|
||||
- This is the last Pillow release to support Python 2.7 #3642
|
||||
|
||||
- Overflow checks for realloc for tiff decoding. CVE TBD
|
||||
[wiredfool, radarhere]
|
||||
|
||||
- Catch SGI buffer overrun. CVE TBD
|
||||
[radarhere]
|
||||
|
||||
- Catch PCX P mode buffer overrun. CVE TBD
|
||||
[radarhere]
|
||||
|
||||
- Catch FLI buffer overrun. CVE TBD
|
||||
[radarhere]
|
||||
|
||||
- Raise an error for an invalid number of bands in FPX image. CVE-2019-19911
|
||||
[wiredfool, radarhere]
|
||||
|
||||
6.2.1 (2019-10-21)
|
||||
------------------
|
||||
|
||||
- Add support for Python 3.8 #4141
|
||||
[hugovk]
|
||||
|
||||
6.2.0 (2019-10-01)
|
||||
------------------
|
||||
|
||||
- Catch buffer overruns #4104
|
||||
[radarhere]
|
||||
|
||||
|
||||
2
LICENSE
2
LICENSE
@ -5,7 +5,7 @@ The Python Imaging Library (PIL) is
|
||||
|
||||
Pillow is the friendly PIL fork. It is
|
||||
|
||||
Copyright © 2010-2019 by Alex Clark and contributors
|
||||
Copyright © 2010-2020 by Alex Clark and contributors
|
||||
|
||||
Like PIL, Pillow is licensed under the open source PIL Software License:
|
||||
|
||||
|
||||
BIN
Tests/images/fli_overrun2.bin
Normal file
BIN
Tests/images/fli_overrun2.bin
Normal file
Binary file not shown.
BIN
Tests/images/input_bw_five_bands.fpx
Normal file
BIN
Tests/images/input_bw_five_bands.fpx
Normal file
Binary file not shown.
BIN
Tests/images/pcx_overrun2.bin
Normal file
BIN
Tests/images/pcx_overrun2.bin
Normal file
Binary file not shown.
BIN
Tests/images/sgi_overrun_expandrow.bin
Normal file
BIN
Tests/images/sgi_overrun_expandrow.bin
Normal file
Binary file not shown.
BIN
Tests/images/sgi_overrun_expandrow2.bin
Normal file
BIN
Tests/images/sgi_overrun_expandrow2.bin
Normal file
Binary file not shown.
BIN
Tests/images/tiff_overflow_rows_per_strip.tif
Normal file
BIN
Tests/images/tiff_overflow_rows_per_strip.tif
Normal file
Binary file not shown.
@ -1,3 +1,5 @@
|
||||
from PIL import Image
|
||||
|
||||
from .helper import PillowTestCase, unittest
|
||||
|
||||
try:
|
||||
@ -18,3 +20,7 @@ class TestFileFpx(PillowTestCase):
|
||||
# Test a valid OLE file, but not an FPX file
|
||||
ole_file = "Tests/images/test-ole-file.doc"
|
||||
self.assertRaises(SyntaxError, FpxImagePlugin.FpxImageFile, ole_file)
|
||||
|
||||
def test_fpx_invalid_number_of_bands(self):
|
||||
with self.assertRaisesRegex(IOError, "Invalid number of bands"):
|
||||
Image.open("Tests/images/input_bw_five_bands.fpx")
|
||||
|
||||
@ -870,3 +870,13 @@ class TestFileLibTiff(LibTiffTestCase):
|
||||
out.seek(0)
|
||||
with Image.open(out) as im:
|
||||
im.load()
|
||||
|
||||
def test_realloc_overflow(self):
|
||||
TiffImagePlugin.READ_LIBTIFF = True
|
||||
with Image.open("Tests/images/tiff_overflow_rows_per_strip.tif") as im:
|
||||
with self.assertRaises(IOError) as e:
|
||||
im.load()
|
||||
|
||||
# Assert that the error code is IMAGING_CODEC_MEMORY
|
||||
self.assertEqual(str(e.exception), "-9")
|
||||
TiffImagePlugin.READ_LIBTIFF = False
|
||||
|
||||
@ -590,7 +590,14 @@ class TestImage(PillowTestCase):
|
||||
self.assertFalse(fp.closed)
|
||||
|
||||
def test_overrun(self):
|
||||
for file in ["fli_overrun.bin", "sgi_overrun.bin", "pcx_overrun.bin"]:
|
||||
for file in [
|
||||
"fli_overrun.bin",
|
||||
"sgi_overrun.bin",
|
||||
"sgi_overrun_expandrow.bin",
|
||||
"sgi_overrun_expandrow2.bin",
|
||||
"pcx_overrun.bin",
|
||||
"pcx_overrun2.bin",
|
||||
]:
|
||||
im = Image.open(os.path.join("Tests/images", file))
|
||||
try:
|
||||
im.load()
|
||||
@ -598,6 +605,13 @@ class TestImage(PillowTestCase):
|
||||
except IOError as e:
|
||||
self.assertEqual(str(e), "buffer overrun when reading image file")
|
||||
|
||||
with Image.open("Tests/images/fli_overrun2.bin") as im:
|
||||
try:
|
||||
im.seek(1)
|
||||
self.assertFail()
|
||||
except IOError as e:
|
||||
self.assertEqual(str(e), "buffer overrun when reading image file")
|
||||
|
||||
|
||||
class MockEncoder(object):
|
||||
pass
|
||||
|
||||
@ -51,6 +51,11 @@ jobs:
|
||||
docker: 'centos-7-amd64'
|
||||
name: 'centos_7_amd64'
|
||||
|
||||
- template: .azure-pipelines/jobs/test-docker.yml
|
||||
parameters:
|
||||
docker: 'centos-8-amd64'
|
||||
name: 'centos_8_amd64'
|
||||
|
||||
- template: .azure-pipelines/jobs/test-docker.yml
|
||||
parameters:
|
||||
docker: 'amazon-1-amd64'
|
||||
@ -63,10 +68,10 @@ jobs:
|
||||
|
||||
- template: .azure-pipelines/jobs/test-docker.yml
|
||||
parameters:
|
||||
docker: 'fedora-29-amd64'
|
||||
name: 'fedora_29_amd64'
|
||||
docker: 'fedora-30-amd64'
|
||||
name: 'fedora_30_amd64'
|
||||
|
||||
- template: .azure-pipelines/jobs/test-docker.yml
|
||||
parameters:
|
||||
docker: 'fedora-30-amd64'
|
||||
name: 'fedora_30_amd64'
|
||||
docker: 'fedora-31-amd64'
|
||||
name: 'fedora_31_amd64'
|
||||
|
||||
@ -5,7 +5,7 @@ The Python Imaging Library (PIL) is
|
||||
|
||||
Pillow is the friendly PIL fork. It is
|
||||
|
||||
Copyright © 2010-2019 by Alex Clark and contributors
|
||||
Copyright © 2010-2020 by Alex Clark and contributors
|
||||
|
||||
Like PIL, Pillow is licensed under the open source PIL
|
||||
Software License:
|
||||
|
||||
@ -43,7 +43,7 @@ master_doc = "index"
|
||||
|
||||
# General information about the project.
|
||||
project = u"Pillow (PIL Fork)"
|
||||
copyright = u"1995-2011 Fredrik Lundh, 2010-2019 Alex Clark and Contributors"
|
||||
copyright = u"1995-2011 Fredrik Lundh, 2010-2020 Alex Clark and Contributors"
|
||||
author = u"Fredrik Lundh, Alex Clark and Contributors"
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
|
||||
@ -15,23 +15,25 @@ Notes
|
||||
|
||||
.. note:: Pillow is supported on the following Python versions
|
||||
|
||||
+---------------------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
|**Python** |**2.4**|**2.5**|**2.6**|**2.7**|**3.2**|**3.3**|**3.4**|**3.5**|**3.6**|**3.7**|
|
||||
+---------------------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
|Pillow < 2.0.0 | Yes | Yes | Yes | Yes | | | | | | |
|
||||
+---------------------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
|Pillow 2.x - 3.x | | | Yes | Yes | Yes | Yes | Yes | Yes | | |
|
||||
+---------------------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
|Pillow 4.x | | | | Yes | | Yes | Yes | Yes | Yes | |
|
||||
+---------------------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
|Pillow 5.0.x - 5.1.x | | | | Yes | | | Yes | Yes | Yes | |
|
||||
+---------------------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
|Pillow 5.2.x - 5.4.x | | | | Yes | | | Yes | Yes | Yes | Yes |
|
||||
+---------------------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
|Pillow 6.x | | | | Yes | | | | Yes | Yes | Yes |
|
||||
+---------------------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
|Pillow >= 7.0.0 | | | | | | | | Yes | Yes | Yes |
|
||||
+---------------------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
+-------------------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
|**Python** |**2.4**|**2.5**|**2.6**|**2.7**|**3.2**|**3.3**|**3.4**|**3.5**|**3.6**|**3.7**|**3.8**|
|
||||
+-------------------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
|Pillow < 2 | Yes | Yes | Yes | Yes | | | | | | | |
|
||||
+-------------------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
|Pillow 2 - 3 | | | Yes | Yes | Yes | Yes | Yes | Yes | | | |
|
||||
+-------------------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
|Pillow 4 | | | | Yes | | Yes | Yes | Yes | Yes | | |
|
||||
+-------------------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
|Pillow 5.0 - 5.1 | | | | Yes | | | Yes | Yes | Yes | | |
|
||||
+-------------------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
|Pillow 5.2 - 5.4 | | | | Yes | | | Yes | Yes | Yes | Yes | |
|
||||
+-------------------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
|Pillow 6.0 - 6.2.0 | | | | Yes | | | | Yes | Yes | Yes | |
|
||||
+-------------------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
|Pillow 6.2.1 | | | | Yes | | | | Yes | Yes | Yes | Yes |
|
||||
+-------------------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
|Pillow >= 7 | | | | | | | | Yes | Yes | Yes | Yes |
|
||||
+-------------------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
|
||||
Basic Installation
|
||||
------------------
|
||||
@ -395,20 +397,22 @@ These platforms are built and tested for every change.
|
||||
+----------------------------------+-------------------------------+-----------------------+
|
||||
| CentOS 7 | 2.7, 3.6 |x86-64 |
|
||||
+----------------------------------+-------------------------------+-----------------------+
|
||||
| CentOS 8 | 2.7, 3.6 |x86-64 |
|
||||
+----------------------------------+-------------------------------+-----------------------+
|
||||
| Debian 9 Stretch | 2.7, 3.5 |x86 |
|
||||
+----------------------------------+-------------------------------+-----------------------+
|
||||
| Debian 10 Buster | 2.7, 3.7 |x86 |
|
||||
+----------------------------------+-------------------------------+-----------------------+
|
||||
| Fedora 29 | 2.7, 3.7 |x86-64 |
|
||||
+----------------------------------+-------------------------------+-----------------------+
|
||||
| Fedora 30 | 2.7, 3.7 |x86-64 |
|
||||
+----------------------------------+-------------------------------+-----------------------+
|
||||
| macOS 10.13 High Sierra* | 2.7, 3.5, 3.6, 3.7 |x86-64 |
|
||||
| Fedora 31 | 2.7, 3.7 |x86-64 |
|
||||
+----------------------------------+-------------------------------+-----------------------+
|
||||
| Ubuntu Linux 16.04 LTS | 2.7, 3.5, 3.6, 3.7, |x86-64 |
|
||||
| macOS 10.13 High Sierra* | 2.7, 3.5, 3.6, 3.7, 3.8 |x86-64 |
|
||||
+----------------------------------+-------------------------------+-----------------------+
|
||||
| Ubuntu Linux 16.04 LTS | 2.7, 3.5, 3.6, 3.7, 3.8, |x86-64 |
|
||||
| | PyPy, PyPy3 | |
|
||||
+----------------------------------+-------------------------------+-----------------------+
|
||||
| Windows Server 2012 R2 | 2.7, 3.5, 3.6, 3.7 |x86, x86-64 |
|
||||
| Windows Server 2012 R2 | 2.7, 3.5, 3.6, 3.7, 3.8 |x86, x86-64 |
|
||||
| +-------------------------------+-----------------------+
|
||||
| | PyPy, 3.7/MinGW |x86 |
|
||||
+----------------------------------+-------------------------------+-----------------------+
|
||||
|
||||
@ -62,14 +62,6 @@ shared instance of ``Image.Exif``.
|
||||
Deprecations
|
||||
^^^^^^^^^^^^
|
||||
|
||||
Python 2.7
|
||||
~~~~~~~~~~
|
||||
|
||||
Python 2.7 reaches end-of-life on 2020-01-01.
|
||||
|
||||
Pillow 7.0.0 will be released on 2020-01-01 and will drop support for Python
|
||||
2.7, making Pillow 6.2.x the last release series to support Python 2.
|
||||
|
||||
Image.frombuffer
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
@ -77,6 +69,27 @@ There has been a longstanding warning that the defaults of ``Image.frombuffer``
|
||||
may change in the future for the "raw" decoder. The change will now take place
|
||||
in Pillow 7.0.
|
||||
|
||||
Security
|
||||
========
|
||||
|
||||
This release catches several buffer overruns, as well as addressing
|
||||
CVE-2019-16865. The CVE is regarding DOS problems, such as consuming large
|
||||
amounts of memory, or taking a large amount of time to process an image.
|
||||
|
||||
In RawDecode.c, an error is now thrown if skip is calculated to be less than
|
||||
zero. It is intended to skip padding between lines, not to go backwards.
|
||||
|
||||
In PsdImagePlugin, if the combined sizes of the individual parts is larger than
|
||||
the declared size of the extra data field, then it looked for the next layer by
|
||||
seeking backwards. This is now corrected by seeking to (the start of the layer
|
||||
+ the size of the extra data field) instead of (the read parts of the layer +
|
||||
the rest of the layer).
|
||||
|
||||
Decompression bomb checks have been added to GIF and ICO formats.
|
||||
|
||||
An error is now raised if a TIFF dimension is a string, rather than trying to
|
||||
perform operations on it.
|
||||
|
||||
Other Changes
|
||||
=============
|
||||
|
||||
|
||||
26
docs/releasenotes/6.2.1.rst
Normal file
26
docs/releasenotes/6.2.1.rst
Normal file
@ -0,0 +1,26 @@
|
||||
6.2.1
|
||||
-----
|
||||
|
||||
API Changes
|
||||
===========
|
||||
|
||||
Deprecations
|
||||
^^^^^^^^^^^^
|
||||
|
||||
Python 2.7
|
||||
~~~~~~~~~~
|
||||
|
||||
Python 2.7 reaches end-of-life on 2020-01-01.
|
||||
|
||||
Pillow 7.0.0 will be released on 2020-01-01 and will drop support for Python
|
||||
2.7, making Pillow 6.2.x the last release series to support Python 2.
|
||||
|
||||
Other Changes
|
||||
=============
|
||||
|
||||
|
||||
|
||||
Support added for Python 3.8
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Pillow 6.2.1 supports Python 3.8.
|
||||
18
docs/releasenotes/6.2.2.rst
Normal file
18
docs/releasenotes/6.2.2.rst
Normal file
@ -0,0 +1,18 @@
|
||||
6.2.2
|
||||
-----
|
||||
|
||||
Security
|
||||
========
|
||||
|
||||
This release addresses several security problems {CVEs TBD), as well as addressing
|
||||
CVE-2019-19911.
|
||||
|
||||
CVE-2019-19911 is regarding FPX images. If an image reports that it has a large number
|
||||
of bands, a large amount of resources will be used when trying to process the
|
||||
image. This is fixed by limiting the number of bands to those usable by Pillow.
|
||||
|
||||
Buffer overruns were found when processing an SGI, PCX or FLI image. Checks
|
||||
have been added to prevent this.
|
||||
|
||||
Overflow checks have been added when calculating the size of a memory block to
|
||||
be reallocated in the processing of a TIFF image.
|
||||
@ -6,6 +6,8 @@ Release Notes
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
6.2.2
|
||||
6.2.1
|
||||
6.2.0
|
||||
6.1.0
|
||||
6.0.0
|
||||
|
||||
3
setup.py
3
setup.py
@ -24,7 +24,7 @@ from setuptools import Extension, setup
|
||||
# comment this out to disable multi threaded builds.
|
||||
import mp_compile
|
||||
|
||||
if sys.platform == "win32" and sys.version_info >= (3, 8):
|
||||
if sys.platform == "win32" and sys.version_info >= (3, 9):
|
||||
warnings.warn(
|
||||
"Pillow does not yet support Python {}.{} and does not yet provide "
|
||||
"prebuilt Windows binaries. We do not recommend building from "
|
||||
@ -867,6 +867,7 @@ try:
|
||||
"Programming Language :: Python :: 3.5",
|
||||
"Programming Language :: Python :: 3.6",
|
||||
"Programming Language :: Python :: 3.7",
|
||||
"Programming Language :: Python :: 3.8",
|
||||
"Programming Language :: Python :: Implementation :: CPython",
|
||||
"Programming Language :: Python :: Implementation :: PyPy",
|
||||
"Topic :: Multimedia :: Graphics",
|
||||
|
||||
@ -119,7 +119,7 @@ def decode_dxt3(data):
|
||||
bits = struct.unpack_from("<8B", block)
|
||||
color0, color1 = struct.unpack_from("<HH", block, 8)
|
||||
|
||||
code, = struct.unpack_from("<I", block, 12)
|
||||
(code,) = struct.unpack_from("<I", block, 12)
|
||||
|
||||
r0, g0, b0 = unpack_565(color0)
|
||||
r1, g1, b1 = unpack_565(color1)
|
||||
@ -177,7 +177,7 @@ def decode_dxt5(data):
|
||||
|
||||
color0, color1 = struct.unpack_from("<HH", block, 8)
|
||||
|
||||
code, = struct.unpack_from("<I", block, 12)
|
||||
(code,) = struct.unpack_from("<I", block, 12)
|
||||
|
||||
r0, g0, b0 = unpack_565(color0)
|
||||
r1, g1, b1 = unpack_565(color1)
|
||||
@ -255,19 +255,19 @@ class BlpImageFile(ImageFile.ImageFile):
|
||||
self.tile = [(decoder, (0, 0) + self.size, 0, (self.mode, 0, 1))]
|
||||
|
||||
def _read_blp_header(self):
|
||||
self._blp_compression, = struct.unpack("<i", self.fp.read(4))
|
||||
(self._blp_compression,) = struct.unpack("<i", self.fp.read(4))
|
||||
|
||||
self._blp_encoding, = struct.unpack("<b", self.fp.read(1))
|
||||
self._blp_alpha_depth, = struct.unpack("<b", self.fp.read(1))
|
||||
self._blp_alpha_encoding, = struct.unpack("<b", self.fp.read(1))
|
||||
self._blp_mips, = struct.unpack("<b", self.fp.read(1))
|
||||
(self._blp_encoding,) = struct.unpack("<b", self.fp.read(1))
|
||||
(self._blp_alpha_depth,) = struct.unpack("<b", self.fp.read(1))
|
||||
(self._blp_alpha_encoding,) = struct.unpack("<b", self.fp.read(1))
|
||||
(self._blp_mips,) = struct.unpack("<b", self.fp.read(1))
|
||||
|
||||
self._size = struct.unpack("<II", self.fp.read(8))
|
||||
|
||||
if self.magic == b"BLP1":
|
||||
# Only present for BLP1
|
||||
self._blp_encoding, = struct.unpack("<i", self.fp.read(4))
|
||||
self._blp_subtype, = struct.unpack("<i", self.fp.read(4))
|
||||
(self._blp_encoding,) = struct.unpack("<i", self.fp.read(4))
|
||||
(self._blp_subtype,) = struct.unpack("<i", self.fp.read(4))
|
||||
|
||||
self._blp_offsets = struct.unpack("<16I", self.fp.read(16 * 4))
|
||||
self._blp_lengths = struct.unpack("<16I", self.fp.read(16 * 4))
|
||||
@ -297,19 +297,19 @@ class _BLPBaseDecoder(ImageFile.PyDecoder):
|
||||
return ret
|
||||
|
||||
def _read_blp_header(self):
|
||||
self._blp_compression, = struct.unpack("<i", self.fd.read(4))
|
||||
(self._blp_compression,) = struct.unpack("<i", self.fd.read(4))
|
||||
|
||||
self._blp_encoding, = struct.unpack("<b", self.fd.read(1))
|
||||
self._blp_alpha_depth, = struct.unpack("<b", self.fd.read(1))
|
||||
self._blp_alpha_encoding, = struct.unpack("<b", self.fd.read(1))
|
||||
self._blp_mips, = struct.unpack("<b", self.fd.read(1))
|
||||
(self._blp_encoding,) = struct.unpack("<b", self.fd.read(1))
|
||||
(self._blp_alpha_depth,) = struct.unpack("<b", self.fd.read(1))
|
||||
(self._blp_alpha_encoding,) = struct.unpack("<b", self.fd.read(1))
|
||||
(self._blp_mips,) = struct.unpack("<b", self.fd.read(1))
|
||||
|
||||
self.size = struct.unpack("<II", self.fd.read(8))
|
||||
|
||||
if self.magic == b"BLP1":
|
||||
# Only present for BLP1
|
||||
self._blp_encoding, = struct.unpack("<i", self.fd.read(4))
|
||||
self._blp_subtype, = struct.unpack("<i", self.fd.read(4))
|
||||
(self._blp_encoding,) = struct.unpack("<i", self.fd.read(4))
|
||||
(self._blp_subtype,) = struct.unpack("<i", self.fd.read(4))
|
||||
|
||||
self._blp_offsets = struct.unpack("<16I", self.fd.read(16 * 4))
|
||||
self._blp_lengths = struct.unpack("<16I", self.fd.read(16 * 4))
|
||||
@ -327,7 +327,7 @@ class BLP1Decoder(_BLPBaseDecoder):
|
||||
_data = BytesIO(self.fd.read(self._blp_lengths[0]))
|
||||
while True:
|
||||
try:
|
||||
offset, = struct.unpack("<B", _data.read(1))
|
||||
(offset,) = struct.unpack("<B", _data.read(1))
|
||||
except struct.error:
|
||||
break
|
||||
b, g, r, a = palette[offset]
|
||||
@ -346,7 +346,7 @@ class BLP1Decoder(_BLPBaseDecoder):
|
||||
def _decode_jpeg_stream(self):
|
||||
from PIL.JpegImagePlugin import JpegImageFile
|
||||
|
||||
jpeg_header_size, = struct.unpack("<I", self.fd.read(4))
|
||||
(jpeg_header_size,) = struct.unpack("<I", self.fd.read(4))
|
||||
jpeg_header = self.fd.read(jpeg_header_size)
|
||||
self.fd.read(self._blp_offsets[0] - self.fd.tell()) # What IS this?
|
||||
data = self.fd.read(self._blp_lengths[0])
|
||||
@ -372,7 +372,7 @@ class BLP2Decoder(_BLPBaseDecoder):
|
||||
_data = BytesIO(self.fd.read(self._blp_lengths[0]))
|
||||
while True:
|
||||
try:
|
||||
offset, = struct.unpack("<B", _data.read(1))
|
||||
(offset,) = struct.unpack("<B", _data.read(1))
|
||||
except struct.error:
|
||||
break
|
||||
b, g, r, a = palette[offset]
|
||||
|
||||
@ -122,7 +122,7 @@ class DdsImageFile(ImageFile.ImageFile):
|
||||
# pixel format
|
||||
pfsize, pfflags = struct.unpack("<2I", header.read(8))
|
||||
fourcc = header.read(4)
|
||||
bitcount, = struct.unpack("<I", header.read(4))
|
||||
(bitcount,) = struct.unpack("<I", header.read(4))
|
||||
masks = struct.unpack("<4I", header.read(16))
|
||||
if pfflags & 0x40:
|
||||
# DDPF_RGB - Texture contains uncompressed RGB data
|
||||
|
||||
@ -104,7 +104,10 @@ class FpxImageFile(ImageFile.ImageFile):
|
||||
s = prop[0x2000002 | id]
|
||||
|
||||
colors = []
|
||||
for i in range(i32(s, 4)):
|
||||
bands = i32(s, 4)
|
||||
if bands > 4:
|
||||
raise IOError("Invalid number of bands")
|
||||
for i in range(bands):
|
||||
# note: for now, we ignore the "uncalibrated" flag
|
||||
colors.append(i32(s, 8 + i * 4) & 0x7FFFFFFF)
|
||||
|
||||
|
||||
@ -79,7 +79,7 @@ class FtexImageFile(ImageFile.ImageFile):
|
||||
|
||||
format, where = struct.unpack("<2i", self.fp.read(8))
|
||||
self.fp.seek(where)
|
||||
mipmap_size, = struct.unpack("<i", self.fp.read(4))
|
||||
(mipmap_size,) = struct.unpack("<i", self.fp.read(4))
|
||||
|
||||
data = self.fp.read(mipmap_size)
|
||||
|
||||
|
||||
@ -3238,7 +3238,7 @@ class Exif(MutableMapping):
|
||||
continue
|
||||
size = count * unit_size
|
||||
if size > 4:
|
||||
offset, = struct.unpack("<L", data)
|
||||
(offset,) = struct.unpack("<L", data)
|
||||
data = ifd_data[offset - 12 : offset + size - 12]
|
||||
else:
|
||||
data = data[:size]
|
||||
@ -3268,7 +3268,7 @@ class Exif(MutableMapping):
|
||||
)
|
||||
if ifd_tag == 0x1101:
|
||||
# CameraInfo
|
||||
offset, = struct.unpack(">L", data)
|
||||
(offset,) = struct.unpack(">L", data)
|
||||
self.fp.seek(offset)
|
||||
|
||||
camerainfo = {"ModelID": self.fp.read(4)}
|
||||
|
||||
@ -484,7 +484,7 @@ class ImageFileDirectory_v2(MutableMapping):
|
||||
else:
|
||||
raise SyntaxError("not a TIFF IFD")
|
||||
self.reset()
|
||||
self.next, = self._unpack("L", ifh[4:])
|
||||
(self.next,) = self._unpack("L", ifh[4:])
|
||||
self._legacy_api = False
|
||||
|
||||
prefix = property(lambda self: self._prefix)
|
||||
@ -595,7 +595,7 @@ class ImageFileDirectory_v2(MutableMapping):
|
||||
]: # rationals
|
||||
values = (values,)
|
||||
try:
|
||||
dest[tag], = values
|
||||
(dest[tag],) = values
|
||||
except ValueError:
|
||||
# We've got a builtin tag with 1 expected entry
|
||||
warnings.warn(
|
||||
@ -765,7 +765,7 @@ class ImageFileDirectory_v2(MutableMapping):
|
||||
size = count * unit_size
|
||||
if size > 4:
|
||||
here = fp.tell()
|
||||
offset, = self._unpack("L", data)
|
||||
(offset,) = self._unpack("L", data)
|
||||
if DEBUG:
|
||||
print(
|
||||
"Tag Location: %s - Data Location: %s" % (here, offset),
|
||||
@ -797,7 +797,7 @@ class ImageFileDirectory_v2(MutableMapping):
|
||||
else:
|
||||
print("- value:", self[tag])
|
||||
|
||||
self.next, = self._unpack("L", self._ensure_read(fp, 4))
|
||||
(self.next,) = self._unpack("L", self._ensure_read(fp, 4))
|
||||
except IOError as msg:
|
||||
warnings.warn(str(msg))
|
||||
return
|
||||
@ -1809,11 +1809,11 @@ class AppendingTiffWriter:
|
||||
return self.f.write(data)
|
||||
|
||||
def readShort(self):
|
||||
value, = struct.unpack(self.shortFmt, self.f.read(2))
|
||||
(value,) = struct.unpack(self.shortFmt, self.f.read(2))
|
||||
return value
|
||||
|
||||
def readLong(self):
|
||||
value, = struct.unpack(self.longFmt, self.f.read(4))
|
||||
(value,) = struct.unpack(self.longFmt, self.f.read(4))
|
||||
return value
|
||||
|
||||
def rewriteLastShortToLong(self, value):
|
||||
|
||||
@ -1,2 +1,2 @@
|
||||
# Master version for Pillow
|
||||
__version__ = "6.2.0"
|
||||
__version__ = "6.2.2"
|
||||
|
||||
@ -40,8 +40,7 @@ ImagingFliDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
|
||||
return 0;
|
||||
|
||||
/* We don't decode anything unless we have a full chunk in the
|
||||
input buffer (on the other hand, the Python part of the driver
|
||||
makes sure this is always the case) */
|
||||
input buffer */
|
||||
|
||||
ptr = buf;
|
||||
|
||||
@ -52,6 +51,10 @@ ImagingFliDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
|
||||
/* Make sure this is a frame chunk. The Python driver takes
|
||||
case of other chunk types. */
|
||||
|
||||
if (bytes < 8) {
|
||||
state->errcode = IMAGING_CODEC_OVERRUN;
|
||||
return -1;
|
||||
}
|
||||
if (I16(ptr+4) != 0xF1FA) {
|
||||
state->errcode = IMAGING_CODEC_UNKNOWN;
|
||||
return -1;
|
||||
|
||||
@ -25,6 +25,9 @@ ImagingPcxDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
|
||||
if (strcmp(im->mode, "1") == 0 && state->xsize > state->bytes * 8) {
|
||||
state->errcode = IMAGING_CODEC_OVERRUN;
|
||||
return -1;
|
||||
} else if (strcmp(im->mode, "P") == 0 && state->xsize > state->bytes) {
|
||||
state->errcode = IMAGING_CODEC_OVERRUN;
|
||||
return -1;
|
||||
}
|
||||
|
||||
ptr = buf;
|
||||
|
||||
@ -25,7 +25,7 @@ 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)
|
||||
static int expandrow(UINT8* dest, UINT8* src, int n, int z, int xsize)
|
||||
{
|
||||
UINT8 pixel, count;
|
||||
|
||||
@ -37,6 +37,9 @@ static int expandrow(UINT8* dest, UINT8* src, int n, int z)
|
||||
count = pixel & RLE_MAX_RUN;
|
||||
if (!count)
|
||||
return count;
|
||||
if (count > xsize) {
|
||||
return -1;
|
||||
}
|
||||
if (pixel & RLE_COPY_FLAG) {
|
||||
while(count--) {
|
||||
*dest = *src++;
|
||||
@ -56,7 +59,7 @@ static int expandrow(UINT8* dest, UINT8* src, int n, int z)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int expandrow2(UINT8* dest, const UINT8* src, int n, int z)
|
||||
static int expandrow2(UINT8* dest, const UINT8* src, int n, int z, int xsize)
|
||||
{
|
||||
UINT8 pixel, count;
|
||||
|
||||
@ -70,6 +73,9 @@ static int expandrow2(UINT8* dest, const UINT8* src, int n, int z)
|
||||
count = pixel & RLE_MAX_RUN;
|
||||
if (!count)
|
||||
return count;
|
||||
if (count > xsize) {
|
||||
return -1;
|
||||
}
|
||||
if (pixel & RLE_COPY_FLAG) {
|
||||
while(count--) {
|
||||
memcpy(dest, src, 2);
|
||||
@ -96,6 +102,7 @@ ImagingSgiRleDecode(Imaging im, ImagingCodecState state,
|
||||
UINT8 *ptr;
|
||||
SGISTATE *c;
|
||||
int err = 0;
|
||||
int status;
|
||||
|
||||
/* Get all data from File descriptor */
|
||||
c = (SGISTATE*)state->context;
|
||||
@ -164,12 +171,16 @@ ImagingSgiRleDecode(Imaging im, ImagingCodecState state,
|
||||
|
||||
/* row decompression */
|
||||
if (c->bpc ==1) {
|
||||
if(expandrow(&state->buffer[c->channo], &ptr[c->rleoffset], c->rlelength, im->bands))
|
||||
goto sgi_finish_decode;
|
||||
status = expandrow(&state->buffer[c->channo], &ptr[c->rleoffset], c->rlelength, im->bands, im->xsize);
|
||||
}
|
||||
else {
|
||||
if(expandrow2(&state->buffer[c->channo * 2], &ptr[c->rleoffset], c->rlelength, im->bands))
|
||||
goto sgi_finish_decode;
|
||||
status = expandrow2(&state->buffer[c->channo * 2], &ptr[c->rleoffset], c->rlelength, im->bands, im->xsize);
|
||||
}
|
||||
if (status == -1) {
|
||||
state->errcode = IMAGING_CODEC_OVERRUN;
|
||||
return -1;
|
||||
} else if (status == 1) {
|
||||
goto sgi_finish_decode;
|
||||
}
|
||||
|
||||
state->count += c->rlelength;
|
||||
|
||||
@ -353,16 +353,18 @@ int ImagingLibTiffDecode(Imaging im, ImagingCodecState state, UINT8* buffer, Py_
|
||||
|
||||
// We could use TIFFTileSize, but for YCbCr data it returns subsampled data size
|
||||
row_byte_size = (tile_width * state->bits + 7) / 8;
|
||||
state->bytes = row_byte_size * tile_length;
|
||||
|
||||
/* overflow check for malloc */
|
||||
if (state->bytes > INT_MAX - 1) {
|
||||
/* overflow check for realloc */
|
||||
if (INT_MAX / row_byte_size < tile_length) {
|
||||
state->errcode = IMAGING_CODEC_MEMORY;
|
||||
TIFFClose(tiff);
|
||||
return -1;
|
||||
}
|
||||
|
||||
state->bytes = row_byte_size * tile_length;
|
||||
|
||||
/* realloc to fit whole tile */
|
||||
/* malloc check above */
|
||||
new_data = realloc (state->buffer, state->bytes);
|
||||
if (!new_data) {
|
||||
state->errcode = IMAGING_CODEC_MEMORY;
|
||||
@ -415,11 +417,20 @@ int ImagingLibTiffDecode(Imaging im, ImagingCodecState state, UINT8* buffer, Py_
|
||||
|
||||
// We could use TIFFStripSize, but for YCbCr data it returns subsampled data size
|
||||
row_byte_size = (state->xsize * state->bits + 7) / 8;
|
||||
|
||||
/* overflow check for realloc */
|
||||
if (INT_MAX / row_byte_size < rows_per_strip) {
|
||||
state->errcode = IMAGING_CODEC_MEMORY;
|
||||
TIFFClose(tiff);
|
||||
return -1;
|
||||
}
|
||||
|
||||
state->bytes = rows_per_strip * row_byte_size;
|
||||
|
||||
TRACE(("StripSize: %d \n", state->bytes));
|
||||
|
||||
/* realloc to fit whole strip */
|
||||
/* malloc check above */
|
||||
new_data = realloc (state->buffer, state->bytes);
|
||||
if (!new_data) {
|
||||
state->errcode = IMAGING_CODEC_MEMORY;
|
||||
|
||||
2
tox.ini
2
tox.ini
@ -6,7 +6,7 @@
|
||||
[tox]
|
||||
envlist =
|
||||
lint
|
||||
py{27,35,36,37}
|
||||
py{27,35,36,37,38}
|
||||
minversion = 1.9
|
||||
|
||||
[testenv]
|
||||
|
||||
@ -10,6 +10,7 @@ pythons = {
|
||||
"36": {"compiler": 7.1, "vc": 2015},
|
||||
"pypy3": {"compiler": 7.1, "vc": 2015},
|
||||
"37": {"compiler": 7.1, "vc": 2015},
|
||||
"38": {"compiler": 7.1, "vc": 2015},
|
||||
}
|
||||
|
||||
VIRT_BASE = "c:/vp/"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user