!105 update to Pillow-9.0.1

From: @shirely16 
Reviewed-by: @zzm_567, @t_feng, @shinwell_hu 
Signed-off-by: @t_feng, @shinwell_hu
This commit is contained in:
openeuler-ci-bot 2022-03-07 04:00:46 +00:00 committed by Gitee
commit bad35dea21
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
30 changed files with 26 additions and 1721 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,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,45 +0,0 @@
From dd3eb37c615243a0c71d61639578d1bf4618f806 Mon Sep 17 00:00:00 2001
Date: Thu, 5 Aug 2021 14:51:41 +0800
Subject: [PATCH] disable test_sanity
---
Tests/test_qt_image_qapplication.py | 26 --------------------------
1 file changed, 26 deletions(-)
diff --git a/Tests/test_qt_image_qapplication.py b/Tests/test_qt_image_qapplication.py
index 06bd27c..8d4bb58 100644
--- a/Tests/test_qt_image_qapplication.py
+++ b/Tests/test_qt_image_qapplication.py
@@ -35,29 +35,3 @@ def roundtrip(expected):
result = ImageQt.fromqpixmap(ImageQt.toqpixmap(expected))
# Qt saves all pixmaps as rgb
assert_image_equal(result, expected.convert("RGB"))
-
-
-@pytest.mark.skipif(not ImageQt.qt_is_installed, reason="Qt bindings are not installed")
-def test_sanity(tmp_path):
- # Segfault test
- app = QApplication([])
- ex = Example()
- assert app # Silence warning
- assert ex # Silence warning
-
- for mode in ("1", "RGB", "RGBA", "L", "P"):
- # to QPixmap
- data = ImageQt.toqpixmap(hopper(mode))
-
- assert isinstance(data, QPixmap)
- assert not data.isNull()
-
- # Test saving the file
- tempfile = str(tmp_path / f"temp_{mode}.png")
- data.save(tempfile)
-
- # from QPixmap
- roundtrip(hopper(mode))
-
- app.quit()
- app = None
--
2.27.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
Name: python-pillow
Version: 8.1.2
Release: 5
Version: 9.0.1
Release: 1
Summary: Python image processing library
License: MIT
URL: http://python-pillow.github.io/
@ -14,38 +14,13 @@ Source0: https://github.com/python-pillow/Pillow/archive/%{version}/Pillo
Patch0: python-pillow_spinxwarn.patch
Patch1: python-pillow_sphinx-issues.patch
Patch6000: backport-Fix-Wformat-error-in-TiffDecode.patch
Patch6001: backport-Updated-format-specifiers.patch
Patch6002: backport-CVE-2021-25287-CVE-2021-25288.patch
Patch6003: backport-CVE-2021-28675.patch
Patch6004: backport-CVE-2021-28676.patch
Patch6005: backport-CVE-2021-28677.patch
Patch6006: backport-CVE-2021-28678.patch
Patch6007: backport-Fixed-linear_gradient-and-radial_gradient-32-bit-mod.patch
Patch6008: backport-fixes-crash-74d2.patch
Patch6009: backport-fix-for-crash-8115.patch
Patch6010: backport-Fix-Memory-DOS-in-ImageFont.patch
Patch6011: backport-0001-CVE-2021-34552.patch
Patch6012: backport-0002-CVE-2021-34552.patch
Patch6013: backport-Updated-default-value-for-SAMPLESPERPIXEL-tag.patch
Patch6014: backport-CVE-2021-23437.patch
Patch6015: backport-0001-CVE-2022-22815-CVE-2022-22816.patch
Patch6016: backport-0002-CVE-2022-22815-CVE-2022-22816.patch
Patch6017: backport-0003-CVE-2022-22815-CVE-2022-22816.patch
Patch6018: backport-0001-CVE-2022-22817.patch
Patch6019: backport-0002-CVE-2022-22817.patch
Patch6020: backport-0001-CVE-2022-24303.patch
Patch6021: backport-0002-CVE-2022-24303.patch
Patch6022: backport-0003-CVE-2022-24303.patch
Patch6023: backport-0004-CVE-2022-24303.patch
Patch6024: backport-0005-CVE-2022-24303.patch
Patch9000: backport-disable-test-sanity.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 libtiff-devel
BuildRequires: libwebp-devel openjpeg2-devel tk-devel zlib-devel python3-cffi python3-devel python3-numpy python3-olefile
BuildRequires: python3-qt5 python3-setuptools python3-tkinter gcc
BuildRequires: python3-pytest
%if %{?openEuler:1}0
BuildRequires: libraqm-devel
%endif
%if 0%{?with_docs}
BuildRequires: make
BuildRequires: python3-sphinx
@ -140,7 +115,7 @@ pushd build/%py3_libbuilddir
PYTHONPATH=$PWD %{__python3} selftest.py
popd
export PYTHONPATH=%{buildroot}%{python3_sitearch}
pytest --ignore=_build.python2 --ignore=_build.python3 --ignore=_build.pypy3 -v -k 'not (test_stroke or test_stroke_multiline)'
pytest --ignore=_build.python2 --ignore=_build.python3 --ignore=_build.pypy3 -v -k 'not (test_qt_image_qapplication)'
%files -n python3-pillow
%doc README.md CHANGES.rst
@ -175,6 +150,9 @@ pytest --ignore=_build.python2 --ignore=_build.python3 --ignore=_build.pypy3 -v
%{python3_sitearch}/PIL/__pycache__/ImageQt*
%changelog
* Thu Mar 3 2022 hanhui <hanhui15@h-partners.com> - 9.0.1-1
- DESC:update to Pillow-9.0.1
* Thu Feb 17 2022 dongyuzhen <dongyuzhen@h-partners.com> - 8.1.2-5
- 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
--- Pillow-8.1.1/docs/conf.py 2021-03-01 09:24:03.000000000 +0100
+++ Pillow-8.1.1-new/docs/conf.py 2021-03-02 15:10:49.599033773 +0100
@@ -32,7 +32,6 @@ extensions = [
"sphinx.ext.autodoc",
"sphinx.ext.intersphinx",
"sphinx.ext.viewcode",
diff -rupN --no-dereference Pillow-9.0.1/docs/conf.py Pillow-9.0.1-new/docs/conf.py
--- Pillow-9.0.1/docs/conf.py 2022-02-03 00:45:27.000000000 +0100
+++ Pillow-9.0.1-new/docs/conf.py 2022-02-23 09:06:33.169472252 +0100
@@ -30,12 +30,10 @@ needs_sphinx = "2.4"
# ones.
extensions = [
"sphinx_copybutton",
- "sphinx_issues",
"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
--- Pillow-8.1.1/docs/Makefile 2021-03-01 09:24:03.000000000 +0100
+++ Pillow-8.1.1-new/docs/Makefile 2021-03-02 15:10:49.514033779 +0100
diff -rupN --no-dereference Pillow-9.0.1/docs/Makefile Pillow-9.0.1-new/docs/Makefile
--- Pillow-9.0.1/docs/Makefile 2022-02-03 00:45:27.000000000 +0100
+++ Pillow-9.0.1-new/docs/Makefile 2022-02-23 09:06:33.060472214 +0100
@@ -42,7 +42,7 @@ clean:
-rm -rf $(BUILDDIR)/*