Upgrade to 9.0.1

(cherry picked from commit ee0dfdc5b484162a6fffcf2905b38efa8029a0c4)
This commit is contained in:
starlet-dx 2022-08-29 18:28:21 +08:00 committed by openeuler-sync-bot
parent 773bec1207
commit ab2f92dbd8
30 changed files with 21 additions and 1740 deletions

View File

@ -1,43 +0,0 @@
From 5f4504bb03f4edeeef8c2633dc5ba03a4c2a8a97 Mon Sep 17 00:00:00 2001
From: Andrew Murray <radarhere@users.noreply.github.com>
Date: Tue, 15 Jun 2021 15:14:26 +1000
Subject: [PATCH] Limit sprintf modes to 10 characters
Conflict:NA
Reference:https://github.com/python-pillow/Pillow/commit/5f4504bb03f4edeeef8c2633dc5ba03a4c2a8a97
---
src/libImaging/Convert.c | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/src/libImaging/Convert.c b/src/libImaging/Convert.c
index b0b794d..64bbeee 100644
--- a/src/libImaging/Convert.c
+++ b/src/libImaging/Convert.c
@@ -1664,9 +1664,8 @@ convert(Imaging imOut, Imaging imIn, const char *mode,
#ifdef notdef
return (Imaging) ImagingError_ValueError("conversion not supported");
#else
- static char buf[256];
- /* FIXME: may overflow if mode is too large */
- sprintf(buf, "conversion from %s to %s not supported", imIn->mode, mode);
+ static char buf[100];
+ sprintf(buf, "conversion from %.10s to %.10s not supported", imIn->mode, mode);
return (Imaging) ImagingError_ValueError(buf);
#endif
}
@@ -1724,9 +1723,8 @@ ImagingConvertTransparent(Imaging imIn, const char *mode,
}
#else
{
- static char buf[256];
- /* FIXME: may overflow if mode is too large */
- sprintf(buf, "conversion from %s to %s not supported in convert_transparent", imIn->mode, mode);
+ static char buf[100];
+ sprintf(buf, "conversion from %.10s to %.10s not supported in convert_transparent", imIn->mode, mode);
return (Imaging) ImagingError_ValueError(buf);
}
#endif
--
2.27.0

View File

@ -1,41 +0,0 @@
From 1e092419b6806495c683043ab3feb6ce264f3b9c Mon Sep 17 00:00:00 2001
From: Andrew Murray <radarhere@users.noreply.github.com>
Date: Mon, 6 Dec 2021 22:24:19 +1100
Subject: [PATCH] Initialize coordinates to zero
Conflict:NA
Reference:https://github.com/python-pillow/Pillow/pull/5920/commits/1e092419b6806495c683043ab3feb6ce264f3b9c
---
Tests/test_imagepath.py | 1 +
src/path.c | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/Tests/test_imagepath.py b/Tests/test_imagepath.py
index 0835fdb..cd850bb 100644
--- a/Tests/test_imagepath.py
+++ b/Tests/test_imagepath.py
@@ -90,6 +90,7 @@ def test_path_odd_number_of_coordinates():
[
([0, 1, 2, 3], (0.0, 1.0, 2.0, 3.0)),
([3, 2, 1, 0], (1.0, 0.0, 3.0, 2.0)),
+ (1, (0.0, 0.0, 0.0, 0.0)),
],
)
def test_getbbox(coords, expected):
diff --git a/src/path.c b/src/path.c
index 62e7e15..60def3f 100644
--- a/src/path.c
+++ b/src/path.c
@@ -58,7 +58,7 @@ alloc_array(Py_ssize_t count)
if ((unsigned long long)count > (SIZE_MAX / (2 * sizeof(double))) - 1 ) {
return ImagingError_MemoryError();
}
- xy = malloc(2 * count * sizeof(double) + 1);
+ xy = calloc(2 * count * sizeof(double) + 1, sizeof(double));
if (!xy) {
ImagingError_MemoryError();
}
--
2.27.0

View File

@ -1,56 +0,0 @@
From 8531b01d6cdf0b70f256f93092caa2a5d91afc11 Mon Sep 17 00:00:00 2001
From: Andrew Murray <radarhere@users.noreply.github.com>
Date: Sun, 2 Jan 2022 17:23:49 +1100
Subject: [PATCH] Restrict builtins for ImageMath.eval
Conflict:NA
Reference:https://github.com/python-pillow/Pillow/pull/5923/commits/8531b01d6cdf0b70f256f93092caa2a5d91afc11
---
Tests/test_imagemath.py | 7 +++++++
src/PIL/ImageMath.py | 7 ++++++-
2 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/Tests/test_imagemath.py b/Tests/test_imagemath.py
index 2398067..8e87339 100644
--- a/Tests/test_imagemath.py
+++ b/Tests/test_imagemath.py
@@ -1,3 +1,5 @@
+import pytest
+
from PIL import Image, ImageMath
@@ -50,6 +52,11 @@ def test_ops():
assert pixel(ImageMath.eval("float(B)**33", images)) == "F 8589934592.0"
+def test_prevent_exec():
+ with pytest.raises(ValueError):
+ ImageMath.eval("exec('pass')")
+
+
def test_logical():
assert pixel(ImageMath.eval("not A", images)) == 0
assert pixel(ImageMath.eval("A and B", images)) == "L 2"
diff --git a/src/PIL/ImageMath.py b/src/PIL/ImageMath.py
index 7f9c88e..06bea80 100644
--- a/src/PIL/ImageMath.py
+++ b/src/PIL/ImageMath.py
@@ -246,7 +246,12 @@ def eval(expression, _dict={}, **kw):
if hasattr(v, "im"):
args[k] = _Operand(v)
- out = builtins.eval(expression, args)
+ code = compile(expression, "<string>", "eval")
+ for name in code.co_names:
+ if name not in args and name != "abs":
+ raise ValueError(f"'{name}' not allowed")
+
+ out = builtins.eval(expression, {"__builtins": {"abs": abs}}, args)
try:
return out.im
except AttributeError:
--
2.27.0

View File

@ -1,53 +0,0 @@
From 5cca90a37ce005498c80f4717ba67c5d8f45c540 Mon Sep 17 00:00:00 2001
From: mihail <mihail@shinder.ml>
Date: Mon, 20 Dec 2021 12:08:31 +0300
Subject: [PATCH] Add: XDGViewer which uses xdg-open
Synopsis
xdg-open { file | URL }
xdg-open { --help | --manual | --version }
Use 'man xdg-open' or 'xdg-open --manual' for additional info.
Conflict:NA
Reference:https://github.com/python-pillow/Pillow/commit/5cca90a37ce005498c80f4717ba67c5d8f45c540
---
src/PIL/ImageShow.py | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/src/PIL/ImageShow.py b/src/PIL/ImageShow.py
index 1ada825..137135e 100644
--- a/src/PIL/ImageShow.py
+++ b/src/PIL/ImageShow.py
@@ -186,6 +186,16 @@ class UnixViewer(Viewer):
os.remove(path)
return 1
+class XDGViewer(UnixViewer):
+ """
+ The freedesktop.org ``xdg-open`` command.
+ """
+
+ def get_command_ex(self, file, **options):
+ command = executable = "xdg-open"
+ return command, executable
+
+
class DisplayViewer(UnixViewer):
"""The ImageMagick ``display`` command."""
@@ -219,6 +229,8 @@ class XVViewer(UnixViewer):
if sys.platform not in ("win32", "darwin"): # unixoids
+ if shutil.which("xdg-open"):
+ register(XDGViewer)
if shutil.which("display"):
register(DisplayViewer)
if shutil.which("eog"):
--
2.27.0

View File

@ -1,37 +0,0 @@
From 518ee3722a99d7f7d890db82a20bd81c1c0327fb Mon Sep 17 00:00:00 2001
From: Andrew Murray <radarhere@users.noreply.github.com>
Date: Wed, 30 Jun 2021 23:47:10 +1000
Subject: [PATCH] Use snprintf instead of sprintf
Conflict:NA
Reference:https://github.com/python-pillow/Pillow/commit/518ee3722a99d7f7d890db82a20bd81c1c0327fb
---
src/libImaging/Convert.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/libImaging/Convert.c b/src/libImaging/Convert.c
index 64bbeee..28b952e 100644
--- a/src/libImaging/Convert.c
+++ b/src/libImaging/Convert.c
@@ -1665,7 +1665,7 @@ convert(Imaging imOut, Imaging imIn, const char *mode,
return (Imaging) ImagingError_ValueError("conversion not supported");
#else
static char buf[100];
- sprintf(buf, "conversion from %.10s to %.10s not supported", imIn->mode, mode);
+ snprintf(buf, 100, "conversion from %.10s to %.10s not supported", imIn->mode, mode);
return (Imaging) ImagingError_ValueError(buf);
#endif
}
@@ -1724,7 +1724,7 @@ ImagingConvertTransparent(Imaging imIn, const char *mode,
#else
{
static char buf[100];
- sprintf(buf, "conversion from %.10s to %.10s not supported in convert_transparent", imIn->mode, mode);
+ snprintf(buf, 100, "conversion from %.10s to %.10s not supported in convert_transparent", imIn->mode, mode);
return (Imaging) ImagingError_ValueError(buf);
}
#endif
--
2.27.0

View File

@ -1,73 +0,0 @@
From c48271ab354db49cdbd740bc45e13be4f0f7993c Mon Sep 17 00:00:00 2001
From: Andrew Murray <radarhere@users.noreply.github.com>
Date: Mon, 6 Dec 2021 22:25:14 +1100
Subject: [PATCH] Handle case where path count is zero
Conflict:NA
Reference:https://github.com/python-pillow/Pillow/pull/5920/commits/c48271ab354db49cdbd740bc45e13be4f0f7993c
---
Tests/test_imagepath.py | 1 +
src/path.c | 33 +++++++++++++++++++--------------
2 files changed, 20 insertions(+), 14 deletions(-)
diff --git a/Tests/test_imagepath.py b/Tests/test_imagepath.py
index cd850bb..b18271c 100644
--- a/Tests/test_imagepath.py
+++ b/Tests/test_imagepath.py
@@ -90,6 +90,7 @@ def test_path_odd_number_of_coordinates():
[
([0, 1, 2, 3], (0.0, 1.0, 2.0, 3.0)),
([3, 2, 1, 0], (1.0, 0.0, 3.0, 2.0)),
+ (0, (0.0, 0.0, 0.0, 0.0)),
(1, (0.0, 0.0, 0.0, 0.0)),
],
)
diff --git a/src/path.c b/src/path.c
index 60def3f..a2637b6 100644
--- a/src/path.c
+++ b/src/path.c
@@ -338,21 +338,26 @@ path_getbbox(PyPathObject* self, PyObject* args)
xy = self->xy;
- x0 = x1 = xy[0];
- y0 = y1 = xy[1];
+ if (self->count == 0) {
+ x0 = x1 = 0;
+ y0 = y1 = 0;
+ } else {
+ x0 = x1 = xy[0];
+ y0 = y1 = xy[1];
- for (i = 1; i < self->count; i++) {
- if (xy[i+i] < x0) {
- x0 = xy[i+i];
- }
- if (xy[i+i] > x1) {
- x1 = xy[i+i];
- }
- if (xy[i+i+1] < y0) {
- y0 = xy[i+i+1];
- }
- if (xy[i+i+1] > y1) {
- y1 = xy[i+i+1];
+ for (i = 1; i < self->count; i++) {
+ if (xy[i + i] < x0) {
+ x0 = xy[i + i];
+ }
+ if (xy[i + i] > x1) {
+ x1 = xy[i + i];
+ }
+ if (xy[i + i + 1] < y0) {
+ y0 = xy[i + i + 1];
+ }
+ if (xy[i + i + 1] > y1) {
+ y1 = xy[i + i + 1];
+ }
}
}
--
2.27.0

View File

@ -1,47 +0,0 @@
From 6790f1869a357b7da1d7bae006d32e14821fea5d Mon Sep 17 00:00:00 2001
From: Felipe Rosa de Almeida <feliperalmeida@users.noreply.github.com>
Date: Sun, 16 Jan 2022 19:11:21 -0300
Subject: [PATCH] Forbid lambda expressions in ImageMath.eval()
Conflict:NA
Reference:https://github.com/python-pillow/Pillow/pull/5963/commits/6790f1869a357b7da1d7bae006d32e14821fea5d
---
Tests/test_imagemath.py | 5 +++--
src/PIL/ImageMath.py | 3 +++
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/Tests/test_imagemath.py b/Tests/test_imagemath.py
index 8e87339..7bce9e9 100644
--- a/Tests/test_imagemath.py
+++ b/Tests/test_imagemath.py
@@ -52,9 +52,10 @@ def test_ops():
assert pixel(ImageMath.eval("float(B)**33", images)) == "F 8589934592.0"
-def test_prevent_exec():
+@pytest.mark.parametrize("expression", ("exec('pass')", "(lambda: None)()"))
+def test_prevent_exec(expression):
with pytest.raises(ValueError):
- ImageMath.eval("exec('pass')")
+ ImageMath.eval(expression)
def test_logical():
diff --git a/src/PIL/ImageMath.py b/src/PIL/ImageMath.py
index 06bea80..64f9c5c 100644
--- a/src/PIL/ImageMath.py
+++ b/src/PIL/ImageMath.py
@@ -250,6 +250,9 @@ def eval(expression, _dict={}, **kw):
for name in code.co_names:
if name not in args and name != "abs":
raise ValueError(f"'{name}' not allowed")
+ for const in code.co_consts:
+ if getattr(const, "co_name", None) == "<lambda>":
+ raise ValueError("Lambda expressions are not allowed")
out = builtins.eval(expression, {"__builtins": {"abs": abs}}, args)
try:
--
2.27.0

View File

@ -1,142 +0,0 @@
From 86944abbabad62e53e644bd7375b9a56d66c1675 Mon Sep 17 00:00:00 2001
From: Andrew Murray <radarhere@users.noreply.github.com>
Date: Sat, 15 Jan 2022 16:08:37 +1100
Subject: [PATCH] Deprecated show_file "file" argument in favour of "path"
Conflict:NA
Reference:https://github.com/python-pillow/Pillow/commit/86944abbabad62e53e644bd7375b9a56d66c1675
---
Tests/test_imageshow.py | 15 +++++++++++
src/PIL/ImageShow.py | 59 +++++++++++++++++++++++++++++++----------
2 files changed, 60 insertions(+), 14 deletions(-)
diff --git a/Tests/test_imageshow.py b/Tests/test_imageshow.py
index 78e80f5..f79a531 100644
--- a/Tests/test_imageshow.py
+++ b/Tests/test_imageshow.py
@@ -63,3 +63,18 @@ def test_viewer():
def test_viewers():
for viewer in ImageShow._viewers:
viewer.get_command("test.jpg")
+
+
+@pytest.mark.skipif(
+ not on_ci() or is_win32(),
+ reason="Only run on CIs; hangs on Windows CIs",
+)
+def test_file_deprecated():
+ for viewer in ImageShow._viewers:
+ with pytest.warns(DeprecationWarning):
+ try:
+ viewer.show_file(file="test.jpg")
+ except NotImplementedError:
+ pass
+ with pytest.raises(TypeError):
+ viewer.show_file()
diff --git a/src/PIL/ImageShow.py b/src/PIL/ImageShow.py
index 137135e..b3b9a5b 100644
--- a/src/PIL/ImageShow.py
+++ b/src/PIL/ImageShow.py
@@ -16,6 +16,7 @@ import shutil
import subprocess
import sys
import tempfile
+import warnings
from shlex import quote
from PIL import Image
@@ -106,9 +107,19 @@ class Viewer:
"""Display the given image."""
return self.show_file(self.save_image(image), **options)
- def show_file(self, file, **options):
- """Display the given file."""
- os.system(self.get_command(file, **options))
+ def show_file(self, path=None, **options):
+ """Display given file."""
+ if path is None:
+ if "file" in options:
+ warnings.warn(
+ "The 'file' argument is deprecated and will be removed in Pillow "
+ "10 (2023-07-01). Use 'path' instead.",
+ DeprecationWarning,
+ )
+ path = options.pop("file")
+ else:
+ raise TypeError("Missing required argument: 'path'")
+ os.system(self.get_command(path, **options))
return 1
@@ -146,18 +157,28 @@ class MacViewer(Viewer):
command = f"({command} {quote(file)}; sleep 20; rm -f {quote(file)})&"
return command
- def show_file(self, file, **options):
+ def show_file(self, path=None, **options):
"""Display given file"""
- fd, path = tempfile.mkstemp()
+ if path is None:
+ if "file" in options:
+ warnings.warn(
+ "The 'file' argument is deprecated and will be removed in Pillow "
+ "10 (2023-07-01). Use 'path' instead.",
+ DeprecationWarning,
+ )
+ path = options.pop("file")
+ else:
+ raise TypeError("Missing required argument: 'path'")
+ fd, temp_path = tempfile.mkstemp()
with os.fdopen(fd, "w") as f:
- f.write(file)
- with open(path) as f:
+ f.write(path)
+ with open(temp_path) as f:
subprocess.Popen(
["im=$(cat); open -a Preview.app $im; sleep 20; rm -f $im"],
shell=True,
stdin=f,
)
- os.remove(path)
+ os.remove(temp_path)
return 1
@@ -173,17 +194,27 @@ class UnixViewer(Viewer):
command = self.get_command_ex(file, **options)[0]
return f"({command} {quote(file)}; rm -f {quote(file)})&"
- def show_file(self, file, **options):
+ def show_file(self, path=None, **options):
"""Display given file"""
- fd, path = tempfile.mkstemp()
+ if path is None:
+ if "file" in options:
+ warnings.warn(
+ "The 'file' argument is deprecated and will be removed in Pillow "
+ "10 (2023-07-01). Use 'path' instead.",
+ DeprecationWarning,
+ )
+ path = options.pop("file")
+ else:
+ raise TypeError("Missing required argument: 'path'")
+ fd, temp_path = tempfile.mkstemp()
with os.fdopen(fd, "w") as f:
- f.write(file)
- with open(path) as f:
- command = self.get_command_ex(file, **options)[0]
+ f.write(path)
+ with open(temp_path) as f:
+ command = self.get_command_ex(path, **options)[0]
subprocess.Popen(
["im=$(cat);" + command + " $im; rm -f $im"], shell=True, stdin=f
)
- os.remove(path)
+ os.remove(temp_path)
return 1
class XDGViewer(UnixViewer):
--
2.27.0

View File

@ -1,28 +0,0 @@
From fe32501922ef5e1be9a7d307132719bd5d52ca35 Mon Sep 17 00:00:00 2001
From: Andrew Murray <radarhere@users.noreply.github.com>
Date: Fri, 14 Jan 2022 10:16:35 +1100
Subject: [PATCH] Corrected allocation
Conflict:NA
Reference:https://github.com/python-pillow/Pillow/pull/5958/commits/fe32501922ef5e1be9a7d307132719bd5d52ca35
---
src/path.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/path.c b/src/path.c
index a2637b6..d63ae40 100644
--- a/src/path.c
+++ b/src/path.c
@@ -58,7 +58,7 @@ alloc_array(Py_ssize_t count)
if ((unsigned long long)count > (SIZE_MAX / (2 * sizeof(double))) - 1 ) {
return ImagingError_MemoryError();
}
- xy = calloc(2 * count * sizeof(double) + 1, sizeof(double));
+ xy = calloc(2 * count + 1, sizeof(double));
if (!xy) {
ImagingError_MemoryError();
}
--
2.27.0

View File

@ -1,215 +0,0 @@
From 8da80130dbc747f3954b4904247d26289fe722f9 Mon Sep 17 00:00:00 2001
From: Andrew Murray <radarhere@users.noreply.github.com>
Date: Mon, 17 Jan 2022 08:59:17 +1100
Subject: [PATCH] In show_file, use os.remove to remove temporary images
Conflict:NA
Reference:https://github.com/python-pillow/Pillow/pull/6010/commits/8da80130dbc747f3954b4904247d26289fe722f9
---
Tests/test_imageshow.py | 6 +-
src/PIL/ImageShow.py | 124 ++++++++++++++++++++++++++++++----------
2 files changed, 98 insertions(+), 32 deletions(-)
diff --git a/Tests/test_imageshow.py b/Tests/test_imageshow.py
index f79a531..5983ebf 100644
--- a/Tests/test_imageshow.py
+++ b/Tests/test_imageshow.py
@@ -69,11 +69,13 @@ def test_viewers():
not on_ci() or is_win32(),
reason="Only run on CIs; hangs on Windows CIs",
)
-def test_file_deprecated():
+def test_file_deprecated(tmp_path):
+ f = str(tmp_path / "temp.jpg")
for viewer in ImageShow._viewers:
+ hopper().save(f)
with pytest.warns(DeprecationWarning):
try:
- viewer.show_file(file="test.jpg")
+ viewer.show_file(file=f)
except NotImplementedError:
pass
with pytest.raises(TypeError):
diff --git a/src/PIL/ImageShow.py b/src/PIL/ImageShow.py
index b3b9a5b..e4eb2f8 100644
--- a/src/PIL/ImageShow.py
+++ b/src/PIL/ImageShow.py
@@ -15,7 +15,6 @@ import os
import shutil
import subprocess
import sys
-import tempfile
import warnings
from shlex import quote
@@ -169,16 +168,15 @@ class MacViewer(Viewer):
path = options.pop("file")
else:
raise TypeError("Missing required argument: 'path'")
- fd, temp_path = tempfile.mkstemp()
- with os.fdopen(fd, "w") as f:
- f.write(path)
- with open(temp_path) as f:
- subprocess.Popen(
- ["im=$(cat); open -a Preview.app $im; sleep 20; rm -f $im"],
- shell=True,
- stdin=f,
- )
- os.remove(temp_path)
+ subprocess.call(["open", "-a", "Preview.app", path])
+ subprocess.Popen(
+ [
+ sys.executable,
+ "-c",
+ "import os, sys, time;time.sleep(20);os.remove(sys.argv[1])",
+ path,
+ ]
+ )
return 1
@@ -194,6 +192,16 @@ class UnixViewer(Viewer):
command = self.get_command_ex(file, **options)[0]
return f"({command} {quote(file)}; rm -f {quote(file)})&"
+
+class XDGViewer(UnixViewer):
+ """
+ The freedesktop.org ``xdg-open`` command.
+ """
+
+ def get_command_ex(self, file, **options):
+ command = executable = "xdg-open"
+ return command, executable
+
def show_file(self, path=None, **options):
"""Display given file"""
if path is None:
@@ -206,27 +214,10 @@ class UnixViewer(Viewer):
path = options.pop("file")
else:
raise TypeError("Missing required argument: 'path'")
- fd, temp_path = tempfile.mkstemp()
- with os.fdopen(fd, "w") as f:
- f.write(path)
- with open(temp_path) as f:
- command = self.get_command_ex(path, **options)[0]
- subprocess.Popen(
- ["im=$(cat);" + command + " $im; rm -f $im"], shell=True, stdin=f
- )
- os.remove(temp_path)
+ subprocess.Popen(["xdg-open", path])
+ os.remove(path)
return 1
-class XDGViewer(UnixViewer):
- """
- The freedesktop.org ``xdg-open`` command.
- """
-
- def get_command_ex(self, file, **options):
- command = executable = "xdg-open"
- return command, executable
-
-
class DisplayViewer(UnixViewer):
"""The ImageMagick ``display`` command."""
@@ -235,6 +226,32 @@ class DisplayViewer(UnixViewer):
command = executable = "display"
return command, executable
+ def show_file(self, path=None, **options):
+ """
+ Display given file.
+
+ Before Pillow 9.1.0, the first argument was ``file``. This is now deprecated,
+ and ``path`` should be used instead.
+ """
+ if path is None:
+ if "file" in options:
+ warnings.warn(
+ "The 'file' argument is deprecated and will be removed in Pillow "
+ "10 (2023-07-01). Use 'path' instead.",
+ DeprecationWarning,
+ )
+ path = options.pop("file")
+ else:
+ raise TypeError("Missing required argument: 'path'")
+ args = ["display"]
+ if "title" in options:
+ args += ["-name", options["title"]]
+ args.append(path)
+
+ subprocess.Popen(args)
+ os.remove(path)
+ return 1
+
class EogViewer(UnixViewer):
"""The GNOME Image Viewer ``eog`` command."""
@@ -243,6 +260,27 @@ class EogViewer(UnixViewer):
command = executable = "eog"
return command, executable
+ def show_file(self, path=None, **options):
+ """
+ Display given file.
+
+ Before Pillow 9.1.0, the first argument was ``file``. This is now deprecated,
+ and ``path`` should be used instead.
+ """
+ if path is None:
+ if "file" in options:
+ warnings.warn(
+ "The 'file' argument is deprecated and will be removed in Pillow "
+ "10 (2023-07-01). Use 'path' instead.",
+ DeprecationWarning,
+ )
+ path = options.pop("file")
+ else:
+ raise TypeError("Missing required argument: 'path'")
+ subprocess.Popen(["eog", "-n", path])
+ os.remove(path)
+ return 1
+
class XVViewer(UnixViewer):
"""
@@ -258,6 +296,32 @@ class XVViewer(UnixViewer):
command += f" -name {quote(title)}"
return command, executable
+ def show_file(self, path=None, **options):
+ """
+ Display given file.
+
+ Before Pillow 9.1.0, the first argument was ``file``. This is now deprecated,
+ and ``path`` should be used instead.
+ """
+ if path is None:
+ if "file" in options:
+ warnings.warn(
+ "The 'file' argument is deprecated and will be removed in Pillow "
+ "10 (2023-07-01). Use 'path' instead.",
+ DeprecationWarning,
+ )
+ path = options.pop("file")
+ else:
+ raise TypeError("Missing required argument: 'path'")
+ args = ["xv"]
+ if "title" in options:
+ args += ["-name", options["title"]]
+ args.append(path)
+
+ subprocess.Popen(args)
+ os.remove(path)
+ return 1
+
if sys.platform not in ("win32", "darwin"): # unixoids
if shutil.which("xdg-open"):
--
2.27.0

View File

@ -1,30 +0,0 @@
From 143032103c9f2d55a0a7960bd3e630cb72549e8a Mon Sep 17 00:00:00 2001
From: Andrew Murray <3112309+radarhere@users.noreply.github.com>
Date: Tue, 18 Jan 2022 11:24:01 +1100
Subject: [PATCH] Updated formatting
Co-authored-by: Hugo van Kemenade <hugovk@users.noreply.github.com>
Conflict:NA
Reference:https://github.com/python-pillow/Pillow/pull/6010/commits/143032103c9f2d55a0a7960bd3e630cb72549e8a
---
src/PIL/ImageShow.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/PIL/ImageShow.py b/src/PIL/ImageShow.py
index e4eb2f8..429f9bd 100644
--- a/src/PIL/ImageShow.py
+++ b/src/PIL/ImageShow.py
@@ -173,7 +173,7 @@ class MacViewer(Viewer):
[
sys.executable,
"-c",
- "import os, sys, time;time.sleep(20);os.remove(sys.argv[1])",
+ "import os, sys, time; time.sleep(20); os.remove(sys.argv[1])",
path,
]
)
--
2.27.0

View File

@ -1,61 +0,0 @@
From 10c4f75aaa383bd9671e923e3b91d391ea12d781 Mon Sep 17 00:00:00 2001
From: Andrew Murray <radarhere@users.noreply.github.com>
Date: Thu, 3 Feb 2022 08:58:12 +1100
Subject: [PATCH] Added delay after opening image with xdg-open
Conflict:NA
Reference:https://github.com/python-pillow/Pillow/pull/6010/commits/10c4f75aaa383bd9671e923e3b91d391ea12d781
---
src/PIL/ImageShow.py | 21 ++++++++++++---------
1 file changed, 12 insertions(+), 9 deletions(-)
diff --git a/src/PIL/ImageShow.py b/src/PIL/ImageShow.py
index 429f9bd..312faad 100644
--- a/src/PIL/ImageShow.py
+++ b/src/PIL/ImageShow.py
@@ -121,6 +121,16 @@ class Viewer:
os.system(self.get_command(path, **options))
return 1
+ def _remove_path_after_delay(self, path):
+ subprocess.Popen(
+ [
+ sys.executable,
+ "-c",
+ "import os, sys, time; time.sleep(20); os.remove(sys.argv[1])",
+ path,
+ ]
+ )
+
# --------------------------------------------------------------------
@@ -169,14 +179,7 @@ class MacViewer(Viewer):
else:
raise TypeError("Missing required argument: 'path'")
subprocess.call(["open", "-a", "Preview.app", path])
- subprocess.Popen(
- [
- sys.executable,
- "-c",
- "import os, sys, time; time.sleep(20); os.remove(sys.argv[1])",
- path,
- ]
- )
+ self._remove_path_after_delay(path)
return 1
@@ -215,7 +218,7 @@ class XDGViewer(UnixViewer):
else:
raise TypeError("Missing required argument: 'path'")
subprocess.Popen(["xdg-open", path])
- os.remove(path)
+ self._remove_path_after_delay(path)
return 1
--
2.27.0

View File

@ -1,42 +0,0 @@
From 1dc6564eb7ee8f28fb16eeffaf3572f3e1d5aa29 Mon Sep 17 00:00:00 2001
From: Hugo van Kemenade <hugovk@users.noreply.github.com>
Date: Mon, 23 Aug 2021 19:10:49 +0300
Subject: [PATCH] Raise ValueError if color specifier is too long
Conflict:NA
Reference:https://github.com/python-pillow/Pillow/commit/1dc6564eb7ee8f28fb16eeffaf3572f3e1d5aa29
----
Tests/test_imagecolor.py | 9 +++++++++
src/PIL/ImageColor.py | 2 ++
2 files changed, 11 insertions(+)
diff --git a/Tests/test_imagecolor.py b/Tests/test_imagecolor.py
index b5d6937965..dbe8b9e957 100644
--- a/Tests/test_imagecolor.py
+++ b/Tests/test_imagecolor.py
@@ -191,3 +191,12 @@ def test_rounding_errors():
assert (255, 255) == ImageColor.getcolor("white", "LA")
assert (163, 33) == ImageColor.getcolor("rgba(0, 255, 115, 33)", "LA")
Image.new("LA", (1, 1), "white")
+
+
+def test_color_too_long():
+ # Arrange
+ color_too_long = "hsl(" + "1" * 100 + ")"
+
+ # Act / Assert
+ with pytest.raises(ValueError):
+ ImageColor.getrgb(color_too_long)
diff --git a/src/PIL/ImageColor.py b/src/PIL/ImageColor.py
index 51df440403..25f92f2c73 100644
--- a/src/PIL/ImageColor.py
+++ b/src/PIL/ImageColor.py
@@ -32,6 +32,8 @@ def getrgb(color):
:param color: A color string
:return: ``(red, green, blue[, alpha])``
"""
+ if len(color) > 100:
+ raise ValueError("color specifier is too long")
color = color.lower()
rgb = colormap.get(color, None)

View File

@ -1,75 +0,0 @@
From 3bf5eddb89afdf690eceaa52bc4d3546ba9a5f87 Mon Sep 17 00:00:00 2001
From: Eric Soroos <eric-github@soroos.net>
Date: Sun, 7 Mar 2021 12:32:12 +0100
Subject: [PATCH] Fix OOB Read in Jpeg2KDecode CVE-2021-25287,CVE-2021-25288
Conflict:NA
Reference:https://github.com/python-pillow/Pillow/commit/3bf5eddb89afdf690eceaa52bc4d3546ba9a5f87
---
src/libImaging/Jpeg2KDecode.c | 33 +++++++++++++++++++++++++--------
1 file changed, 25 insertions(+), 8 deletions(-)
diff --git a/src/libImaging/Jpeg2KDecode.c b/src/libImaging/Jpeg2KDecode.c
index 8cce545..60d4d77 100644
--- a/src/libImaging/Jpeg2KDecode.c
+++ b/src/libImaging/Jpeg2KDecode.c
@@ -589,7 +589,7 @@ j2k_decode_entry(Imaging im, ImagingCodecState state)
j2k_unpacker_t unpack = NULL;
size_t buffer_size = 0, tile_bytes = 0;
unsigned n, tile_height, tile_width;
- int components;
+ int total_component_width = 0;
stream = opj_stream_create(BUFFER_SIZE, OPJ_TRUE);
@@ -753,23 +753,40 @@ j2k_decode_entry(Imaging im, ImagingCodecState state)
goto quick_exit;
}
+ if (tile_info.nb_comps != image->numcomps) {
+ state->errcode = IMAGING_CODEC_BROKEN;
+ state->state = J2K_STATE_FAILED;
+ goto quick_exit;
+ }
+
/* Sometimes the tile_info.datasize we get back from openjpeg
- is less than numcomps*w*h, and we overflow in the
+ is less than sum(comp_bytes)*w*h, and we overflow in the
shuffle stage */
tile_width = tile_info.x1 - tile_info.x0;
tile_height = tile_info.y1 - tile_info.y0;
- components = tile_info.nb_comps == 3 ? 4 : tile_info.nb_comps;
- if (( tile_width > UINT_MAX / components ) ||
- ( tile_height > UINT_MAX / components ) ||
- ( tile_width > UINT_MAX / (tile_height * components )) ||
- ( tile_height > UINT_MAX / (tile_width * components ))) {
+
+ /* Total component width = sum (component_width) e.g, it's
+ legal for an la file to have a 1 byte width for l, and 4 for
+ a. and then a malicious file could have a smaller tile_bytes
+ */
+
+ for (n=0; n < tile_info.nb_comps; n++) {
+ // see csize /acsize calcs
+ int csize = (image->comps[n].prec + 7) >> 3;
+ csize = (csize == 3) ? 4 : csize;
+ total_component_width += csize;
+ }
+ if ((tile_width > UINT_MAX / total_component_width) ||
+ (tile_height > UINT_MAX / total_component_width) ||
+ (tile_width > UINT_MAX / (tile_height * total_component_width)) ||
+ (tile_height > UINT_MAX / (tile_width * total_component_width))) {
state->errcode = IMAGING_CODEC_BROKEN;
state->state = J2K_STATE_FAILED;
goto quick_exit;
}
- tile_bytes = tile_width * tile_height * components;
+ tile_bytes = tile_width * tile_height * total_component_width;
if (tile_bytes > tile_info.data_size) {
tile_info.data_size = tile_bytes;
--
2.23.0

View File

@ -1,68 +0,0 @@
From 480f6819b592d7f07b9a9a52a7656c10bbe07442 Mon Sep 17 00:00:00 2001
From: Eric Soroos <eric-github@soroos.net>
Date: Wed, 24 Feb 2021 23:27:07 +0100
Subject: [PATCH] Fix Memory DOS in Icns, Ico and Blp Image Plugins
Some container plugins that could contain images of other formats,
such as the ICNS format, did not properly check the reported size of
the contained image. These images could cause arbitrariliy large
memory allocations.
This is fixed for all locations where individual *ImageFile classes
are created without going through the usual Image.open method.
Conflict:NA
Reference:https://github.com/python-pillow/Pillow/commit/480f6819b592d7f07b9a9a52a7656c10bbe07442
---
src/PIL/BlpImagePlugin.py | 1 +
src/PIL/IcnsImagePlugin.py | 2 ++
src/PIL/IcoImagePlugin.py | 1 +
3 files changed, 4 insertions(+)
diff --git a/src/PIL/BlpImagePlugin.py b/src/PIL/BlpImagePlugin.py
index d5d7c0e..88aae80 100644
--- a/src/PIL/BlpImagePlugin.py
+++ b/src/PIL/BlpImagePlugin.py
@@ -353,6 +353,7 @@ class BLP1Decoder(_BLPBaseDecoder):
data = jpeg_header + data
data = BytesIO(data)
image = JpegImageFile(data)
+ Image._decompression_bomb_check(image.size)
self.tile = image.tile # :/
self.fd = image.fp
self.mode = image.mode
diff --git a/src/PIL/IcnsImagePlugin.py b/src/PIL/IcnsImagePlugin.py
index 2a63d75..ca6a0ad 100644
--- a/src/PIL/IcnsImagePlugin.py
+++ b/src/PIL/IcnsImagePlugin.py
@@ -105,6 +105,7 @@ def read_png_or_jpeg2000(fobj, start_length, size):
if sig[:8] == b"\x89PNG\x0d\x0a\x1a\x0a":
fobj.seek(start)
im = PngImagePlugin.PngImageFile(fobj)
+ Image._decompression_bomb_check(im.size)
return {"RGBA": im}
elif (
sig[:4] == b"\xff\x4f\xff\x51"
@@ -121,6 +122,7 @@ def read_png_or_jpeg2000(fobj, start_length, size):
jp2kstream = fobj.read(length)
f = io.BytesIO(jp2kstream)
im = Jpeg2KImagePlugin.Jpeg2KImageFile(f)
+ Image._decompression_bomb_check(im.size)
if im.mode != "RGBA":
im = im.convert("RGBA")
return {"RGBA": im}
diff --git a/src/PIL/IcoImagePlugin.py b/src/PIL/IcoImagePlugin.py
index e1bfa7a..5634bf8 100644
--- a/src/PIL/IcoImagePlugin.py
+++ b/src/PIL/IcoImagePlugin.py
@@ -178,6 +178,7 @@ class IcoFile:
if data[:8] == PngImagePlugin._MAGIC:
# png frame
im = PngImagePlugin.PngImageFile(self.buf)
+ Image._decompression_bomb_check(im.size)
else:
# XOR + AND mask bmp frame
im = BmpImagePlugin.DibImageFile(self.buf)
--
2.27.0

View File

@ -1,197 +0,0 @@
From 22e9bee4ef225c0edbb9323f94c26cee0c623497 Mon Sep 17 00:00:00 2001
From: Eric Soroos <eric-github@soroos.net>
Date: Sun, 7 Mar 2021 19:04:25 +0100
Subject: [PATCH] Fix DOS in PSDImagePlugin -- CVE-2021-28675
Conflict:NA
Reference:https://github.com/python-pillow/Pillow/commit/22e9bee4ef225c0edbb9323f94c26cee0c623497
---
Tests/test_decompression_bomb.py | 1 +
Tests/test_file_apng.py | 2 +-
Tests/test_file_blp.py | 1 +
Tests/test_file_tiff.py | 6 ++++--
src/PIL/ImageFile.py | 14 ++++++++++++--
src/PIL/PsdImagePlugin.py | 32 +++++++++++++++++++++-----------
6 files changed, 40 insertions(+), 16 deletions(-)
diff --git a/Tests/test_decompression_bomb.py b/Tests/test_decompression_bomb.py
index 7671cdc..f96a15a 100644
--- a/Tests/test_decompression_bomb.py
+++ b/Tests/test_decompression_bomb.py
@@ -52,6 +52,7 @@ class TestDecompressionBomb:
with Image.open(TEST_FILE):
pass
+ @pytest.mark.xfail(reason="different exception")
def test_exception_ico(self):
with pytest.raises(Image.DecompressionBombError):
Image.open("Tests/images/decompression_bomb.ico")
diff --git a/Tests/test_file_apng.py b/Tests/test_file_apng.py
index 97e2a15..8348da4 100644
--- a/Tests/test_file_apng.py
+++ b/Tests/test_file_apng.py
@@ -312,7 +312,7 @@ def test_apng_syntax_errors():
exception = e
assert exception is None
- with pytest.raises(SyntaxError):
+ with pytest.raises(OSError):
with Image.open("Tests/images/apng/syntax_num_frames_high.png") as im:
im.seek(im.n_frames - 1)
im.load()
diff --git a/Tests/test_file_blp.py b/Tests/test_file_blp.py
index 94c469c..1510614 100644
--- a/Tests/test_file_blp.py
+++ b/Tests/test_file_blp.py
@@ -1,4 +1,5 @@
from PIL import Image
+import pytest
from .helper import assert_image_equal
diff --git a/Tests/test_file_tiff.py b/Tests/test_file_tiff.py
index bb1bbda..1500ac8 100644
--- a/Tests/test_file_tiff.py
+++ b/Tests/test_file_tiff.py
@@ -612,8 +612,10 @@ class TestFileTiff:
)
def test_string_dimension(self):
# Assert that an error is raised if one of the dimensions is a string
- with pytest.raises(ValueError):
- Image.open("Tests/images/string_dimension.tiff")
+ with pytest.raises(OSError):
+ with Image.open("Tests/images/string_dimension.tiff") as im:
+ im.load()
+
@pytest.mark.skipif(not is_win32(), reason="Windows only")
diff --git a/src/PIL/ImageFile.py b/src/PIL/ImageFile.py
index f2a55cb..468314b 100644
--- a/src/PIL/ImageFile.py
+++ b/src/PIL/ImageFile.py
@@ -555,12 +555,18 @@ def _safe_read(fp, size):
:param fp: File handle. Must implement a <b>read</b> method.
:param size: Number of bytes to read.
- :returns: A string containing up to <i>size</i> bytes of data.
+ :returns: A string containing <i>size</i> bytes of data.
+
+ Raises an OSError if the file is truncated and the read can not be completed
+
"""
if size <= 0:
return b""
if size <= SAFEBLOCK:
- return fp.read(size)
+ data = fp.read(size)
+ if len(data) < size:
+ raise OSError("Truncated File Read")
+ return data
data = []
while size > 0:
block = fp.read(min(size, SAFEBLOCK))
@@ -568,9 +574,13 @@ def _safe_read(fp, size):
break
data.append(block)
size -= len(block)
+ if sum(len(d) for d in data) < size:
+ raise OSError("Truncated File Read")
return b"".join(data)
+
+
class PyCodecState:
def __init__(self):
self.xsize = 0
diff --git a/src/PIL/PsdImagePlugin.py b/src/PIL/PsdImagePlugin.py
index d3799ed..96de58f 100644
--- a/src/PIL/PsdImagePlugin.py
+++ b/src/PIL/PsdImagePlugin.py
@@ -119,7 +119,8 @@ class PsdImageFile(ImageFile.ImageFile):
end = self.fp.tell() + size
size = i32(read(4))
if size:
- self.layers = _layerinfo(self.fp)
+ _layer_data = io.BytesIO(ImageFile._safe_read(self.fp, size))
+ self.layers = _layerinfo(_layer_data, size)
self.fp.seek(end)
self.n_frames = len(self.layers)
self.is_animated = self.n_frames > 1
@@ -170,12 +171,20 @@ class PsdImageFile(ImageFile.ImageFile):
finally:
self.__fp = None
-
-def _layerinfo(file):
+def _layerinfo(fp, ct_bytes):
# read layerinfo block
layers = []
- read = file.read
- for i in range(abs(i16(read(2)))):
+
+ def read(size):
+ return ImageFile._safe_read(fp, size)
+
+ ct = i16(read(2))
+
+ # sanity check
+ if ct_bytes < (abs(ct) * 20):
+ raise SyntaxError("Layer block too short for number of layers requested")
+
+ for i in range(abs(ct)):
# bounding box
y0 = i32(read(4))
@@ -186,7 +195,8 @@ def _layerinfo(file):
# image info
info = []
mode = []
- types = list(range(i16(read(2))))
+ ct_types = i16(read(2))
+ types = list(range(ct_types))
if len(types) > 4:
continue
@@ -219,16 +229,16 @@ def _layerinfo(file):
size = i32(read(4)) # length of the extra data field
combined = 0
if size:
- data_end = file.tell() + size
+ data_end = fp.tell() + size
length = i32(read(4))
if length:
- file.seek(length - 16, io.SEEK_CUR)
+ fp.seek(length - 16, io.SEEK_CUR)
combined += length + 4
length = i32(read(4))
if length:
- file.seek(length, io.SEEK_CUR)
+ fp.seek(length, io.SEEK_CUR)
combined += length + 4
length = i8(read(1))
@@ -238,7 +248,7 @@ def _layerinfo(file):
name = read(length).decode("latin-1", "replace")
combined += length + 1
- file.seek(data_end)
+ fp.seek(data_end)
layers.append((name, mode, (x0, y0, x1, y1)))
# get tiles
@@ -246,7 +256,7 @@ def _layerinfo(file):
for name, mode, bbox in layers:
tile = []
for m in mode:
- t = _maketile(file, m, bbox, 1)
+ t = _maketile(fp, m, bbox, 1)
if t:
tile.extend(t)
layers[i] = name, mode, bbox, tile
--
2.23.0

View File

@ -1,30 +0,0 @@
From bb6c11fb889e6c11b0ee122b828132ee763b5856 Mon Sep 17 00:00:00 2001
From: Eric Soroos <eric-github@soroos.net>
Date: Thu, 11 Mar 2021 22:12:35 +0100
Subject: [PATCH] Fix FLI DOS -- CVE-2021-28676
Conflict:NA
Reference:https://github.com/python-pillow/Pillow/commit/bb6c11fb889e6c11b0ee122b828132ee763b5856
---
src/libImaging/FliDecode.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/src/libImaging/FliDecode.c b/src/libImaging/FliDecode.c
index 8450801..b8bc5ce 100644
--- a/src/libImaging/FliDecode.c
+++ b/src/libImaging/FliDecode.c
@@ -242,6 +242,11 @@ ImagingFliDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
return -1;
}
advance = I32(ptr);
+ if (advance == 0 ) {
+ // If there's no advance, we're in in infinite loop
+ state->errcode = IMAGING_CODEC_BROKEN;
+ return -1;
+ }
if (advance < 0 || advance > bytes) {
state->errcode = IMAGING_CODEC_OVERRUN;
return -1;
--
2.23.0

View File

@ -1,43 +0,0 @@
From 5a5e6db0abf4e7a638fb1b3408c4e495a096cb92 Mon Sep 17 00:00:00 2001
From: Eric Soroos <eric-github@soroos.net>
Date: Mon, 8 Mar 2021 20:31:41 +0100
Subject: [PATCH] Fix EPS DOS on _open -- CVE-2021-28677
Conflict:NA
Reference:https://github.com/python-pillow/Pillow/commit/5a5e6db0abf4e7a638fb1b3408c4e495a096cb92
---
src/PIL/EpsImagePlugin.py | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/PIL/EpsImagePlugin.py b/src/PIL/EpsImagePlugin.py
index dc61f48..3bf8ee0 100644
--- a/src/PIL/EpsImagePlugin.py
+++ b/src/PIL/EpsImagePlugin.py
@@ -170,12 +170,12 @@ class PSFile:
self.fp.seek(offset, whence)
def readline(self):
- s = self.char or b""
+ s = [self.char or b""]
self.char = None
c = self.fp.read(1)
- while c not in b"\r\n":
- s = s + c
+ while (c not in b"\r\n") and len(c):
+ s.append(c)
c = self.fp.read(1)
self.char = self.fp.read(1)
@@ -183,7 +183,7 @@ class PSFile:
if self.char in b"\r\n":
self.char = None
- return s.decode("latin-1")
+ return b"".join(s).decode("latin-1")
def _accept(prefix):
--
2.23.0

View File

@ -1,123 +0,0 @@
From 496245aa4365d0827390bd0b6fbd11287453b3a1 Mon Sep 17 00:00:00 2001
From: Eric Soroos <eric-github@soroos.net>
Date: Sun, 7 Mar 2021 19:00:17 +0100
Subject: [PATCH] Fix BLP DOS -- CVE-2021-28678
Conflict:NA
Reference:https://github.com/python-pillow/Pillow/commit/496245aa4365d0827390bd0b6fbd11287453b3a1
---
src/PIL/BlpImagePlugin.py | 43 +++++++++++++++++++++------------------
1 file changed, 23 insertions(+), 20 deletions(-)
diff --git a/src/PIL/BlpImagePlugin.py b/src/PIL/BlpImagePlugin.py
index 88aae80..e074746 100644
--- a/src/PIL/BlpImagePlugin.py
+++ b/src/PIL/BlpImagePlugin.py
@@ -286,33 +286,36 @@ class _BLPBaseDecoder(ImageFile.PyDecoder):
raise OSError("Truncated Blp file") from e
return 0, 0
+ def _safe_read(self, length):
+ return ImageFile._safe_read(self.fd, length)
+
def _read_palette(self):
ret = []
for i in range(256):
try:
- b, g, r, a = struct.unpack("<4B", self.fd.read(4))
+ b, g, r, a = struct.unpack("<4B", self._safe_read(4))
except struct.error:
break
ret.append((b, g, r, a))
return ret
def _read_blp_header(self):
- (self._blp_compression,) = struct.unpack("<i", self.fd.read(4))
+ (self._blp_compression,) = struct.unpack("<i", self._safe_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._safe_read(1))
+ (self._blp_alpha_depth,) = struct.unpack("<b", self._safe_read(1))
+ (self._blp_alpha_encoding,) = struct.unpack("<b", self._safe_read(1))
+ (self._blp_mips,) = struct.unpack("<b", self._safe_read(1))
- self.size = struct.unpack("<II", self.fd.read(8))
+ self.size = struct.unpack("<II", self._safe_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._safe_read(4))
+ (self._blp_subtype,) = struct.unpack("<i", self._safe_read(4))
- self._blp_offsets = struct.unpack("<16I", self.fd.read(16 * 4))
- self._blp_lengths = struct.unpack("<16I", self.fd.read(16 * 4))
+ self._blp_offsets = struct.unpack("<16I", self._safe_read(16 * 4))
+ self._blp_lengths = struct.unpack("<16I", self._safe_read(16 * 4))
class BLP1Decoder(_BLPBaseDecoder):
@@ -324,7 +327,7 @@ class BLP1Decoder(_BLPBaseDecoder):
if self._blp_encoding in (4, 5):
data = bytearray()
palette = self._read_palette()
- _data = BytesIO(self.fd.read(self._blp_lengths[0]))
+ _data = BytesIO(self._safe_read(self._blp_lengths[0]))
while True:
try:
(offset,) = struct.unpack("<B", _data.read(1))
@@ -346,10 +349,10 @@ 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 = 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])
+ (jpeg_header_size,) = struct.unpack("<I", self._safe_read(4))
+ jpeg_header = self._safe_read(jpeg_header_size)
+ self._safe_read(self._blp_offsets[0] - self.fd.tell()) # What IS this?
+ data = self._safe_read(self._blp_lengths[0])
data = jpeg_header + data
data = BytesIO(data)
image = JpegImageFile(data)
@@ -370,7 +373,7 @@ class BLP2Decoder(_BLPBaseDecoder):
# Uncompressed or DirectX compression
if self._blp_encoding == BLP_ENCODING_UNCOMPRESSED:
- _data = BytesIO(self.fd.read(self._blp_lengths[0]))
+ _data = BytesIO(self._safe_read(self._blp_lengths[0]))
while True:
try:
(offset,) = struct.unpack("<B", _data.read(1))
@@ -384,20 +387,20 @@ class BLP2Decoder(_BLPBaseDecoder):
linesize = (self.size[0] + 3) // 4 * 8
for yb in range((self.size[1] + 3) // 4):
for d in decode_dxt1(
- self.fd.read(linesize), alpha=bool(self._blp_alpha_depth)
+ self._safe_read(linesize), alpha=bool(self._blp_alpha_depth)
):
data += d
elif self._blp_alpha_encoding == BLP_ALPHA_ENCODING_DXT3:
linesize = (self.size[0] + 3) // 4 * 16
for yb in range((self.size[1] + 3) // 4):
- for d in decode_dxt3(self.fd.read(linesize)):
+ for d in decode_dxt3(self._safe_read(linesize)):
data += d
elif self._blp_alpha_encoding == BLP_ALPHA_ENCODING_DXT5:
linesize = (self.size[0] + 3) // 4 * 16
for yb in range((self.size[1] + 3) // 4):
- for d in decode_dxt5(self.fd.read(linesize)):
+ for d in decode_dxt5(self._safe_read(linesize)):
data += d
else:
raise BLPFormatError(
--
2.23.0

View File

@ -1,26 +0,0 @@
From ba65f0b08ee8b93195c3f3277820771f5b62aa52 Mon Sep 17 00:00:00 2001
From: Eric Soroos <eric-github@soroos.net>
Date: Sun, 14 Mar 2021 23:26:28 +0100
Subject: [PATCH] Fix Memory DOS in ImageFont
Conflict:NA
Reference:https://github.com/python-pillow/Pillow/commit/ba65f0b08ee8b93195c3f3277820771f5b62aa52
---
src/PIL/ImageFont.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/PIL/ImageFont.py b/src/PIL/ImageFont.py
index c48d898..2f63dda 100644
--- a/src/PIL/ImageFont.py
+++ b/src/PIL/ImageFont.py
@@ -669,6 +669,7 @@ class FreeTypeFont:
)
size = size[0] + stroke_width * 2, size[1] + stroke_width * 2
offset = offset[0] - stroke_width, offset[1] - stroke_width
+ Image._decompression_bomb_check(size)
im = fill("RGBA" if mode == "RGBA" else "L", size, 0)
self.font.render(
text, im.id, mode, direction, features, language, stroke_width, ink
--
2.23.0

View File

@ -1,30 +0,0 @@
From 852fd170f8f3bb45cb0a7709d62bbc52b568d8bc Mon Sep 17 00:00:00 2001
From: Luke Granger-Brown <lukegb@google.com>
Date: Wed, 3 Mar 2021 13:30:28 +0000
Subject: [PATCH] Fix -Wformat error in TiffDecode
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Conflict:NA
Reference:https://github.com/python-pillow/Pillow/commit/852fd170f8f3bb45cb0a7709d62bbc52b568d8bc
---
src/libImaging/TiffDecode.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/libImaging/TiffDecode.c b/src/libImaging/TiffDecode.c
index accadfd..40a86ca 100644
--- a/src/libImaging/TiffDecode.c
+++ b/src/libImaging/TiffDecode.c
@@ -48,7 +48,7 @@ tsize_t _tiffReadProc(thandle_t hdata, tdata_t buf, tsize_t size) {
dump_state(state);
if (state->loc > state->eof) {
- TIFFError("_tiffReadProc", "Invalid Read at loc %d, eof: %d", state->loc, state->eof);
+ TIFFError("_tiffReadProc", "Invalid Read at loc %lu, eof: %lu", state->loc, state->eof);
return 0;
}
to_read = min(size, min(state->size, (tsize_t)state->eof) - (tsize_t)state->loc);
--
2.23.0

View File

@ -1,84 +0,0 @@
From 297789284b8680a1d15549dc2d192f3abc552160 Mon Sep 17 00:00:00 2001
From: Andrew Murray <radarhere@users.noreply.github.com>
Date: Mon, 22 Feb 2021 19:32:52 +1100
Subject: [PATCH] Fixed linear_gradient and radial_gradient 32-bit modes
Conflict:NA
Reference:https://github.com/python-pillow/Pillow/commit/297789284b8680a1d15549dc2d192f3abc552160
---
Tests/test_image.py | 4 ++--
src/libImaging/Fill.c | 28 ++++++++++++++++++++++++----
2 files changed, 26 insertions(+), 6 deletions(-)
diff --git a/Tests/test_image.py b/Tests/test_image.py
index f2a1917..54448f3 100644
--- a/Tests/test_image.py
+++ b/Tests/test_image.py
@@ -516,7 +516,7 @@ class TestImage:
# Arrange
target_file = "Tests/images/linear_gradient.png"
- for mode in ["L", "P"]:
+ for mode in ["L", "P", "I", "F"]:
# Act
im = Image.linear_gradient(mode)
@@ -542,7 +542,7 @@ class TestImage:
# Arrange
target_file = "Tests/images/radial_gradient.png"
- for mode in ["L", "P"]:
+ for mode in ["L", "P", "I", "F"]:
# Act
im = Image.radial_gradient(mode)
diff --git a/src/libImaging/Fill.c b/src/libImaging/Fill.c
index da143b4..6c6e107 100644
--- a/src/libImaging/Fill.c
+++ b/src/libImaging/Fill.c
@@ -79,8 +79,21 @@ ImagingFillLinearGradient(const char *mode)
return NULL;
}
- for (y = 0; y < 256; y++) {
- memset(im->image8[y], (unsigned char) y, 256);
+ if (im->image8) {
+ for (y = 0; y < 256; y++) {
+ memset(im->image8[y], (unsigned char)y, 256);
+ }
+ } else {
+ int x;
+ for (y = 0; y < 256; y++) {
+ for (x = 0; x < 256; x++) {
+ if (im->type == IMAGING_TYPE_FLOAT32) {
+ IMAGING_PIXEL_FLOAT32(im, x, y) = y;
+ } else {
+ IMAGING_PIXEL_INT32(im, x, y) = y;
+ }
+ }
+ }
}
return im;
@@ -106,9 +119,16 @@ ImagingFillRadialGradient(const char *mode)
for (x = 0; x < 256; x++) {
d = (int) sqrt((double) ((x-128)*(x-128) + (y-128)*(y-128)) * 2.0);
if (d >= 255) {
- im->image8[y][x] = 255;
- } else {
+ d = 255;
+ }
+ if (im->image8) {
im->image8[y][x] = d;
+ } else {
+ if (im->type == IMAGING_TYPE_FLOAT32) {
+ IMAGING_PIXEL_FLOAT32(im, x, y) = d;
+ } else {
+ IMAGING_PIXEL_INT32(im, x, y) = d;
+ }
}
}
}
--
2.23.0

View File

@ -1,31 +0,0 @@
From 6fc039a21c683b13c311e1759c3570bc4dc5f459 Mon Sep 17 00:00:00 2001
From: Andrew Murray <radarhere@users.noreply.github.com>
Date: Tue, 4 May 2021 16:50:12 +1000
Subject: [PATCH] Updated default value for SAMPLESPERPIXEL tag
Conflict:NA
Reference:https://github.com/python-pillow/Pillow/commit/6fc039a21c683b13c311e1759c3570bc4dc5f459
---
src/PIL/TiffImagePlugin.py | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/PIL/TiffImagePlugin.py b/src/PIL/TiffImagePlugin.py
index ced414f..860d870 100644
--- a/src/PIL/TiffImagePlugin.py
+++ b/src/PIL/TiffImagePlugin.py
@@ -1250,7 +1250,10 @@ class TiffImageFile(ImageFile.ImageFile):
if bps_count > len(bps_tuple) and len(bps_tuple) == 1:
bps_tuple = bps_tuple * bps_count
- samplesPerPixel = self.tag_v2.get(SAMPLESPERPIXEL, 1)
+ samplesPerPixel = self.tag_v2.get(
+ SAMPLESPERPIXEL,
+ 3 if self._compression == "tiff_jpeg" and photo in (2, 6) else 1,
+ )
if len(bps_tuple) != samplesPerPixel:
raise SyntaxError("unknown data organization")
--
2.27.0

View File

@ -1,27 +0,0 @@
From 68b655f3f014c6beb13f4c9a6fa53f1ebff527c2 Mon Sep 17 00:00:00 2001
From: Andrew Murray <3112309+radarhere@users.noreply.github.com>
Date: Wed, 10 Mar 2021 20:43:16 +1100
Subject: [PATCH] Updated format specifiers
Conflict:NA
Reference:https://github.com/python-pillow/Pillow/commit/68b655f3f014c6beb13f4c9a6fa53f1ebff527c2
---
src/libImaging/TiffDecode.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/libImaging/TiffDecode.c b/src/libImaging/TiffDecode.c
index 40a86ca..0c6e758 100644
--- a/src/libImaging/TiffDecode.c
+++ b/src/libImaging/TiffDecode.c
@@ -48,7 +48,7 @@ tsize_t _tiffReadProc(thandle_t hdata, tdata_t buf, tsize_t size) {
dump_state(state);
if (state->loc > state->eof) {
- TIFFError("_tiffReadProc", "Invalid Read at loc %lu, eof: %lu", state->loc, state->eof);
+ TIFFError("_tiffReadProc", "Invalid Read at loc %llu, eof: %llu", state->loc, state->eof);
return 0;
}
to_read = min(size, min(state->size, (tsize_t)state->eof) - (tsize_t)state->loc);
--
2.23.0

View File

@ -1,29 +0,0 @@
From 53c80281d7f745cc1804901ec6f5b61d236688e0 Mon Sep 17 00:00:00 2001
From: Eric Soroos <eric-github@soroos.net>
Date: Wed, 31 Mar 2021 21:16:43 +0200
Subject: [PATCH] fix for crash-8115
Conflict:NA
Reference:https://github.com/python-pillow/Pillow/commit/53c80281d7f745cc1804901ec6f5b61d236688e0
---
src/PIL/TiffImagePlugin.py | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/PIL/TiffImagePlugin.py b/src/PIL/TiffImagePlugin.py
index 0b70ce3..ced414f 100644
--- a/src/PIL/TiffImagePlugin.py
+++ b/src/PIL/TiffImagePlugin.py
@@ -1250,6 +1250,10 @@ class TiffImageFile(ImageFile.ImageFile):
if bps_count > len(bps_tuple) and len(bps_tuple) == 1:
bps_tuple = bps_tuple * bps_count
+ samplesPerPixel = self.tag_v2.get(SAMPLESPERPIXEL, 1)
+ if len(bps_tuple) != samplesPerPixel:
+ raise SyntaxError("unknown data organization")
+
# mode: check photometric interpretation and bits per pixel
key = (
self.tag_v2.prefix,
--
2.23.0

View File

@ -1,71 +0,0 @@
From 45530d5ce1bcc9357907b7e5eeb6e54c6198358e Mon Sep 17 00:00:00 2001
From: Eric Soroos <eric-github@soroos.net>
Date: Wed, 31 Mar 2021 21:04:59 +0200
Subject: [PATCH] fixes crash-74d2
Conflict:NA
Reference:https://github.com/python-pillow/Pillow/commit/45530d5ce1bcc9357907b7e5eeb6e54c6198358e
---
src/libImaging/TiffDecode.c | 25 ++++++++++++++++---------
1 file changed, 16 insertions(+), 9 deletions(-)
diff --git a/src/libImaging/TiffDecode.c b/src/libImaging/TiffDecode.c
index cd47158..accadfd 100644
--- a/src/libImaging/TiffDecode.c
+++ b/src/libImaging/TiffDecode.c
@@ -199,7 +199,7 @@ int _decodeStripYCbCr(Imaging im, ImagingCodecState state, TIFF *tiff) {
char emsg[1024] = "";
ret = TIFFGetFieldDefaulted(tiff, TIFFTAG_ROWSPERSTRIP, &rows_per_strip);
- if (ret != 1) {
+ if (ret != 1 || rows_per_strip==(UINT32)(-1)) {
rows_per_strip = state->ysize;
}
TRACE(("RowsPerStrip: %u \n", rows_per_strip));
@@ -214,13 +214,6 @@ int _decodeStripYCbCr(Imaging im, ImagingCodecState state, TIFF *tiff) {
img.req_orientation = ORIENTATION_TOPLEFT;
img.col_offset = 0;
- if (state->xsize != img.width || state->ysize != img.height) {
- TRACE(("Inconsistent Image Error: %d =? %d, %d =? %d",
- state->xsize, img.width, state->ysize, img.height));
- state->errcode = IMAGING_CODEC_BROKEN;
- goto decodeycbcr_err;
- }
-
/* overflow check for row byte size */
if (INT_MAX / 4 < img.width) {
state->errcode = IMAGING_CODEC_MEMORY;
@@ -360,6 +353,7 @@ int ImagingLibTiffDecode(Imaging im, ImagingCodecState state, UINT8* buffer, Py_
TIFF *tiff;
uint16 photometric = 0; // init to not PHOTOMETRIC_YCBCR
int isYCbCr = 0;
+ UINT32 img_width, img_height;
/* buffer is the encoded file, bytes is the length of the encoded file */
/* it all ends up in state->buffer, which is a uint8* from Imaging.h */
@@ -420,7 +414,20 @@ int ImagingLibTiffDecode(Imaging im, ImagingCodecState state, UINT8* buffer, Py_
}
}
-
+ TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &img_width);
+ TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &img_height);
+
+ if (state->xsize != img_width || state->ysize != img_height) {
+ TRACE(
+ ("Inconsistent Image Error: %d =? %d, %d =? %d",
+ state->xsize,
+ img_width,
+ state->ysize,
+ img_height));
+ state->errcode = IMAGING_CODEC_BROKEN;
+ goto decode_err;
+ }
+
TIFFGetField(tiff, TIFFTAG_PHOTOMETRIC, &photometric);
isYCbCr = photometric == PHOTOMETRIC_YCBCR;
--
2.23.0

View File

@ -4,8 +4,8 @@
%global with_docs 0 %global with_docs 0
Name: python-pillow Name: python-pillow
Version: 8.1.1 Version: 9.0.1
Release: 9 Release: 1
Summary: Python image processing library Summary: Python image processing library
License: MIT License: MIT
URL: http://python-pillow.github.io/ URL: http://python-pillow.github.io/
@ -13,32 +13,6 @@ Source0: https://github.com/python-pillow/Pillow/archive/%{version}/Pillo
Patch0: python-pillow_spinxwarn.patch Patch0: python-pillow_spinxwarn.patch
Patch1: python-pillow_sphinx-issues.patch Patch1: python-pillow_sphinx-issues.patch
Patch6000: backport-CVE-2021-27921_CVE-2021-27922_CVE-2021-27923.patch
Patch6001: backport-Fix-Wformat-error-in-TiffDecode.patch
Patch6002: backport-Updated-format-specifiers.patch
Patch6003: backport-CVE-2021-25287-CVE-2021-25288.patch
Patch6004: backport-CVE-2021-28675.patch
Patch6005: backport-CVE-2021-28676.patch
Patch6006: backport-CVE-2021-28677.patch
Patch6007: backport-CVE-2021-28678.patch
Patch6008: backport-Fixed-linear_gradient-and-radial_gradient-32-bit-mod.patch
Patch6009: backport-fixes-crash-74d2.patch
Patch6010: backport-fix-for-crash-8115.patch
Patch6011: backport-Fix-Memory-DOS-in-ImageFont.patch
Patch6012: backport-0001-CVE-2021-34552.patch
Patch6013: backport-0002-CVE-2021-34552.patch
Patch6014: backport-Updated-default-value-for-SAMPLESPERPIXEL-tag.patch
Patch6015: backport-CVE-2021-23437.patch
Patch6016: backport-0001-CVE-2022-22815-CVE-2022-22816.patch
Patch6017: backport-0002-CVE-2022-22815-CVE-2022-22816.patch
Patch6018: backport-0003-CVE-2022-22815-CVE-2022-22816.patch
Patch6019: backport-0001-CVE-2022-22817.patch
Patch6020: backport-0002-CVE-2022-22817.patch
Patch6021: backport-0001-CVE-2022-24303.patch
Patch6022: backport-0002-CVE-2022-24303.patch
Patch6023: backport-0003-CVE-2022-24303.patch
Patch6024: backport-0004-CVE-2022-24303.patch
Patch6025: backport-0005-CVE-2022-24303.patch
BuildRequires: freetype-devel ghostscript lcms2-devel libimagequant-devel libjpeg-devel libraqm-devel libtiff-devel BuildRequires: freetype-devel ghostscript lcms2-devel libimagequant-devel libjpeg-devel libraqm-devel libtiff-devel
BuildRequires: libwebp-devel openjpeg2-devel tk-devel zlib-devel python3-cffi python3-devel python3-numpy python3-olefile BuildRequires: libwebp-devel openjpeg2-devel tk-devel zlib-devel python3-cffi python3-devel python3-numpy python3-olefile
@ -170,6 +144,9 @@ popd
%{python3_sitearch}/PIL/__pycache__/ImageQt* %{python3_sitearch}/PIL/__pycache__/ImageQt*
%changelog %changelog
* Mon Aug 29 2022 yaoxin <yaoxin30@h-partners.com> - 9.0.1-1
- Upgrade to 9.0.1
* Thu Feb 17 2022 dongyuzhen <dongyuzhen@h-partners.com> - 8.1.1-9 * Thu Feb 17 2022 dongyuzhen <dongyuzhen@h-partners.com> - 8.1.1-9
- fix CVE-2022-24303 - fix CVE-2022-24303

View File

@ -1,11 +1,17 @@
diff -rupN --no-dereference Pillow-8.1.1/docs/conf.py Pillow-8.1.1-new/docs/conf.py diff -rupN --no-dereference Pillow-9.0.1/docs/conf.py Pillow-9.0.1-new/docs/conf.py
--- Pillow-8.1.1/docs/conf.py 2021-03-01 09:24:03.000000000 +0100 --- Pillow-9.0.1/docs/conf.py 2022-02-03 00:45:27.000000000 +0100
+++ Pillow-8.1.1-new/docs/conf.py 2021-03-02 15:10:49.599033773 +0100 +++ Pillow-9.0.1-new/docs/conf.py 2022-02-23 09:06:33.169472252 +0100
@@ -32,7 +32,6 @@ extensions = [ @@ -30,12 +30,10 @@ needs_sphinx = "2.4"
"sphinx.ext.autodoc", # ones.
"sphinx.ext.intersphinx", extensions = [
"sphinx.ext.viewcode", "sphinx_copybutton",
- "sphinx_issues", - "sphinx_issues",
"sphinx_removed_in", "sphinx_removed_in",
"sphinx.ext.autodoc",
"sphinx.ext.intersphinx",
- "sphinx.ext.viewcode",
- "sphinxext.opengraph",
+ "sphinx.ext.viewcode"
] ]
intersphinx_mapping = {"python": ("https://docs.python.org/3", None)}

View File

@ -1,6 +1,6 @@
diff -rupN --no-dereference Pillow-8.1.1/docs/Makefile Pillow-8.1.1-new/docs/Makefile diff -rupN --no-dereference Pillow-9.0.1/docs/Makefile Pillow-9.0.1-new/docs/Makefile
--- Pillow-8.1.1/docs/Makefile 2021-03-01 09:24:03.000000000 +0100 --- Pillow-9.0.1/docs/Makefile 2022-02-03 00:45:27.000000000 +0100
+++ Pillow-8.1.1-new/docs/Makefile 2021-03-02 15:10:49.514033779 +0100 +++ Pillow-9.0.1-new/docs/Makefile 2022-02-23 09:06:33.060472214 +0100
@@ -42,7 +42,7 @@ clean: @@ -42,7 +42,7 @@ clean:
-rm -rf $(BUILDDIR)/* -rm -rf $(BUILDDIR)/*