Merge branch 'master' into fribidi-link

This commit is contained in:
Andrew Murray 2021-02-07 16:02:16 +11:00 committed by GitHub
commit 9b56833300
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
40 changed files with 723 additions and 58 deletions

View File

@ -32,7 +32,7 @@ install:
c:\pillow\winbuild\build\build_dep_all.cmd
$host.SetShouldExit(0)
- path C:\pillow\winbuild\build\bin;%PATH%
- '%PYTHON%\%EXECUTABLE% -m pip install -U "setuptools>=49.3.2"'
- '%PYTHON%\%EXECUTABLE% -m pip install -U setuptools'
build_script:
- ps: |
@ -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

@ -34,12 +34,12 @@ jobs:
python-version: 3.8
- name: Build system information
run: python .github/workflows/system-info.py
run: python3 .github/workflows/system-info.py
- name: Install dependencies
run: |
python -m pip install -U pip
python -m pip install -U tox
python3 -m pip install -U pip
python3 -m pip install -U tox
- name: Lint
run: tox -e lint

View File

@ -41,7 +41,7 @@ jobs:
- uses: actions/checkout@v2
- name: Build system information
run: python .github/workflows/system-info.py
run: python3 .github/workflows/system-info.py
- name: Set up QEMU
if: "matrix.qemu-arch"

View File

@ -246,8 +246,6 @@ jobs:
${{ matrix.package }}-python3-olefile \
${{ matrix.package }}-python3-pip \
${{ matrix.package }}-python3-pyqt5 \
${{ matrix.package }}-python3-pytest \
${{ matrix.package }}-python3-pytest-cov \
${{ matrix.package }}-python3-setuptools \
${{ matrix.package }}-freetype \
${{ matrix.package }}-ghostscript \
@ -260,7 +258,7 @@ jobs:
${{ matrix.package }}-openjpeg2 \
subversion
python3 -m pip install pyroma
python3 -m pip install pyroma pytest pytest-cov
pushd depends && ./install_extra_test_images.sh && popd
@ -270,6 +268,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

@ -58,7 +58,7 @@ jobs:
${{ matrix.os }}-${{ matrix.python-version }}-
- name: Build system information
run: python .github/workflows/system-info.py
run: python3 .github/workflows/system-info.py
- name: Install Linux dependencies
if: startsWith(matrix.os, 'ubuntu')

View File

@ -2,6 +2,24 @@
Changelog (Pillow)
==================
8.2.0 (unreleased)
------------------
- Deprecate Tk/Tcl 8.4, to be removed in Pillow 10 (2023-01-02) #5216
[radarhere]
- Added tk version to pilinfo #5226
[radarhere, nulano]
- Support for ignoring tests when running valgrind #5150
[wiredfool, radarhere, hugovk]
- PyModule_AddObject fix for Python 3.10 #5194
[radarhere]
- OSS-Fuzz support #5189
[wiredfool, radarhere]
8.1.0 (2020-01-02)
------------------

View File

@ -1,4 +1,7 @@
import io
import warnings
import pytest
def pytest_report_header(config):
@ -10,3 +13,19 @@ def pytest_report_header(config):
return out.getvalue()
except Exception as e:
return f"pytest_report_header failed: {e}"
def pytest_configure(config):
# We're marking some tests to ignore valgrind errors and XFAIL them.
# Ensure that the mark is defined
# even in cases where pytest-valgrind isn't installed
with warnings.catch_warnings():
warnings.simplefilter("error")
try:
getattr(pytest.mark, "valgrind_known_error")
except Exception:
config.addinivalue_line(
"markers",
"valgrind_known_error: Tests that have known issues with valgrind",
)

View File

@ -0,0 +1,48 @@
#!/usr/bin/python3
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import io
import sys
import warnings
import atheris_no_libfuzzer as atheris
from PIL import Image, ImageFile, ImageFilter
def TestOneInput(data):
try:
with Image.open(io.BytesIO(data)) as im:
im.rotate(45)
im.filter(ImageFilter.DETAIL)
im.save(io.BytesIO(), "BMP")
except Exception:
# We're catching all exceptions because Pillow's exceptions are
# directly inheriting from Exception.
return
return
def main():
ImageFile.LOAD_TRUNCATED_IMAGES = True
warnings.filterwarnings("ignore")
warnings.simplefilter("error", Image.DecompressionBombWarning)
atheris.Setup(sys.argv, TestOneInput, enable_python_coverage=True)
atheris.Fuzz()
if __name__ == "__main__":
main()

View File

@ -59,6 +59,7 @@ def test_invalid_file():
EpsImagePlugin.EpsImageFile(invalid_file)
@pytest.mark.valgrind_known_error(reason="Known Failing")
@pytest.mark.skipif(not HAS_GHOSTSCRIPT, reason="Ghostscript not available")
def test_cmyk():
with Image.open("Tests/images/pil_sample_cmyk.eps") as cmyk_image:

View File

@ -114,6 +114,7 @@ class TestFileJpeg:
assert test(100, 200) == (100, 200)
assert test(0) is None # square pixels
@pytest.mark.valgrind_known_error(reason="Known Failing")
def test_icc(self, tmp_path):
# Test ICC support
with Image.open("Tests/images/rgb.jpg") as im1:
@ -153,6 +154,7 @@ class TestFileJpeg:
test(ImageFile.MAXBLOCK + 1) # full buffer block plus one byte
test(ImageFile.MAXBLOCK * 4 + 3) # large block
@pytest.mark.valgrind_known_error(reason="Known Failing")
def test_large_icc_meta(self, tmp_path):
# https://github.com/python-pillow/Pillow/issues/148
# Sometimes the meta data on the icc_profile block is bigger than
@ -419,6 +421,7 @@ class TestFileJpeg:
with Image.open(filename):
pass
@pytest.mark.valgrind_known_error(reason="Known Failing")
def test_truncated_jpeg_should_read_all_the_data(self):
filename = "Tests/images/truncated_jpeg.jpg"
ImageFile.LOAD_TRUNCATED_IMAGES = True
@ -437,6 +440,7 @@ class TestFileJpeg:
with pytest.raises(OSError):
im.load()
@pytest.mark.valgrind_known_error(reason="Known Failing")
def test_qtables(self, tmp_path):
def _n_qtables_helper(n, test_file):
with Image.open(test_file) as im:
@ -720,6 +724,7 @@ class TestFileJpeg:
# OSError for unidentified image.
assert im.info.get("dpi") == (72, 72)
@pytest.mark.valgrind_known_error(reason="Known Failing")
def test_exif_x_resolution(self, tmp_path):
with Image.open("Tests/images/flower.jpg") as im:
exif = im.getexif()
@ -750,6 +755,7 @@ class TestFileJpeg:
# Act / Assert
assert im._getexif()[306] == "2017:03:13 23:03:09"
@pytest.mark.valgrind_known_error(reason="Backtrace in Python Core")
def test_photoshop(self):
with Image.open("Tests/images/photoshop-200dpi.jpg") as im:
assert im.info["photoshop"][0x03ED] == {

View File

@ -9,6 +9,7 @@ from ctypes import c_float
import pytest
from PIL import Image, ImageFilter, TiffImagePlugin, TiffTags, features
from PIL.TiffImagePlugin import SUBIFD
from .helper import (
assert_image_equal,
@ -185,6 +186,7 @@ class TestFileLibTiff(LibTiffTestCase):
for field in requested_fields:
assert field in reloaded, f"{field} not in metadata"
@pytest.mark.valgrind_known_error(reason="Known invalid metadata")
def test_additional_metadata(self, tmp_path):
# these should not crash. Seriously dummy data, most of it doesn't make
# any sense, so we're running up against limits where we're asking
@ -323,6 +325,14 @@ class TestFileLibTiff(LibTiffTestCase):
)
TiffImagePlugin.WRITE_LIBTIFF = False
def test_subifd(self, tmp_path):
outfile = str(tmp_path / "temp.tif")
with Image.open("Tests/images/g4_orientation_6.tif") as im:
im.tag_v2[SUBIFD] = 10000
# Should not segfault
im.save(outfile)
def test_xmlpacket_tag(self, tmp_path):
TiffImagePlugin.WRITE_LIBTIFF = True
@ -814,12 +824,14 @@ class TestFileLibTiff(LibTiffTestCase):
with Image.open(infile) as im:
assert_image_similar_tofile(im, "Tests/images/pil_sample_cmyk.jpg", 0.5)
@pytest.mark.valgrind_known_error(reason="Known Failing")
@pytest.mark.xfail(is_big_endian(), reason="Fails on big-endian")
def test_strip_ycbcr_jpeg_2x2_sampling(self):
infile = "Tests/images/tiff_strip_ycbcr_jpeg_2x2_sampling.tif"
with Image.open(infile) as im:
assert_image_similar_tofile(im, "Tests/images/flower.jpg", 0.5)
@pytest.mark.valgrind_known_error(reason="Known Failing")
@pytest.mark.xfail(is_big_endian(), reason="Fails on big-endian")
def test_strip_ycbcr_jpeg_1x1_sampling(self):
infile = "Tests/images/tiff_strip_ycbcr_jpeg_1x1_sampling.tif"
@ -831,12 +843,14 @@ class TestFileLibTiff(LibTiffTestCase):
with Image.open(infile) as im:
assert_image_similar_tofile(im, "Tests/images/pil_sample_cmyk.jpg", 0.5)
@pytest.mark.valgrind_known_error(reason="Known Failing")
@pytest.mark.xfail(is_big_endian(), reason="Fails on big-endian")
def test_tiled_ycbcr_jpeg_1x1_sampling(self):
infile = "Tests/images/tiff_tiled_ycbcr_jpeg_1x1_sampling.tif"
with Image.open(infile) as im:
assert_image_equal_tofile(im, "Tests/images/flower2.jpg")
@pytest.mark.valgrind_known_error(reason="Known Failing")
@pytest.mark.xfail(is_big_endian(), reason="Fails on big-endian")
def test_tiled_ycbcr_jpeg_2x2_sampling(self):
infile = "Tests/images/tiff_tiled_ycbcr_jpeg_2x2_sampling.tif"
@ -864,6 +878,7 @@ class TestFileLibTiff(LibTiffTestCase):
assert_image_similar(base_im, im, 0.7)
@pytest.mark.valgrind_known_error(reason="Backtrace in Python Core")
def test_sampleformat_not_corrupted(self):
# Assert that a TIFF image with SampleFormat=UINT tag is not corrupted
# when saving to a new file.

View File

@ -85,6 +85,7 @@ def test_unsupported_mode(tmp_path):
im.save(outfile)
@pytest.mark.valgrind_known_error(reason="Known Failing")
def test_save_all(tmp_path):
# Single frame image
helper_save_as_pdf(tmp_path, "RGB", save_all=True)

View File

@ -571,8 +571,8 @@ class TestFilePng:
assert len(chunks) == 3
def test_read_private_chunks(self):
im = Image.open("Tests/images/exif.png")
assert im.private_chunks == [(b"orNT", b"\x01")]
with Image.open("Tests/images/exif.png") as im:
assert im.private_chunks == [(b"orNT", b"\x01")]
def test_roundtrip_private_chunk(self):
# Check private chunk roundtripping
@ -654,6 +654,7 @@ class TestFilePng:
exif = reloaded._getexif()
assert exif[274] == 1
@pytest.mark.valgrind_known_error(reason="Known Failing")
def test_exif_from_jpg(self, tmp_path):
with Image.open("Tests/images/pil_sample_rgb.jpg") as im:
test_file = str(tmp_path / "temp.png")

View File

@ -4,7 +4,7 @@ from io import BytesIO
import pytest
from PIL import Image, TiffImagePlugin
from PIL.TiffImagePlugin import RESOLUTION_UNIT, SUBIFD, X_RESOLUTION, Y_RESOLUTION
from PIL.TiffImagePlugin import RESOLUTION_UNIT, X_RESOLUTION, Y_RESOLUTION
from .helper import (
assert_image_equal,
@ -161,14 +161,6 @@ class TestFileTiff:
reloaded.load()
assert (round(dpi), round(dpi)) == reloaded.info["dpi"]
def test_subifd(self, tmp_path):
outfile = str(tmp_path / "temp.tif")
with Image.open("Tests/images/g4_orientation_6.tif") as im:
im.tag_v2[SUBIFD] = 10000
# Should not segfault
im.save(outfile)
def test_save_setting_missing_resolution(self):
b = BytesIO()
Image.open("Tests/images/10ct_32bit_128.tiff").save(

View File

@ -1,5 +1,7 @@
from io import BytesIO
import pytest
from PIL import Image
from .helper import skip_unless_feature
@ -39,6 +41,7 @@ def test_read_exif_metadata_without_prefix():
assert exif[305] == "Adobe Photoshop CS6 (Macintosh)"
@pytest.mark.valgrind_known_error(reason="Known Failing")
def test_write_exif_metadata():
file_path = "Tests/images/flower.jpg"
test_buffer = BytesIO()
@ -71,6 +74,7 @@ def test_read_icc_profile():
assert icc == expected_icc
@pytest.mark.valgrind_known_error(reason="Known Failing")
def test_write_icc_metadata():
file_path = "Tests/images/flower2.jpg"
test_buffer = BytesIO()
@ -88,6 +92,7 @@ def test_write_icc_metadata():
assert webp_icc_profile == expected_icc_profile, "Webp ICC didn't match"
@pytest.mark.valgrind_known_error(reason="Known Failing")
def test_read_no_exif():
file_path = "Tests/images/flower.jpg"
test_buffer = BytesIO()

View File

@ -652,6 +652,7 @@ class TestImage:
assert not fp.closed
@pytest.mark.valgrind_known_error(reason="Known Failing")
def test_exif_jpeg(self, tmp_path):
with Image.open("Tests/images/exif-72dpi-int.jpg") as im: # Little endian
exif = im.getexif()

View File

@ -455,6 +455,7 @@ class TestCoreResampleBox:
tiled.paste(tile, (x0, y0))
return tiled
@pytest.mark.valgrind_known_error(reason="Known Failing")
def test_tiles(self):
with Image.open("Tests/images/flower.jpg") as im:
assert im.size == (480, 360)
@ -465,6 +466,7 @@ class TestCoreResampleBox:
tiled = self.resize_tiled(im, dst_size, *tiles)
assert_image_similar(reference, tiled, 0.01)
@pytest.mark.valgrind_known_error(reason="Known Failing")
def test_subsample(self):
# This test shows advantages of the subpixel resizing
# after supersampling (e.g. during JPEG decoding).

View File

@ -88,6 +88,7 @@ def test_no_resize():
assert im.size == (64, 64)
@pytest.mark.valgrind_known_error(reason="Known Failing")
def test_DCT_scaling_edges():
# Make an image with red borders and size (N * 8) + 1 to cross DCT grid
im = Image.new("RGB", (257, 257), "red")

View File

@ -1,7 +1,7 @@
#!/bin/bash
# install libimagequant
archive=libimagequant-2.13.1
archive=libimagequant-2.14.0
./download-and-extract.sh $archive https://raw.githubusercontent.com/python-pillow/pillow-depends/master/$archive.tar.gz

View File

@ -1,7 +1,7 @@
#!/bin/bash
# install webp
archive=libwebp-1.1.0
archive=libwebp-1.2.0
./download-and-extract.sh $archive https://raw.githubusercontent.com/python-pillow/pillow-depends/master/$archive.tar.gz

View File

@ -25,6 +25,14 @@ vulnerability introduced in FreeType 2.6 (:cve:`CVE-2020-15999`).
.. _2.10.4: https://sourceforge.net/projects/freetype/files/freetype2/2.10.4/
Tk/Tcl 8.4
~~~~~~~~~~
.. deprecated:: 8.2.0
Support for Tk/Tcl 8.4 is deprecated and will be removed in Pillow 10.0.0 (2023-01-02),
when Tk/Tcl 8.5 will be the minimum supported.
Image.show command parameter
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -159,7 +159,7 @@ Many of Pillow's features require external libraries:
* **littlecms** provides color management
* Pillow version 2.2.1 and below uses liblcms1, Pillow 2.3.0 and
above uses liblcms2. Tested with **1.19** and **2.7-2.11**.
above uses liblcms2. Tested with **1.19** and **2.7-2.12**.
* **libwebp** provides the WebP format.
@ -177,7 +177,7 @@ Many of Pillow's features require external libraries:
* **libimagequant** provides improved color quantization
* Pillow has been tested with libimagequant **2.6-2.13.1**
* Pillow has been tested with libimagequant **2.6-2.14**
* Libimagequant is licensed GPLv3, which is more restrictive than
the Pillow license, therefore we will not be distributing binaries
with libimagequant support enabled.
@ -465,9 +465,9 @@ These platforms have been reported to work at the versions mentioned.
+----------------------------------+------------------------------+--------------------------------+-----------------------+
|**Operating system** |**Tested Python versions** |**Latest tested Pillow version**|**Tested processors** |
+----------------------------------+------------------------------+--------------------------------+-----------------------+
| macOS 11.0 Big Sur | 3.8, 3.9 | 8.0.1 |arm |
| macOS 11.0 Big Sur | 3.8, 3.9 | 8.1.0 |arm |
| +------------------------------+--------------------------------+-----------------------+
| | 3.6, 3.7, 3.8, 3.9 | 8.0.1 |x86-64 |
| | 3.6, 3.7, 3.8, 3.9 | 8.1.0 |x86-64 |
+----------------------------------+------------------------------+--------------------------------+-----------------------+
| macOS 10.15 Catalina | 3.6, 3.7, 3.8, 3.9 | 8.0.1 |x86-64 |
| +------------------------------+--------------------------------+ +

View File

@ -22,7 +22,7 @@ Windows).
.. code-block:: python
from PIL import Image
im = Image.open("bride.jpg")
im = Image.open("hopper.jpg")
im.rotate(45).show()
Create thumbnails

View File

@ -0,0 +1,469 @@
C Extension debugging on Linux, with gbd/valgrind.
==================================================
Install the tools
-----------------
You need some basics in addition to the basic tools to build
pillow. These are what's required on Ubuntu, YMMV for other
distributions.
- ``python3-dbg`` package for the gdb extensions and python symbols
- ``gdb`` and ``valgrind``
- Potentially debug symbols for libraries. On ubuntu they're shipped
in package-dbgsym packages, from a different repo.
::
deb http://ddebs.ubuntu.com focal main restricted universe multiverse
deb http://ddebs.ubuntu.com focal-updates main restricted universe multiverse
deb http://ddebs.ubuntu.com focal-proposed main restricted universe multiverse
Then ``sudo apt-get update && sudo apt-get install libtiff5-dbgsym``
- There's a bug with the dbg package for at least python 3.8 on ubuntu
20.04, and you need to add a new link or two to make it autoload when
running python:
::
cd /usr/share/gdb/auto-load/usr/bin
ln -s python3.8m-gdb.py python3.8d-gdb.py
- In Ubuntu 18.04, it's actually including the path to the virtualenv
in the search for the ``python3.*-gdb.py`` file, but you can
helpfully put in the same directory as the binary.
- I also find that history is really useful for gdb, so I added this to
my ``~/.gdbinit`` file:
::
set history filename ~/.gdb_history
set history save on
- If the python stack isn't working in gdb, then
``set debug auto-load`` can also be helpful in ``.gdbinit``.
- Make a virtualenv with the debug python and activate it, then install
whatever dependencies are required and build. You want to build with
the debug python so you get symbols for your extension.
::
virtualenv -p python3.8-dbg ~/vpy38-dbg
source ~/vpy38-dbg/bin/activate
cd ~/Pillow && pip install -r requirements.txt && make install
Test Case
---------
Take your test image, and make a really simple harness.
::
from PIL import Image
im = Image.open(path)
im.load()
- Run this through valgrind, but note that python triggers some issues
on its own, so you're looking for items within the Pillow hierarchy
that don't look like they're solely in the python call chain. In this
example, the ones we're interested are after the warnings, and have
``decode.c`` and ``TiffDecode.c`` in the call stack:
::
(vpy38-dbg) ubuntu@primary:~/Home/tests$ valgrind python test_tiff.py
==51890== Memcheck, a memory error detector
==51890== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==51890== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==51890== Command: python test_tiff.py
==51890==
==51890== Invalid read of size 4
==51890== at 0x472E3D: address_in_range (obmalloc.c:1401)
==51890== by 0x472EEA: pymalloc_free (obmalloc.c:1677)
==51890== by 0x474960: _PyObject_Free (obmalloc.c:1896)
==51890== by 0x473BAC: _PyMem_DebugRawFree (obmalloc.c:2187)
==51890== by 0x473BD4: _PyMem_DebugFree (obmalloc.c:2318)
==51890== by 0x474C08: PyObject_Free (obmalloc.c:709)
==51890== by 0x45DD60: dictresize (dictobject.c:1259)
==51890== by 0x45DD76: insertion_resize (dictobject.c:1019)
==51890== by 0x464F30: PyDict_SetDefault (dictobject.c:2924)
==51890== by 0x4D03BE: PyUnicode_InternInPlace (unicodeobject.c:15289)
==51890== by 0x4D0700: PyUnicode_InternFromString (unicodeobject.c:15322)
==51890== by 0x64D2FC: descr_new (descrobject.c:857)
==51890== Address 0x4c1b020 is 384 bytes inside a block of size 1,160 free'd
==51890== at 0x483CA3F: free (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==51890== by 0x4735D3: _PyMem_RawFree (obmalloc.c:127)
==51890== by 0x473BAC: _PyMem_DebugRawFree (obmalloc.c:2187)
==51890== by 0x474941: PyMem_RawFree (obmalloc.c:595)
==51890== by 0x47496E: _PyObject_Free (obmalloc.c:1898)
==51890== by 0x473BAC: _PyMem_DebugRawFree (obmalloc.c:2187)
==51890== by 0x473BD4: _PyMem_DebugFree (obmalloc.c:2318)
==51890== by 0x474C08: PyObject_Free (obmalloc.c:709)
==51890== by 0x45DD60: dictresize (dictobject.c:1259)
==51890== by 0x45DD76: insertion_resize (dictobject.c:1019)
==51890== by 0x464F30: PyDict_SetDefault (dictobject.c:2924)
==51890== by 0x4D03BE: PyUnicode_InternInPlace (unicodeobject.c:15289)
==51890== Block was alloc'd at
==51890== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==51890== by 0x473646: _PyMem_RawMalloc (obmalloc.c:99)
==51890== by 0x473529: _PyMem_DebugRawAlloc (obmalloc.c:2120)
==51890== by 0x473565: _PyMem_DebugRawMalloc (obmalloc.c:2153)
==51890== by 0x4748B1: PyMem_RawMalloc (obmalloc.c:572)
==51890== by 0x475909: _PyObject_Malloc (obmalloc.c:1628)
==51890== by 0x473529: _PyMem_DebugRawAlloc (obmalloc.c:2120)
==51890== by 0x473565: _PyMem_DebugRawMalloc (obmalloc.c:2153)
==51890== by 0x4736B0: _PyMem_DebugMalloc (obmalloc.c:2303)
==51890== by 0x474B78: PyObject_Malloc (obmalloc.c:685)
==51890== by 0x45C435: new_keys_object (dictobject.c:558)
==51890== by 0x45DA95: dictresize (dictobject.c:1202)
==51890==
==51890== Invalid read of size 4
==51890== at 0x472E3D: address_in_range (obmalloc.c:1401)
==51890== by 0x47594A: pymalloc_realloc (obmalloc.c:1929)
==51890== by 0x475A02: _PyObject_Realloc (obmalloc.c:1982)
==51890== by 0x473DCA: _PyMem_DebugRawRealloc (obmalloc.c:2240)
==51890== by 0x473FF8: _PyMem_DebugRealloc (obmalloc.c:2326)
==51890== by 0x4749FB: PyMem_Realloc (obmalloc.c:623)
==51890== by 0x44A6FC: list_resize (listobject.c:70)
==51890== by 0x44A872: app1 (listobject.c:340)
==51890== by 0x44FD65: PyList_Append (listobject.c:352)
==51890== by 0x514315: r_ref (marshal.c:945)
==51890== by 0x516034: r_object (marshal.c:1139)
==51890== by 0x516C70: r_object (marshal.c:1389)
==51890== Address 0x4c41020 is 32 bytes before a block of size 1,600 in arena "client"
==51890==
==51890== Conditional jump or move depends on uninitialised value(s)
==51890== at 0x472E46: address_in_range (obmalloc.c:1403)
==51890== by 0x47594A: pymalloc_realloc (obmalloc.c:1929)
==51890== by 0x475A02: _PyObject_Realloc (obmalloc.c:1982)
==51890== by 0x473DCA: _PyMem_DebugRawRealloc (obmalloc.c:2240)
==51890== by 0x473FF8: _PyMem_DebugRealloc (obmalloc.c:2326)
==51890== by 0x4749FB: PyMem_Realloc (obmalloc.c:623)
==51890== by 0x44A6FC: list_resize (listobject.c:70)
==51890== by 0x44A872: app1 (listobject.c:340)
==51890== by 0x44FD65: PyList_Append (listobject.c:352)
==51890== by 0x5E3321: _posix_listdir (posixmodule.c:3823)
==51890== by 0x5E33A8: os_listdir_impl (posixmodule.c:3879)
==51890== by 0x5E4D77: os_listdir (posixmodule.c.h:1197)
==51890==
==51890== Use of uninitialised value of size 8
==51890== at 0x472E59: address_in_range (obmalloc.c:1403)
==51890== by 0x47594A: pymalloc_realloc (obmalloc.c:1929)
==51890== by 0x475A02: _PyObject_Realloc (obmalloc.c:1982)
==51890== by 0x473DCA: _PyMem_DebugRawRealloc (obmalloc.c:2240)
==51890== by 0x473FF8: _PyMem_DebugRealloc (obmalloc.c:2326)
==51890== by 0x4749FB: PyMem_Realloc (obmalloc.c:623)
==51890== by 0x44A6FC: list_resize (listobject.c:70)
==51890== by 0x44A872: app1 (listobject.c:340)
==51890== by 0x44FD65: PyList_Append (listobject.c:352)
==51890== by 0x5E3321: _posix_listdir (posixmodule.c:3823)
==51890== by 0x5E33A8: os_listdir_impl (posixmodule.c:3879)
==51890== by 0x5E4D77: os_listdir (posixmodule.c.h:1197)
==51890==
/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data. Expecting to read 16908288 bytes but only got 0. Skipping tag 0
warnings.warn(
/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data. Expecting to read 67895296 bytes but only got 0. Skipping tag 0
warnings.warn(
/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data. Expecting to read 1572864 bytes but only got 0. Skipping tag 42
warnings.warn(
/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data. Expecting to read 116647 bytes but only got 4867. Skipping tag 42738
warnings.warn(
/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data. Expecting to read 3468830728 bytes but only got 4851. Skipping tag 279
warnings.warn(
/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data. Expecting to read 2198732800 bytes but only got 0. Skipping tag 0
warnings.warn(
/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data. Expecting to read 67239937 bytes but only got 4125. Skipping tag 0
warnings.warn(
/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data. Expecting to read 33947764 bytes but only got 0. Skipping tag 139
warnings.warn(
/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data. Expecting to read 17170432 bytes but only got 0. Skipping tag 0
warnings.warn(
/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data. Expecting to read 80478208 bytes but only got 0. Skipping tag 1
warnings.warn(
/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data. Expecting to read 787460 bytes but only got 4882. Skipping tag 20
warnings.warn(
/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data. Expecting to read 1075 bytes but only got 0. Skipping tag 256
warnings.warn(
/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data. Expecting to read 120586240 bytes but only got 0. Skipping tag 194
warnings.warn(
/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data. Expecting to read 65536 bytes but only got 0. Skipping tag 3
warnings.warn(
/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data. Expecting to read 198656 bytes but only got 0. Skipping tag 279
warnings.warn(
/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data. Expecting to read 206848 bytes but only got 0. Skipping tag 64512
warnings.warn(
/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data. Expecting to read 130968 bytes but only got 4882. Skipping tag 256
warnings.warn(
/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data. Expecting to read 77848 bytes but only got 4689. Skipping tag 64270
warnings.warn(
/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data. Expecting to read 262156 bytes but only got 0. Skipping tag 257
warnings.warn(
/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data. Expecting to read 33624064 bytes but only got 0. Skipping tag 49152
warnings.warn(
/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data. Expecting to read 67178752 bytes but only got 4627. Skipping tag 50688
warnings.warn(
/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data. Expecting to read 33632768 bytes but only got 0. Skipping tag 56320
warnings.warn(
/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data. Expecting to read 134386688 bytes but only got 4115. Skipping tag 2048
warnings.warn(
/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data. Expecting to read 33912832 bytes but only got 0. Skipping tag 7168
warnings.warn(
/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data. Expecting to read 151966208 bytes but only got 4627. Skipping tag 10240
warnings.warn(
/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data. Expecting to read 119032832 bytes but only got 3859. Skipping tag 256
warnings.warn(
/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data. Expecting to read 46535680 bytes but only got 0. Skipping tag 256
warnings.warn(
/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data. Expecting to read 35651584 bytes but only got 0. Skipping tag 42
warnings.warn(
/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data. Expecting to read 524288 bytes but only got 0. Skipping tag 0
warnings.warn(
_TIFFVSetField: tempfile.tif: Null count for "Tag 769" (type 1, writecount -3, passcount 1).
_TIFFVSetField: tempfile.tif: Null count for "Tag 42754" (type 1, writecount -3, passcount 1).
_TIFFVSetField: tempfile.tif: Null count for "Tag 769" (type 1, writecount -3, passcount 1).
_TIFFVSetField: tempfile.tif: Null count for "Tag 42754" (type 1, writecount -3, passcount 1).
ZIPDecode: Decoding error at scanline 0, incorrect header check.
==51890== Invalid write of size 4
==51890== at 0x61C39E6: putcontig8bitYCbCr22tile (tif_getimage.c:2146)
==51890== by 0x61C5865: gtStripContig (tif_getimage.c:977)
==51890== by 0x6094317: ReadStrip (TiffDecode.c:269)
==51890== by 0x6094749: ImagingLibTiffDecode (TiffDecode.c:479)
==51890== by 0x60615D1: _decode (decode.c:136)
==51890== by 0x64BF47: method_vectorcall_VARARGS (descrobject.c:300)
==51890== by 0x4EB73C: _PyObject_Vectorcall (abstract.h:127)
==51890== by 0x4EB73C: call_function (ceval.c:4963)
==51890== by 0x4EB73C: _PyEval_EvalFrameDefault (ceval.c:3486)
==51890== by 0x4DF2EE: PyEval_EvalFrameEx (ceval.c:741)
==51890== by 0x43627B: function_code_fastcall (call.c:283)
==51890== by 0x436D21: _PyFunction_Vectorcall (call.c:410)
==51890== by 0x4EB73C: _PyObject_Vectorcall (abstract.h:127)
==51890== by 0x4EB73C: call_function (ceval.c:4963)
==51890== by 0x4EB73C: _PyEval_EvalFrameDefault (ceval.c:3486)
==51890== by 0x4DF2EE: PyEval_EvalFrameEx (ceval.c:741)
==51890== Address 0x6f456d4 is 0 bytes after a block of size 68 alloc'd
==51890== at 0x483DFAF: realloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==51890== by 0x60946D0: ImagingLibTiffDecode (TiffDecode.c:469)
==51890== by 0x60615D1: _decode (decode.c:136)
==51890== by 0x64BF47: method_vectorcall_VARARGS (descrobject.c:300)
==51890== by 0x4EB73C: _PyObject_Vectorcall (abstract.h:127)
==51890== by 0x4EB73C: call_function (ceval.c:4963)
==51890== by 0x4EB73C: _PyEval_EvalFrameDefault (ceval.c:3486)
==51890== by 0x4DF2EE: PyEval_EvalFrameEx (ceval.c:741)
==51890== by 0x43627B: function_code_fastcall (call.c:283)
==51890== by 0x436D21: _PyFunction_Vectorcall (call.c:410)
==51890== by 0x4EB73C: _PyObject_Vectorcall (abstract.h:127)
==51890== by 0x4EB73C: call_function (ceval.c:4963)
==51890== by 0x4EB73C: _PyEval_EvalFrameDefault (ceval.c:3486)
==51890== by 0x4DF2EE: PyEval_EvalFrameEx (ceval.c:741)
==51890== by 0x4DFDFB: _PyEval_EvalCodeWithName (ceval.c:4298)
==51890== by 0x436C40: _PyFunction_Vectorcall (call.c:435)
==51890==
==51890== Invalid write of size 4
==51890== at 0x61C39B5: putcontig8bitYCbCr22tile (tif_getimage.c:2145)
==51890== by 0x61C5865: gtStripContig (tif_getimage.c:977)
==51890== by 0x6094317: ReadStrip (TiffDecode.c:269)
==51890== by 0x6094749: ImagingLibTiffDecode (TiffDecode.c:479)
==51890== by 0x60615D1: _decode (decode.c:136)
==51890== by 0x64BF47: method_vectorcall_VARARGS (descrobject.c:300)
==51890== by 0x4EB73C: _PyObject_Vectorcall (abstract.h:127)
==51890== by 0x4EB73C: call_function (ceval.c:4963)
==51890== by 0x4EB73C: _PyEval_EvalFrameDefault (ceval.c:3486)
==51890== by 0x4DF2EE: PyEval_EvalFrameEx (ceval.c:741)
==51890== by 0x43627B: function_code_fastcall (call.c:283)
==51890== by 0x436D21: _PyFunction_Vectorcall (call.c:410)
==51890== by 0x4EB73C: _PyObject_Vectorcall (abstract.h:127)
==51890== by 0x4EB73C: call_function (ceval.c:4963)
==51890== by 0x4EB73C: _PyEval_EvalFrameDefault (ceval.c:3486)
==51890== by 0x4DF2EE: PyEval_EvalFrameEx (ceval.c:741)
==51890== Address 0x6f456d8 is 4 bytes after a block of size 68 alloc'd
==51890== at 0x483DFAF: realloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==51890== by 0x60946D0: ImagingLibTiffDecode (TiffDecode.c:469)
==51890== by 0x60615D1: _decode (decode.c:136)
==51890== by 0x64BF47: method_vectorcall_VARARGS (descrobject.c:300)
==51890== by 0x4EB73C: _PyObject_Vectorcall (abstract.h:127)
==51890== by 0x4EB73C: call_function (ceval.c:4963)
==51890== by 0x4EB73C: _PyEval_EvalFrameDefault (ceval.c:3486)
==51890== by 0x4DF2EE: PyEval_EvalFrameEx (ceval.c:741)
==51890== by 0x43627B: function_code_fastcall (call.c:283)
==51890== by 0x436D21: _PyFunction_Vectorcall (call.c:410)
==51890== by 0x4EB73C: _PyObject_Vectorcall (abstract.h:127)
==51890== by 0x4EB73C: call_function (ceval.c:4963)
==51890== by 0x4EB73C: _PyEval_EvalFrameDefault (ceval.c:3486)
==51890== by 0x4DF2EE: PyEval_EvalFrameEx (ceval.c:741)
==51890== by 0x4DFDFB: _PyEval_EvalCodeWithName (ceval.c:4298)
==51890== by 0x436C40: _PyFunction_Vectorcall (call.c:435)
==51890==
TIFFFillStrip: Invalid strip byte count 0, strip 1.
Traceback (most recent call last):
File "test_tiff.py", line 8, in <module>
im.load()
File "/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py", line 1087, in load
return self._load_libtiff()
File "/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py", line 1191, in _load_libtiff
raise OSError(err)
OSError: -2
sys:1: ResourceWarning: unclosed file <_io.BufferedReader name='crash-2020-10-test.tiff'>
==51890==
==51890== HEAP SUMMARY:
==51890== in use at exit: 748,734 bytes in 444 blocks
==51890== total heap usage: 6,320 allocs, 5,876 frees, 69,142,969 bytes allocated
==51890==
==51890== LEAK SUMMARY:
==51890== definitely lost: 0 bytes in 0 blocks
==51890== indirectly lost: 0 bytes in 0 blocks
==51890== possibly lost: 721,538 bytes in 372 blocks
==51890== still reachable: 27,196 bytes in 72 blocks
==51890== suppressed: 0 bytes in 0 blocks
==51890== Rerun with --leak-check=full to see details of leaked memory
==51890==
==51890== Use --track-origins=yes to see where uninitialised values come from
==51890== For lists of detected and suppressed errors, rerun with: -s
==51890== ERROR SUMMARY: 2556 errors from 6 contexts (suppressed: 0 from 0)
(vpy38-dbg) ubuntu@primary:~/Home/tests$
- Now that we've confirmed that there's something odd/bad going on,
it's time to gdb.
- Start with ``gdb python``
- Set a break point starting with the valgrind stack trace.
``b TiffDecode.c:269``
- Run the script with ``r test_tiff.py``
- When the break point is hit, explore the state with ``info locals``,
``bt``, ``py-bt``, or ``p [variable]``. For pointers,
``p *[variable]`` is useful.
::
(vpy38-dbg) ubuntu@primary:~/Home/tests$ gdb python
GNU gdb (Ubuntu 9.2-0ubuntu1~20.04) 9.2
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from python...
(gdb) b TiffDecode.c:269
No source file named TiffDecode.c.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 1 (TiffDecode.c:269) pending.
(gdb) r test_tiff.py
Starting program: /home/ubuntu/vpy38-dbg/bin/python test_tiff.py
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data. Expecting to read 16908288 bytes but only got 0. Skipping tag 0
warnings.warn(
/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data. Expecting to read 67895296 bytes but only got 0. Skipping tag 0
warnings.warn(
/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data. Expecting to read 1572864 bytes but only got 0. Skipping tag 42
warnings.warn(
/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data. Expecting to read 116647 bytes but only got 4867. Skipping tag 42738
warnings.warn(
/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data. Expecting to read 3468830728 bytes but only got 4851. Skipping tag 279
warnings.warn(
/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data. Expecting to read 2198732800 bytes but only got 0. Skipping tag 0
warnings.warn(
/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data. Expecting to read 67239937 bytes but only got 4125. Skipping tag 0
warnings.warn(
/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data. Expecting to read 33947764 bytes but only got 0. Skipping tag 139
warnings.warn(
/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data. Expecting to read 17170432 bytes but only got 0. Skipping tag 0
warnings.warn(
/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data. Expecting to read 80478208 bytes but only got 0. Skipping tag 1
warnings.warn(
/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data. Expecting to read 787460 bytes but only got 4882. Skipping tag 20
warnings.warn(
/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data. Expecting to read 1075 bytes but only got 0. Skipping tag 256
warnings.warn(
/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data. Expecting to read 120586240 bytes but only got 0. Skipping tag 194
warnings.warn(
/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data. Expecting to read 65536 bytes but only got 0. Skipping tag 3
warnings.warn(
/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data. Expecting to read 198656 bytes but only got 0. Skipping tag 279
warnings.warn(
/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data. Expecting to read 206848 bytes but only got 0. Skipping tag 64512
warnings.warn(
/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data. Expecting to read 130968 bytes but only got 4882. Skipping tag 256
warnings.warn(
/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data. Expecting to read 77848 bytes but only got 4689. Skipping tag 64270
warnings.warn(
/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data. Expecting to read 262156 bytes but only got 0. Skipping tag 257
warnings.warn(
/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data. Expecting to read 33624064 bytes but only got 0. Skipping tag 49152
warnings.warn(
/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data. Expecting to read 67178752 bytes but only got 4627. Skipping tag 50688
warnings.warn(
/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data. Expecting to read 33632768 bytes but only got 0. Skipping tag 56320
warnings.warn(
/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data. Expecting to read 134386688 bytes but only got 4115. Skipping tag 2048
warnings.warn(
/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data. Expecting to read 33912832 bytes but only got 0. Skipping tag 7168
warnings.warn(
/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data. Expecting to read 151966208 bytes but only got 4627. Skipping tag 10240
warnings.warn(
/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data. Expecting to read 119032832 bytes but only got 3859. Skipping tag 256
warnings.warn(
/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data. Expecting to read 46535680 bytes but only got 0. Skipping tag 256
warnings.warn(
/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data. Expecting to read 35651584 bytes but only got 0. Skipping tag 42
warnings.warn(
/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data. Expecting to read 524288 bytes but only got 0. Skipping tag 0
warnings.warn(
_TIFFVSetField: tempfile.tif: Null count for "Tag 769" (type 1, writecount -3, passcount 1).
_TIFFVSetField: tempfile.tif: Null count for "Tag 42754" (type 1, writecount -3, passcount 1).
_TIFFVSetField: tempfile.tif: Null count for "Tag 769" (type 1, writecount -3, passcount 1).
_TIFFVSetField: tempfile.tif: Null count for "Tag 42754" (type 1, writecount -3, passcount 1).
Breakpoint 1, ReadStrip (tiff=tiff@entry=0xae9b90, row=0, buffer=0xac2eb0) at src/libImaging/TiffDecode.c:269
269 ok = TIFFRGBAImageGet(&img, buffer, img.width, rows_to_read);
(gdb) p img
$1 = {tif = 0xae9b90, stoponerr = 0, isContig = 1, alpha = 0, width = 20, height = 1536, bitspersample = 8, samplesperpixel = 3,
orientation = 1, req_orientation = 1, photometric = 6, redcmap = 0x0, greencmap = 0x0, bluecmap = 0x0, get =
0x7ffff71d0710 <gtStripContig>, put = {any = 0x7ffff71ce550 <putcontig8bitYCbCr22tile>,
contig = 0x7ffff71ce550 <putcontig8bitYCbCr22tile>, separate = 0x7ffff71ce550 <putcontig8bitYCbCr22tile>}, Map = 0x0,
BWmap = 0x0, PALmap = 0x0, ycbcr = 0xaf24b0, cielab = 0x0, UaToAa = 0x0, Bitdepth16To8 = 0x0, row_offset = 0, col_offset = 0}
(gdb) up
#1 0x00007ffff736174a in ImagingLibTiffDecode (im=0xac1f90, state=0x7ffff76767e0, buffer=<optimized out>, bytes=<optimized out>)
at src/libImaging/TiffDecode.c:479
479 if (ReadStrip(tiff, state->y, (UINT32 *)state->buffer) == -1) {
(gdb) p *state
$2 = {count = 0, state = 0, errcode = 0, x = 0, y = 0, ystep = 0, xsize = 17, ysize = 108, xoff = 0, yoff = 0,
shuffle = 0x7ffff735f411 <copy4>, bits = 32, bytes = 68, buffer = 0xac2eb0 "P\354\336\367\377\177", context = 0xa75440, fd = 0x0}
(gdb) py-bt
Traceback (most recent call first):
File "/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py", line 1428, in _load_libtiff
File "/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py", line 1087, in load
return self._load_libtiff()
File "test_tiff.py", line 8, in <module>
im.load()
- Poke around till you understand what's going on. In this case,
state->xsize and img.width are different, which led to an out of
bounds write, as the receiving buffer was sized for the smaller of
the two.
Caveats
-------
- If your program is running/hung in a docker container and your host
has the appropriate tools, you can run gdb as the superuser in the
host and you may be able to get a trace of where the process is hung.
You probably won't have the capability to do that from within the
docker container, as the trace capacity isn't allowed by default.
- Variations of this are possible on the mac/windows, but the details
are going to be different.
- IIRC, Fedora has the gdb bits working by default. Ubuntu has always
been a bit of a battle to make it work.

View File

@ -17,7 +17,7 @@ Modules
Support for the following modules can be checked:
* ``pil``: The Pillow core module, required for all functionality.
* ``tkinter``: Tkinter support. Version number not available.
* ``tkinter``: Tkinter support.
* ``freetype2``: FreeType font support via :py:func:`PIL.ImageFont.truetype`.
* ``littlecms2``: LittleCMS 2 support via :py:mod:`PIL.ImageCms`.
* ``webp``: WebP image support.

View File

@ -8,3 +8,4 @@ Internal Reference Docs
limits
block_allocator
internal_modules
c_extension_debugging

View File

@ -69,6 +69,9 @@ Dependencies
OpenJPEG in the macOS and Linux wheels has been updated from 2.3.1 to 2.4.0, including
security fixes.
LibTIFF in the macOS and Linux wheels has been updated from 4.1.0 to 4.2.0, including
security fixes discovered by fuzzers.
Other Changes
=============

View File

@ -0,0 +1,40 @@
8.2.0
-----
Deprecations
============
Tk/Tcl 8.4
^^^^^^^^^^
Support for Tk/Tcl 8.4 is deprecated and will be removed in Pillow 10.0.0 (2023-01-02),
when Tk/Tcl 8.5 will be the minimum supported.
API Changes
===========
TODO
^^^^
TODO
API Additions
=============
TODO
^^^^
TODO
Security
========
TODO
Other Changes
=============
TODO
^^^^
TODO

View File

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

View File

@ -3,7 +3,7 @@
Versioning
==========
Pillow follows [Semantic Versioning](https://semver.org/):
Pillow follows `Semantic Versioning <https://semver.org/>`_:
Given a version number MAJOR.MINOR.PATCH, increment the:

View File

@ -147,9 +147,7 @@ def testimage():
('F', (128, 128))
PIL can do many other things, but I'll leave that for another
day. If you're curious, check the handbook, available from:
http://www.pythonware.com
day.
Cheers /F
"""

View File

@ -37,7 +37,7 @@ JPEG_ROOT = None
LCMS_ROOT = None
TIFF_ROOT = None
ZLIB_ROOT = None
FUZZING_BUILD = "LIB_FUZZING_ENGINE" in os.environ
if sys.platform == "win32" and sys.version_info >= (3, 10):
import atexit
@ -394,6 +394,9 @@ class pil_build_ext(build_ext):
extension.define_macros += define_macros
if sources is not None:
extension.sources += sources
if FUZZING_BUILD:
extension.language = "c++"
extension.extra_link_args = ["--stdlib=libc++"]
break
def _remove_extension(self, name):
@ -940,7 +943,7 @@ class pil_build_ext(build_ext):
def debug_build():
return hasattr(sys, "gettotalrefcount")
return hasattr(sys, "gettotalrefcount") or FUZZING_BUILD
files = ["src/_imaging.c"]

View File

@ -586,10 +586,10 @@ class Image:
This operation will destroy the image core and release its memory.
The image data will be unusable afterward.
This function is only required to close images that have not
had their file read and closed by the
:py:meth:`~PIL.Image.Image.load` method. See
:ref:`file-handling` for more information.
This function is required to close images that have multiple frames or
have not had their file read and closed by the
:py:meth:`~PIL.Image.Image.load` method. See :ref:`file-handling` for
more information.
"""
try:
if hasattr(self, "_close__fp"):
@ -878,7 +878,7 @@ class Image:
The default method of converting a greyscale ("L") or "RGB"
image into a bilevel (mode "1") image uses Floyd-Steinberg
dither to approximate the original image luminosity levels. If
dither is :data:`NONE`, all values larger than 128 are set to 255 (white),
dither is :data:`NONE`, all values larger than 127 are set to 255 (white),
all other values to 0 (black). To use other thresholds, use the
:py:meth:`~PIL.Image.Image.point` method.
@ -1243,6 +1243,10 @@ class Image:
"""
Returns a list of colors used in this image.
The colors will be in the image's mode. For example, an RGB image will
return a tuple of (red, green, blue) color values, and a P image will
return the index of the color in the palette.
:param maxcolors: Maximum number of colors. If this number is
exceeded, this method returns None. The default limit is
256 colors.

View File

@ -111,7 +111,7 @@ class PcxImageFile(ImageFile.ImageFile):
self._size = bbox[2] - bbox[0], bbox[3] - bbox[1]
# don't trust the passed in stride. Calculate for ourselves.
# CVE-2020-35655
# CVE-2020-35653
stride = (self._size[0] * bits + 7) // 8
stride += stride % 2

View File

@ -1,9 +1,20 @@
""" Find compiled module linking to Tcl / Tk libraries
"""
import sys
import tkinter
import warnings
from tkinter import _tkinter as tk
if hasattr(sys, "pypy_find_executable"):
TKINTER_LIB = tk.tklib_cffi.__file__
else:
TKINTER_LIB = tk.__file__
tk_version = str(tkinter.TkVersion)
if tk_version == "8.4":
warnings.warn(
"Support for Tk/Tcl 8.4 is deprecated and will be removed"
" in Pillow 10 (2023-01-02). Please upgrade to Tk/Tcl 8.5 "
"or newer.",
DeprecationWarning,
)

View File

@ -9,7 +9,7 @@ from . import Image
modules = {
"pil": ("PIL._imaging", "PILLOW_VERSION"),
"tkinter": ("PIL._tkinter_finder", None),
"tkinter": ("PIL._tkinter_finder", "tk_version"),
"freetype2": ("PIL._imagingft", "freetype2_version"),
"littlecms2": ("PIL._imagingcms", "littlecms_version"),
"webp": ("PIL._webp", "webpdecoder_version"),

View File

@ -4134,8 +4134,9 @@ setup_module(PyObject *m) {
}
#endif
PyObject *have_libjpegturbo;
#ifdef LIBJPEG_TURBO_VERSION
PyModule_AddObject(m, "HAVE_LIBJPEGTURBO", Py_True);
have_libjpegturbo = Py_True;
#define tostr1(a) #a
#define tostr(a) tostr1(a)
PyDict_SetItemString(
@ -4143,19 +4144,24 @@ setup_module(PyObject *m) {
#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 */
@ -4189,11 +4195,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

@ -920,20 +920,26 @@ 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) {
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

View File

@ -154,9 +154,9 @@ deps = {
# "bins": [r"libtiff\*.dll"],
},
"libwebp": {
"url": "http://downloads.webmproject.org/releases/webp/libwebp-1.1.0.tar.gz",
"filename": "libwebp-1.1.0.tar.gz",
"dir": "libwebp-1.1.0",
"url": "http://downloads.webmproject.org/releases/webp/libwebp-1.2.0.tar.gz",
"filename": "libwebp-1.2.0.tar.gz",
"dir": "libwebp-1.2.0",
"build": [
cmd_rmdir(r"output\release-static"), # clean
cmd_nmake(
@ -219,9 +219,9 @@ deps = {
# "bins": [r"objs\{msbuild_arch}\Release\freetype.dll"],
},
"lcms2": {
"url": SF_MIRROR + "/project/lcms/lcms/2.11/lcms2-2.11.tar.gz",
"filename": "lcms2-2.11.tar.gz",
"dir": "lcms2-2.11",
"url": SF_MIRROR + "/project/lcms/lcms/2.12/lcms2-2.12.tar.gz",
"filename": "lcms2-2.12.tar.gz",
"dir": "lcms2-2.12",
"patch": {
r"Projects\VC2017\lcms2_static\lcms2_static.vcxproj": {
# default is /MD for x86 and /MT for x64, we need /MD always