Skip to content

Commit

Permalink
Merge branch 'main' into tiff
Browse files Browse the repository at this point in the history
  • Loading branch information
radarhere authored Jan 1, 2024
2 parents f6bcf4e + 67a9e6e commit 99760f4
Show file tree
Hide file tree
Showing 36 changed files with 241 additions and 131 deletions.
18 changes: 18 additions & 0 deletions .github/problem-matchers/gcc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"__comment": "Based on vscode-cpptools' Extension/package.json gcc rule",
"problemMatcher": [
{
"owner": "gcc-problem-matcher",
"pattern": [
{
"regexp": "^\\s*(.*):(\\d+):(\\d+):\\s+(?:fatal\\s+)?(warning|error):\\s+(.*)$",
"file": 1,
"line": 2,
"column": 3,
"severity": 4,
"message": 5
}
]
}
]
}
2 changes: 2 additions & 0 deletions .github/release-drafter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ categories:
label: "Removal"
- title: "Testing"
label: "Testing"
- title: "Type hints"
label: "Type hints"

exclude-labels:
- "changelog: skip"
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@ jobs:
env:
GHA_PYTHON_VERSION: ${{ matrix.python-version }}

- name: Register gcc problem matcher
if: "matrix.os == 'ubuntu-latest' && matrix.python-version == '3.12'"
run: echo "::add-matcher::.github/problem-matchers/gcc.json"

- name: Build
run: |
.ci/build.sh
Expand Down
12 changes: 12 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,18 @@ Changelog (Pillow)
10.2.0 (unreleased)
-------------------

- Apply ImageFont.MAX_STRING_LENGTH to ImageFont.getmask() #7662
[radarhere]

- Optimise ``ImageColor`` using ``functools.lru_cache`` #7657
[hugovk]

- Restricted environment keys for ImageMath.eval() #7655
[wiredfool, radarhere]

- Optimise ``ImageMode.getmode`` using ``functools.lru_cache`` #7641
[hugovk, radarhere]

- Fix incorrect color blending for overlapping glyphs #7497
[ZachNagengast, nulano, radarhere]

Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ The Python Imaging Library (PIL) is

Pillow is the friendly PIL fork. It is

Copyright © 2010-2023 by Jeffrey A. Clark (Alex) and contributors.
Copyright © 2010-2024 by Jeffrey A. Clark (Alex) and contributors.

Like PIL, Pillow is licensed under the open source HPND License:

Expand Down
33 changes: 10 additions & 23 deletions RELEASING.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,7 @@ Released quarterly on January 2nd, April 1st, July 1st and October 15th.
git tag 5.2.0
git push --tags
```
* [ ] Create [source and binary distributions](https://github.com/python-pillow/Pillow/blob/main/RELEASING.md#source-and-binary-distributions)
* [ ] Check and upload all source and binary distributions e.g.:
```bash
python3 -m twine check --strict dist/*
python3 -m twine upload dist/Pillow-5.2.0*
```
* [ ] Create and upload all [source and binary distributions](https://github.com/python-pillow/Pillow/blob/main/RELEASING.md#source-and-binary-distributions)
* [ ] Publish the [release on GitHub](https://github.com/python-pillow/Pillow/releases)
* [ ] In compliance with [PEP 440](https://peps.python.org/pep-0440/),
increment and append `.dev0` to version identifier in `src/PIL/_version.py` and then:
Expand Down Expand Up @@ -55,12 +50,7 @@ Released as needed for security, installation or critical bug fixes.
```bash
make sdist
```
* [ ] Create [source and binary distributions](https://github.com/python-pillow/Pillow/blob/main/RELEASING.md#source-and-binary-distributions)
* [ ] Check and upload all source and binary distributions e.g.:
```bash
python3 -m twine check --strict dist/*
python3 -m twine upload dist/Pillow-5.2.1*
```
* [ ] Create and upload all [source and binary distributions](https://github.com/python-pillow/Pillow/blob/main/RELEASING.md#source-and-binary-distributions)
* [ ] Publish the [release on GitHub](https://github.com/python-pillow/Pillow/releases) and then:
```bash
git push
Expand All @@ -82,26 +72,23 @@ Released as needed privately to individual vendors for critical security-related
git tag 2.5.3
git push origin --tags
```
* [ ] Create and check source distribution:
```bash
make sdist
```
* [ ] Create [source and binary distributions](https://github.com/python-pillow/Pillow/blob/main/RELEASING.md#source-and-binary-distributions)
* [ ] Create and upload all [source and binary distributions](https://github.com/python-pillow/Pillow/blob/main/RELEASING.md#source-and-binary-distributions)
* [ ] Publish the [release on GitHub](https://github.com/python-pillow/Pillow/releases) and then:
```bash
git push origin 2.5.x
```

## Source and Binary Distributions

* [ ] Download sdist and wheels from the [GitHub Actions "Wheels" workflow](https://github.com/python-pillow/Pillow/actions/workflows/wheels.yml)
and copy into `dist/`. For example using [GitHub CLI](https://github.com/cli/cli):
* [ ] Check the [GitHub Actions "Wheels" workflow](https://github.com/python-pillow/Pillow/actions/workflows/wheels.yml)
has passed, including the "Upload release to PyPI" job. This will have been triggered
by the new tag.
* [ ] Download the Linux aarch64 wheels created by Travis CI from [GitHub releases](https://github.com/python-pillow/Pillow/releases)
and copy into `dist`. Check and upload them e.g.:
```bash
gh run download --dir dist
# select dist
python3 -m twine check --strict dist/*
python3 -m twine upload dist/Pillow-5.2.0*
```
* [ ] Download the Linux aarch64 wheels created by Travis CI from [GitHub releases](https://github.com/python-pillow/Pillow/releases)
and copy into `dist`.

## Publicize Release

Expand Down
Binary file added Tests/images/bgr15.dds
Binary file not shown.
Binary file added Tests/images/bgr15.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Tests/images/multiple_exif.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
File renamed without changes.
Binary file removed Tests/images/unsupported_bitcount_rgb.dds
Binary file not shown.
2 changes: 0 additions & 2 deletions Tests/oss-fuzz/fuzz_font.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
#!/usr/bin/python3

from __future__ import annotations

# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
Expand Down
2 changes: 0 additions & 2 deletions Tests/oss-fuzz/fuzz_pillow.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
#!/usr/bin/python3

from __future__ import annotations

# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
Expand Down
13 changes: 4 additions & 9 deletions Tests/test_file_dds.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
TEST_FILE_UNCOMPRESSED_L = "Tests/images/uncompressed_l.dds"
TEST_FILE_UNCOMPRESSED_L_WITH_ALPHA = "Tests/images/uncompressed_la.dds"
TEST_FILE_UNCOMPRESSED_RGB = "Tests/images/hopper.dds"
TEST_FILE_UNCOMPRESSED_BGR15 = "Tests/images/bgr15.dds"
TEST_FILE_UNCOMPRESSED_RGB_WITH_ALPHA = "Tests/images/uncompressed_rgb.dds"


Expand Down Expand Up @@ -249,6 +250,7 @@ def test_dx10_r8g8b8a8_unorm_srgb():
("L", (128, 128), TEST_FILE_UNCOMPRESSED_L),
("LA", (128, 128), TEST_FILE_UNCOMPRESSED_L_WITH_ALPHA),
("RGB", (128, 128), TEST_FILE_UNCOMPRESSED_RGB),
("RGB", (128, 128), TEST_FILE_UNCOMPRESSED_BGR15),
("RGBA", (800, 600), TEST_FILE_UNCOMPRESSED_RGB_WITH_ALPHA),
],
)
Expand Down Expand Up @@ -341,16 +343,9 @@ def test_palette():
assert_image_equal_tofile(im, "Tests/images/transparent.gif")


@pytest.mark.parametrize(
"test_file",
(
"Tests/images/unsupported_bitcount_rgb.dds",
"Tests/images/unsupported_bitcount_luminance.dds",
),
)
def test_unsupported_bitcount(test_file):
def test_unsupported_bitcount():
with pytest.raises(OSError):
with Image.open(test_file):
with Image.open("Tests/images/unsupported_bitcount.dds"):
pass


Expand Down
9 changes: 9 additions & 0 deletions Tests/test_file_iptc.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,15 @@
TEST_FILE = "Tests/images/iptc.jpg"


def test_open():
f = BytesIO(
b"\x1c\x03<\x00\x02\x01\x00\x1c\x03x\x00\x01\x01\x1c"
b"\x03\x14\x00\x01\x01\x1c\x03\x1e\x00\x01\x01\x1c\x08\n\x00\x00"
)
with Image.open(f) as im:
assert im.tile == [("iptc", (0, 0, 1, 1), 25, "raw")]


def test_getiptcinfo_jpg_none():
# Arrange
with hopper() as im:
Expand Down
4 changes: 4 additions & 0 deletions Tests/test_file_jpeg.py
Original file line number Diff line number Diff line change
Expand Up @@ -840,6 +840,10 @@ def test_ifd_offset_exif(self):
# Act / Assert
assert im._getexif()[306] == "2017:03:13 23:03:09"

def test_multiple_exif(self):
with Image.open("Tests/images/multiple_exif.jpg") as im:
assert im.info["exif"] == b"Exif\x00\x00firstsecond"

@mark_if_feature_version(
pytest.mark.valgrind_known_error, "libjpeg_turbo", "2.0", reason="Known Failing"
)
Expand Down
8 changes: 8 additions & 0 deletions Tests/test_file_tiff.py
Original file line number Diff line number Diff line change
Expand Up @@ -612,6 +612,14 @@ def test_roundtrip_tiff_uint16(self, tmp_path):

assert_image_equal_tofile(im, tmpfile)

def test_rowsperstrip(self, tmp_path):
outfile = str(tmp_path / "temp.tif")
im = hopper()
im.save(outfile, tiffinfo={278: 256})

with Image.open(outfile) as im:
assert im.tag_v2[278] == 256

def test_strip_raw(self):
infile = "Tests/images/tiff_strip_raw.tif"
with Image.open(infile) as im:
Expand Down
2 changes: 2 additions & 0 deletions Tests/test_file_tiff_metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ def test_write_metadata(tmp_path):
"""Test metadata writing through the python code"""
with Image.open("Tests/images/hopper.tif") as img:
f = str(tmp_path / "temp.tiff")
del img.tag[278]
img.save(f, tiffinfo=img.tag)

original = img.tag_v2.named()
Expand Down Expand Up @@ -159,6 +160,7 @@ def test_change_stripbytecounts_tag_type(tmp_path):
out = str(tmp_path / "temp.tiff")
with Image.open("Tests/images/hopper.tif") as im:
info = im.tag_v2
del info[278]

# Resize the image so that STRIPBYTECOUNTS will be larger than a SHORT
im = im.resize((500, 500))
Expand Down
5 changes: 5 additions & 0 deletions Tests/test_image.py
Original file line number Diff line number Diff line change
Expand Up @@ -1016,6 +1016,11 @@ def test_fli_overrun2(self):
except OSError as e:
assert str(e) == "buffer overrun when reading image file"

def test_exit_fp(self):
with Image.new("L", (1, 1)) as im:
pass
assert not hasattr(im, "fp")

def test_close_graceful(self, caplog):
with Image.open("Tests/images/hopper.jpg") as im:
copy = im.copy()
Expand Down
8 changes: 5 additions & 3 deletions Tests/test_imagefont.py
Original file line number Diff line number Diff line change
Expand Up @@ -1053,11 +1053,13 @@ def test_too_many_characters(font):
with pytest.raises(ValueError):
transposed_font.getlength("A" * 1_000_001)

default_font = ImageFont.load_default()
imagefont = ImageFont.ImageFont()
with pytest.raises(ValueError):
imagefont.getlength("A" * 1_000_001)
with pytest.raises(ValueError):
default_font.getlength("A" * 1_000_001)
imagefont.getbbox("A" * 1_000_001)
with pytest.raises(ValueError):
default_font.getbbox("A" * 1_000_001)
imagefont.getmask("A" * 1_000_001)


@pytest.mark.parametrize(
Expand Down
10 changes: 10 additions & 0 deletions Tests/test_imagemath.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,16 @@ def test_prevent_exec(expression):
ImageMath.eval(expression)


def test_prevent_double_underscores():
with pytest.raises(ValueError):
ImageMath.eval("1", {"__": None})


def test_prevent_builtins():
with pytest.raises(ValueError):
ImageMath.eval("(lambda: exec('exit()'))()", {"exec": None})


def test_logical():
assert pixel(ImageMath.eval("not A", images)) == 0
assert pixel(ImageMath.eval("A and B", images)) == "L 2"
Expand Down
2 changes: 1 addition & 1 deletion docs/COPYING
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ The Python Imaging Library (PIL) is

Pillow is the friendly PIL fork. It is

Copyright © 2010-2023 by Jeffrey A. Clark (Alex) and contributors
Copyright © 2010-2024 by Jeffrey A. Clark (Alex) and contributors

Like PIL, Pillow is licensed under the open source PIL
Software License:
Expand Down
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
# General information about the project.
project = "Pillow (PIL Fork)"
copyright = (
"1995-2011 Fredrik Lundh, 2010-2023 Jeffrey A. Clark (Alex) and contributors"
"1995-2011 Fredrik Lundh, 2010-2024 Jeffrey A. Clark (Alex) and contributors"
)
author = "Fredrik Lundh, Jeffrey A. Clark (Alex), contributors"

Expand Down
20 changes: 17 additions & 3 deletions docs/releasenotes/10.2.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,24 @@ output only the quantization and Huffman tables for the image.
Security
========

TODO
^^^^
ImageFont.getmask: Applied ImageFont.MAX_STRING_LENGTH
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

TODO
To protect against potential DOS attacks when using arbitrary strings as text input,
Pillow will now raise a :py:exc:`ValueError` if the number of characters passed into
:py:meth:`PIL.ImageFont.ImageFont.getmask` is over a certain limit,
:py:data:`PIL.ImageFont.MAX_STRING_LENGTH`.

This threshold can be changed by setting :py:data:`PIL.ImageFont.MAX_STRING_LENGTH`. It
can be disabled by setting ``ImageFont.MAX_STRING_LENGTH = None``.

ImageMath.eval: Restricted environment keys
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

:cve:`2023-50447`: If an attacker has control over the keys passed to the
``environment`` argument of :py:meth:`PIL.ImageMath.eval`, they may be able to execute
arbitrary code. To prevent this, keys matching the names of builtins and keys
containing double underscores will now raise a :py:exc:`ValueError`.

Other Changes
=============
Expand Down
2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,8 @@ extend-ignore = [

[tool.ruff.per-file-ignores]
"Tests/*.py" = ["I001"]
"Tests/oss-fuzz/fuzz_font.py" = ["I002"]
"Tests/oss-fuzz/fuzz_pillow.py" = ["I002"]

[tool.ruff.isort]
known-first-party = ["PIL"]
Expand Down
Loading

0 comments on commit 99760f4

Please sign in to comment.