mirror of
				https://github.com/python-pillow/Pillow.git
				synced 2025-10-30 23:47:27 +03:00 
			
		
		
		
	Merge pull request #8178 from radarhere/imageshow
Raise FileNotFoundError if show_file() path does not exist
This commit is contained in:
		
						commit
						8daf550b7d
					
				|  | @ -1,5 +1,6 @@ | ||||||
| from __future__ import annotations | from __future__ import annotations | ||||||
| 
 | 
 | ||||||
|  | import os | ||||||
| from typing import Any | from typing import Any | ||||||
| 
 | 
 | ||||||
| import pytest | import pytest | ||||||
|  | @ -65,6 +66,27 @@ def test_show_without_viewers() -> None: | ||||||
|     ImageShow._viewers = viewers |     ImageShow._viewers = viewers | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @pytest.mark.parametrize( | ||||||
|  |     "viewer", | ||||||
|  |     ( | ||||||
|  |         ImageShow.Viewer(), | ||||||
|  |         ImageShow.WindowsViewer(), | ||||||
|  |         ImageShow.MacViewer(), | ||||||
|  |         ImageShow.XDGViewer(), | ||||||
|  |         ImageShow.DisplayViewer(), | ||||||
|  |         ImageShow.GmDisplayViewer(), | ||||||
|  |         ImageShow.EogViewer(), | ||||||
|  |         ImageShow.XVViewer(), | ||||||
|  |         ImageShow.IPythonViewer(), | ||||||
|  |     ), | ||||||
|  | ) | ||||||
|  | def test_show_file(viewer: ImageShow.Viewer) -> None: | ||||||
|  |     assert not os.path.exists("missing.png") | ||||||
|  | 
 | ||||||
|  |     with pytest.raises(FileNotFoundError): | ||||||
|  |         viewer.show_file("missing.png") | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| def test_viewer() -> None: | def test_viewer() -> None: | ||||||
|     viewer = ImageShow.Viewer() |     viewer = ImageShow.Viewer() | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -4,21 +4,16 @@ | ||||||
| Security | Security | ||||||
| ======== | ======== | ||||||
| 
 | 
 | ||||||
| TODO | ImageShow.WindowsViewer.show_file | ||||||
| ^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||||||
| 
 | 
 | ||||||
| TODO | If an attacker has control over the ``path`` passed to | ||||||
|  | ``ImageShow.WindowsViewer.show_file()``, they may be able to | ||||||
|  | execute arbitrary shell commands. | ||||||
| 
 | 
 | ||||||
| :cve:`YYYY-XXXXX`: TODO | To prevent this, a :py:exc:`FileNotFoundError` will be raised if the ``path`` | ||||||
| ^^^^^^^^^^^^^^^^^^^^^^^ | does not exist as a file. To provide a consistent experience, the error has | ||||||
| 
 | been added to all :py:class:`~PIL.ImageShow` viewers. | ||||||
| TODO |  | ||||||
| 
 |  | ||||||
| Backwards Incompatible Changes |  | ||||||
| ============================== |  | ||||||
| 
 |  | ||||||
| TODO |  | ||||||
| ^^^^ |  | ||||||
| 
 | 
 | ||||||
| Deprecations | Deprecations | ||||||
| ============ | ============ | ||||||
|  | @ -46,14 +41,6 @@ ImageDraw.getdraw hints parameter | ||||||
| 
 | 
 | ||||||
| The ``hints`` parameter in :py:meth:`~PIL.ImageDraw.getdraw()` has been deprecated. | The ``hints`` parameter in :py:meth:`~PIL.ImageDraw.getdraw()` has been deprecated. | ||||||
| 
 | 
 | ||||||
| API Changes |  | ||||||
| =========== |  | ||||||
| 
 |  | ||||||
| TODO |  | ||||||
| ^^^^ |  | ||||||
| 
 |  | ||||||
| TODO |  | ||||||
| 
 |  | ||||||
| API Additions | API Additions | ||||||
| ============= | ============= | ||||||
| 
 | 
 | ||||||
|  | @ -64,11 +51,6 @@ Added :py:meth:`~PIL.ImageDraw.ImageDraw.circle`. It provides the same functiona | ||||||
| :py:meth:`~PIL.ImageDraw.ImageDraw.ellipse`, but instead of taking a bounding box, it | :py:meth:`~PIL.ImageDraw.ImageDraw.ellipse`, but instead of taking a bounding box, it | ||||||
| takes a center point and radius. | takes a center point and radius. | ||||||
| 
 | 
 | ||||||
| TODO |  | ||||||
| ^^^^ |  | ||||||
| 
 |  | ||||||
| TODO |  | ||||||
| 
 |  | ||||||
| Other Changes | Other Changes | ||||||
| ============= | ============= | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -118,6 +118,8 @@ class Viewer: | ||||||
|         """ |         """ | ||||||
|         Display given file. |         Display given file. | ||||||
|         """ |         """ | ||||||
|  |         if not os.path.exists(path): | ||||||
|  |             raise FileNotFoundError | ||||||
|         os.system(self.get_command(path, **options))  # nosec |         os.system(self.get_command(path, **options))  # nosec | ||||||
|         return 1 |         return 1 | ||||||
| 
 | 
 | ||||||
|  | @ -142,6 +144,8 @@ class WindowsViewer(Viewer): | ||||||
|         """ |         """ | ||||||
|         Display given file. |         Display given file. | ||||||
|         """ |         """ | ||||||
|  |         if not os.path.exists(path): | ||||||
|  |             raise FileNotFoundError | ||||||
|         subprocess.Popen( |         subprocess.Popen( | ||||||
|             self.get_command(path, **options), |             self.get_command(path, **options), | ||||||
|             shell=True, |             shell=True, | ||||||
|  | @ -171,6 +175,8 @@ class MacViewer(Viewer): | ||||||
|         """ |         """ | ||||||
|         Display given file. |         Display given file. | ||||||
|         """ |         """ | ||||||
|  |         if not os.path.exists(path): | ||||||
|  |             raise FileNotFoundError | ||||||
|         subprocess.call(["open", "-a", "Preview.app", path]) |         subprocess.call(["open", "-a", "Preview.app", path]) | ||||||
|         executable = sys.executable or shutil.which("python3") |         executable = sys.executable or shutil.which("python3") | ||||||
|         if executable: |         if executable: | ||||||
|  | @ -215,6 +221,8 @@ class XDGViewer(UnixViewer): | ||||||
|         """ |         """ | ||||||
|         Display given file. |         Display given file. | ||||||
|         """ |         """ | ||||||
|  |         if not os.path.exists(path): | ||||||
|  |             raise FileNotFoundError | ||||||
|         subprocess.Popen(["xdg-open", path]) |         subprocess.Popen(["xdg-open", path]) | ||||||
|         return 1 |         return 1 | ||||||
| 
 | 
 | ||||||
|  | @ -237,6 +245,8 @@ class DisplayViewer(UnixViewer): | ||||||
|         """ |         """ | ||||||
|         Display given file. |         Display given file. | ||||||
|         """ |         """ | ||||||
|  |         if not os.path.exists(path): | ||||||
|  |             raise FileNotFoundError | ||||||
|         args = ["display"] |         args = ["display"] | ||||||
|         title = options.get("title") |         title = options.get("title") | ||||||
|         if title: |         if title: | ||||||
|  | @ -259,6 +269,8 @@ class GmDisplayViewer(UnixViewer): | ||||||
|         """ |         """ | ||||||
|         Display given file. |         Display given file. | ||||||
|         """ |         """ | ||||||
|  |         if not os.path.exists(path): | ||||||
|  |             raise FileNotFoundError | ||||||
|         subprocess.Popen(["gm", "display", path]) |         subprocess.Popen(["gm", "display", path]) | ||||||
|         return 1 |         return 1 | ||||||
| 
 | 
 | ||||||
|  | @ -275,6 +287,8 @@ class EogViewer(UnixViewer): | ||||||
|         """ |         """ | ||||||
|         Display given file. |         Display given file. | ||||||
|         """ |         """ | ||||||
|  |         if not os.path.exists(path): | ||||||
|  |             raise FileNotFoundError | ||||||
|         subprocess.Popen(["eog", "-n", path]) |         subprocess.Popen(["eog", "-n", path]) | ||||||
|         return 1 |         return 1 | ||||||
| 
 | 
 | ||||||
|  | @ -299,6 +313,8 @@ class XVViewer(UnixViewer): | ||||||
|         """ |         """ | ||||||
|         Display given file. |         Display given file. | ||||||
|         """ |         """ | ||||||
|  |         if not os.path.exists(path): | ||||||
|  |             raise FileNotFoundError | ||||||
|         args = ["xv"] |         args = ["xv"] | ||||||
|         title = options.get("title") |         title = options.get("title") | ||||||
|         if title: |         if title: | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user