FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Update release notes for Pillow 13.0.0 (#10223) · python-pillow/Pillow@262e8e4 · GitHub

Repository navigation

Commit 262e8e4

Browse files
authored
Update release notes for Pillow 13.0.0 (#10223)
2 parents af56ace + c13c091 commit 262e8e4

3 files changed

Lines changed: 153 additions & 15 deletions

File tree

‎docs/conf.py‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,7 @@
251251
# https://www.sphinx-doc.org/en/master/usage/extensions/extlinks.html
252252
_repo = "https://github.com/python-pillow/Pillow/"
253253
extlinks = {
254+
"ghsa": (_repo + "security/advisories/GHSA-%s", "GHSA-%s"),
254255
"issue": (_repo + "issues/%s", "#%s"),
255256
"pr": (_repo + "pull/%s", "#%s"),
256257
"pypi": ("https://pypi.org/project/%s/", "%s"),

‎docs/reference/ImagePath.rst‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ The :py:mod:`~PIL.ImagePath` module is used to store and manipulate 2-dimensiona
88
vector data. Path objects can be passed to the methods on the
99
:py:mod:`~PIL.ImageDraw` module.
1010

11-
.. py:class:: PIL.ImagePath.Path
11+
.. py:class:: Path
1212
1313
A path object. The coordinate list can be any sequence object containing
1414
either 2-tuples [(x, y), …] or numeric values [x, y, …].
@@ -27,7 +27,7 @@ vector data. Path objects can be passed to the methods on the
2727
:param xy: A sequence. The sequence can contain 2-tuples [(x, y), ...]
2828
or a flat list of numbers [x, y, ...].
2929

30-
.. py:method:: PIL.ImagePath.Path.compact(distance=2)
30+
.. py:method:: Path.compact(distance=2)
3131
3232
Compacts the path, by removing points that are close to each other. This
3333
method modifies the path in place, and returns the number of points left in
@@ -38,17 +38,17 @@ vector data. Path objects can be passed to the methods on the
3838

3939
.. _Manhattan distance: https://en.wikipedia.org/wiki/Manhattan_distance
4040

41-
.. py:method:: PIL.ImagePath.Path.getbbox()
41+
.. py:method:: Path.getbbox()
4242
4343
Gets the bounding box of the path.
4444

4545
:return: ``(x0, y0, x1, y1)``
4646

47-
.. py:method:: PIL.ImagePath.Path.map(function)
47+
.. py:method:: Path.map(function)
4848
4949
Maps the path through a function.
5050

51-
.. py:method:: PIL.ImagePath.Path.tolist(flat=False)
51+
.. py:method:: Path.tolist(flat=False)
5252
5353
Converts the path to a Python list [(x, y), …].
5454

@@ -57,7 +57,7 @@ vector data. Path objects can be passed to the methods on the
5757
returns a flat list [x, y, ...] instead.
5858
:return: A list of coordinates. See ``flat``.
5959

60-
.. py:method:: PIL.ImagePath.Path.transform(matrix)
60+
.. py:method:: Path.transform(matrix)
6161
6262
Transforms the path in place, using an affine transform. The matrix is a
6363
6-tuple (a, b, c, d, e, f), and each point is mapped as follows::

‎docs/releasenotes/13.0.0.rst‎

Lines changed: 146 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,61 @@
44
Security
55
========
66

7-
TODO
8-
^^^^
7+
CVE identifiers will be added to these entries as they are assigned.
98

10-
TODO
9+
Critical
10+
^^^^^^^^
1111

12-
:cve:`YYYY-XXXXX`: TODO
13-
^^^^^^^^^^^^^^^^^^^^^^^
12+
* :cve:`2026-96639`, :ghsa:`v9pv-5gc8-w2m6`: Stale native image storage reused after mode transitions
13+
* :ghsa:`5x8w-8jj5-q52h`, :ghsa:`8g5g-8vmr-9782`: JPEG decoder buffer overflow from scanlines wider than tile extents
14+
15+
High
16+
^^^^
1417

15-
TODO
18+
* :cve:`2026-96644`, :ghsa:`9v9v-9qvf-h2hj`: WMF/EMF heap out-of-bounds read from dimension truncation
19+
* :cve:`2026-96637`, :ghsa:`g842-9rc4-69pw`: SPIDER decompression bomb bypass via seek()
20+
* :cve:`2026-96643`, :ghsa:`g4qv-2jxx-769h`: Unbounded Exif header replacement loop
21+
* :cve:`2026-96778`, :ghsa:`g7cr-3p24-7wf7`: JPEG comment write after ICC profile fills encoder buffer
22+
* :ghsa:`462x-pgg6-55fp`, :ghsa:`c6hw-5grf-ff96`: TIFF tile and YCbCr decoding out-of-bounds read from undersized libtiff buffers
23+
* :ghsa:`p4wg-p73j-c528`: PDF parsing stack exhaustion from long trailer chains and deep or cyclic page trees
24+
* :cve:`2026-96640`, :ghsa:`mrfp-p49p-3hf2`: PDF append resource exhaustion from repeated page tree references
25+
* :ghsa:`pchr-8j38-3x4p`: TIFF encoder accepted an incorrectly sized Colormap for non-8-bit images
26+
* :ghsa:`332p-7hrc-92wf`: TIFF encoder heap buffer overflow when saving to a file object
27+
* :ghsa:`xcvg-w56q-r89m`: TIFF encoder heap buffer overflow when tags override the image size
28+
* :ghsa:`xvh5-g6gv-559v`: TIFF encoder memory disclosure and crash from mismatched tag values
29+
* :ghsa:`q45j-58j2-45rg`: TIFF decoding returned uninitialized memory for short JPEG strips
30+
* :ghsa:`78g4-xqwv-q3g8`: Bundled OpenJPEG heap buffer overflow when reading tile-part data
31+
32+
Medium
33+
^^^^^^
34+
35+
* :ghsa:`4rr5-89j8-mwwm`: TIFF encoder use-after-free write
36+
* :cve:`2026-96636`, :ghsa:`p8hx-v2p6-rp84`: MPO, DCX and MIC decompression bomb bypass via seek()
37+
* :ghsa:`f2g6-542v-9j58`: PDF page tree stack exhaustion via cyclic ``/Kids`` reference
38+
* :ghsa:`5xm2-6676-qcp9`: APNG decompression bomb bypass via delayed disposal-frame sizing
39+
* :cve:`2026-96642`, :ghsa:`3j72-p6qg-6xp7`: TarIO negative size field causes infinite CPU-spin loop
40+
* :cve:`2026-96638`, :ghsa:`24rc-8hj2-v98c`: BMP RLE decoder memory-amplification denial of service
41+
* :ghsa:`gg2r-wvfm-q9rx`: MSP RLE decoder expands a tiny file into unbounded memory
42+
* :ghsa:`wqgw-9xfh-qf2g`: TIFF and Exif IFD parsing memory and CPU amplification from shared tag data
43+
* :ghsa:`jg86-v3jv-hrpm`: Quadratic time when writing many objects to a PDF
44+
* :ghsa:`254f-3936-288h`: PdfParser unbounded recursion via deeply nested objects
45+
* :ghsa:`rfgq-q3w2-pmv2`: Image.quantize() crash from an empty target palette
46+
* :ghsa:`xgh8-jp6q-p5x8`: XBM header parsing regular expression denial of service
47+
* :ghsa:`22hg-r758-rrw9`, :ghsa:`74r2-7ff9-mjj2`, :ghsa:`fc9g-5qg7-mf45`: GIF comment handling quadratic-time blowup from repeated concatenation
48+
* :ghsa:`27h8-gf7j-v5hc`: Out-of-bounds read in rank-based filters for zero-dimension images
49+
* :cve:`2026-96641`, :ghsa:`4rm8-3hmm-39fg`: Integer underflow in PILfont text width calculation
50+
* :ghsa:`cp9v-662q-vvx9`: Image.merge() buffer overflow when merging 32-bit images as narrower bands
51+
* :ghsa:`j4m9-6w36-pw47`: Uninitialized glyph pointer freed on font rendering error path
52+
* :ghsa:`7mwm-ghpf-9vrm`: Double free in ``Image.transform()`` after an allocation failure
53+
* :ghsa:`4558-3h8r-v8xp`: ``P;2L`` and ``P;4L`` raw mode decoders read past the end of their input
54+
* :ghsa:`w889-685w-c8fh`: EPS filename argument injection into Ghostscript
55+
56+
Low
57+
^^^
58+
59+
* :ghsa:`65qm-jvmh-6pqg`: GIF decompression bomb check used a size discarded on failure
60+
* :ghsa:`vx6w-vv9f-6gvg`: EPS decompression bomb bypass via Ghostscript rendering
61+
* :ghsa:`58r4-6rv3-gfh8`: ImageMorph.MorphOp.apply() out-of-bounds write on zero-width images
1662

1763
Backwards incompatible changes
1864
==============================
@@ -99,10 +145,26 @@ intended for internal use, so there is no replacement.
99145
API changes
100146
===========
101147

102-
TODO
103-
^^^^
148+
ImageColor.getcolor() with premultiplied alpha modes
149+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
150+
151+
When ``mode`` is ``RGBa`` or ``La``, :py:func:`~PIL.ImageColor.getcolor` now returns
152+
color values premultiplied by the alpha channel, matching how pixels are stored in
153+
those modes. Previously, the unmultiplied values were returned.
154+
155+
Duplicate TIFF tags
156+
^^^^^^^^^^^^^^^^^^^
157+
158+
If a TIFF IFD contains the same tag more than once, the first value is now kept.
159+
Previously, the last value overwrote the earlier ones.
104160

105-
TODO
161+
Saving small ICO images
162+
^^^^^^^^^^^^^^^^^^^^^^^
163+
164+
When saving an image smaller than 16x16 pixels as an ICO without a ``sizes``
165+
argument, the image's own size is now used. Previously, none of the default sizes
166+
matched, and an ICO containing no images was written. If no size in ``sizes`` fits
167+
within the image, a :py:exc:`ValueError` is now raised.
106168

107169
API additions
108170
=============
@@ -131,6 +193,21 @@ Added ``escape`` argument to ``PSDraw.text()``
131193
The default, ``False``, preserves the existing handling of backslashes and PostScript
132194
escape sequences.
133195

196+
ImageOps invert, posterize and solarize of P images
197+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
198+
199+
:py:func:`~PIL.ImageOps.invert`, :py:func:`~PIL.ImageOps.posterize` and
200+
:py:func:`~PIL.ImageOps.solarize` now support P mode images. The operation is applied
201+
to the palette colors, leaving any alpha values in the palette unchanged. Previously,
202+
these functions raised :py:exc:`NotImplementedError` for P mode.
203+
204+
Path-like objects for font files
205+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
206+
207+
:py:func:`~PIL.ImageFont.load`, :py:func:`~PIL.ImageFont.load_path` and
208+
:py:meth:`~PIL.FontFile.FontFile.save` now accept :py:class:`os.PathLike` objects,
209+
such as :py:class:`pathlib.Path`, in addition to strings.
210+
134211
Other changes
135212
=============
136213

@@ -143,6 +220,16 @@ immediately at the release of 3.15.0 final (2026-10-01, :pep:`790`).
143220

144221
Pillow 13.0.0 now officially supports Python 3.15.
145222

223+
Faster import
224+
^^^^^^^^^^^^^
225+
226+
Importing Pillow takes around half the time it did in Pillow 12.3.0. ``PIL.Image`` no
227+
longer imports ``logging``, modules that are only needed for some operations, such as
228+
``tempfile``, are now imported on first use, and on Python 3.15 Pillow also declares
229+
``__lazy_modules__`` to defer its remaining standard library imports (:pep:`810`). On an
230+
Apple Silicon Mac, ``from PIL import Image`` took 24 ms on Python 3.14 and 23 ms on
231+
Python 3.15 with Pillow 12.3.0, and now takes 12 ms and 10 ms.
232+
146233
PyPy 3.12
147234
^^^^^^^^^
148235

@@ -164,6 +251,20 @@ These libraries are now compiled with ``-O2``. Compared to Pillow 12.3.0, the wh
164251
PNG, JPEG, WebP and AVIF are unaffected, as those libraries were already built with
165252
optimisation.
166253

254+
Performance improvements
255+
^^^^^^^^^^^^^^^^^^^^^^^^
256+
257+
Building on the optimizations in Pillow 12.3.0, more of the C code has been
258+
restructured so that compilers can vectorize it. Compared to Pillow 12.3.0,
259+
:py:func:`~PIL.ImageChops.offset` is up to 46 times faster,
260+
:py:meth:`~PIL.Image.Image.getbbox` up to 24 times faster,
261+
flipping and rotating by 180 degrees with
262+
:py:meth:`~PIL.Image.Image.transpose` up to 10 times faster,
263+
:py:meth:`~PIL.Image.Image.filter` up to 3.5 times faster,
264+
:py:func:`~PIL.ImageChops.difference` up to 3 times faster, and converting P and PA
265+
images to RGB and RGBA up to 2.5 times faster. Saving an optimized GIF with a shared
266+
palette is around 6 times faster and uses less memory.
267+
167268
Wheels now use HarfBuzz for hinting
168269
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
169270

@@ -183,6 +284,13 @@ installed on the system with the expected name (e.g. ``libharfbuzz.so.0``).
183284
All wheels are now linked against the HarfBuzz that Pillow ships,
184285
which may slightly change how text is rendered in scripts that rely on the auto-hinter.
185286

287+
Thread safety for free-threaded Python
288+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
289+
290+
Critical sections now protect most operations on core image objects, such as
291+
conversion, pasting, filtering and pixel access, improving thread safety in the
292+
free-threaded build of Python. AVIF decoding also no longer blocks other threads.
293+
186294
Resizing images with alpha
187295
^^^^^^^^^^^^^^^^^^^^^^^^^^
188296

@@ -199,6 +307,27 @@ Preserved transparency when padding or expanding images in ImageOps
199307
pixels in L, P and RGB images previously became opaque when a border was added.
200308
New palette colors are allocated without using reserved transparency entries.
201309

310+
Fixed reading FITS images with more than 8 bits per pixel
311+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
312+
313+
FITS data is big-endian, but Pillow was reading 16-bit and 32-bit integer data, and
314+
32-bit and 64-bit floating point data, in the native byte order. These images now
315+
load with the correct pixel values.
316+
317+
Fixed accuracy of 16-bit image filters and conversions
318+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
319+
320+
Applying a kernel filter to an ``I;16`` image gave incorrect results for pixel values
321+
above 255, and converting an ``I;16N`` image to ``I`` or ``F`` clipped values to 255.
322+
Both now preserve the full 16-bit range.
323+
324+
Saving APNG frames with different palettes
325+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
326+
327+
An APNG file can only contain a single palette. When saving P mode frames with
328+
different palettes, the image is now saved as RGB, or RGBA if any palette contains
329+
alpha, instead of writing the later frames with the wrong colors.
330+
202331
Fixed ImageStat variance rounding
203332
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
204333

@@ -294,3 +423,11 @@ FriBiDi itself is not included in Pillow's wheels.
294423

295424
The shim's source files now include SPDX license identifiers, and the SBOM has been
296425
corrected.
426+
427+
ImagePath.Path.compact() on an empty path
428+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
429+
430+
:py:meth:`~PIL.ImagePath.Path.compact` is documented to return the number of
431+
points removed. On a path with no points, it instead added a point whose
432+
y coordinate was read from uninitialized memory, and returned ``-1``.
433+
``compact()`` now leaves an empty path unchanged and returns ``0``.

0 commit comments

Comments
 (0)

Back | FazBrowse Home | New Git URL