Skip to content

Commit

Permalink
Raise FileNotFoundError if show_file() path does not exist
Browse files Browse the repository at this point in the history
  • Loading branch information
radarhere committed Jun 28, 2024
1 parent b48d175 commit c9ec76a
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 26 deletions.
22 changes: 22 additions & 0 deletions Tests/test_imageshow.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from __future__ import annotations

import os
from typing import Any

import pytest
Expand Down Expand Up @@ -65,6 +66,27 @@ def test_show_without_viewers() -> None:
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:
viewer = ImageShow.Viewer()

Expand Down
34 changes: 8 additions & 26 deletions docs/releasenotes/10.4.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,16 @@
Security
========

TODO
^^^^

TODO

:cve:`YYYY-XXXXX`: TODO
^^^^^^^^^^^^^^^^^^^^^^^

TODO
ImageShow.WindowsViewer.show_file
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Backwards Incompatible Changes
==============================
If an attacker has control over the ``path`` passed to
``ImageShow.WindowsViewer.show_file()``, they may be able to
execute arbitrary shell commands.

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.

Deprecations
============
Expand Down Expand Up @@ -46,14 +41,6 @@ ImageDraw.getdraw hints parameter

The ``hints`` parameter in :py:meth:`~PIL.ImageDraw.getdraw()` has been deprecated.

API Changes
===========

TODO
^^^^

TODO

API Additions
=============

Expand All @@ -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
takes a center point and radius.

TODO
^^^^

TODO

Other Changes
=============

Expand Down
16 changes: 16 additions & 0 deletions src/PIL/ImageShow.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ def show_file(self, path: str, **options: Any) -> int:
"""
Display given file.
"""
if not os.path.exists(path):
raise FileNotFoundError
os.system(self.get_command(path, **options)) # nosec
return 1

Expand All @@ -142,6 +144,8 @@ def show_file(self, path: str, **options: Any) -> int:
"""
Display given file.
"""
if not os.path.exists(path):
raise FileNotFoundError
subprocess.Popen(
self.get_command(path, **options),
shell=True,
Expand Down Expand Up @@ -171,6 +175,8 @@ def show_file(self, path: str, **options: Any) -> int:
"""
Display given file.
"""
if not os.path.exists(path):
raise FileNotFoundError
subprocess.call(["open", "-a", "Preview.app", path])
executable = sys.executable or shutil.which("python3")
if executable:
Expand Down Expand Up @@ -215,6 +221,8 @@ def show_file(self, path: str, **options: Any) -> int:
"""
Display given file.
"""
if not os.path.exists(path):
raise FileNotFoundError
subprocess.Popen(["xdg-open", path])
return 1

Expand All @@ -237,6 +245,8 @@ def show_file(self, path: str, **options: Any) -> int:
"""
Display given file.
"""
if not os.path.exists(path):
raise FileNotFoundError
args = ["display"]
title = options.get("title")
if title:
Expand All @@ -259,6 +269,8 @@ def show_file(self, path: str, **options: Any) -> int:
"""
Display given file.
"""
if not os.path.exists(path):
raise FileNotFoundError
subprocess.Popen(["gm", "display", path])
return 1

Expand All @@ -275,6 +287,8 @@ def show_file(self, path: str, **options: Any) -> int:
"""
Display given file.
"""
if not os.path.exists(path):
raise FileNotFoundError
subprocess.Popen(["eog", "-n", path])
return 1

Expand All @@ -299,6 +313,8 @@ def show_file(self, path: str, **options: Any) -> int:
"""
Display given file.
"""
if not os.path.exists(path):
raise FileNotFoundError
args = ["xv"]
title = options.get("title")
if title:
Expand Down

0 comments on commit c9ec76a

Please sign in to comment.