File: test_shell_injection.py

package info (click to toggle)
pillow 12.1.0-1
  • links: PTS
  • area: main
  • in suites: sid
  • size: 72,560 kB
  • sloc: python: 49,748; ansic: 38,748; makefile: 302; sh: 168; javascript: 85
file content (61 lines) | stat: -rw-r--r-- 2,164 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
from __future__ import annotations

import shutil
from io import BytesIO

import pytest

from PIL import GifImagePlugin, Image, JpegImagePlugin

from .helper import djpeg_available, is_win32, netpbm_available

TYPE_CHECKING = False
if TYPE_CHECKING:
    from collections.abc import Callable
    from pathlib import Path
    from typing import IO

TEST_JPG = "Tests/images/hopper.jpg"
TEST_GIF = "Tests/images/hopper.gif"

test_filenames = ("temp_';", 'temp_";', "temp_'\"|", "temp_'\"||", "temp_'\"&&")


@pytest.mark.skipif(is_win32(), reason="Requires Unix or macOS")
class TestShellInjection:
    def assert_save_filename_check(
        self,
        tmp_path: Path,
        src_img: Image.Image,
        save_func: Callable[[Image.Image, IO[bytes], str | bytes], None],
    ) -> None:
        for filename in test_filenames:
            dest_file = str(tmp_path / filename)
            save_func(src_img, BytesIO(), dest_file)
            # If file can't be opened, shell injection probably occurred
            with Image.open(dest_file) as im:
                im.load()

    @pytest.mark.skipif(not djpeg_available(), reason="djpeg not available")
    def test_load_djpeg_filename(self, tmp_path: Path) -> None:
        for filename in test_filenames:
            src_file = tmp_path / filename
            shutil.copy(TEST_JPG, src_file)

            with Image.open(src_file) as im:
                assert isinstance(im, JpegImagePlugin.JpegImageFile)
                im.load_djpeg()

    @pytest.mark.skipif(not netpbm_available(), reason="Netpbm not available")
    def test_save_netpbm_filename_bmp_mode(self, tmp_path: Path) -> None:
        with Image.open(TEST_GIF) as im:
            im_rgb = im.convert("RGB")
            self.assert_save_filename_check(
                tmp_path, im_rgb, GifImagePlugin._save_netpbm
            )

    @pytest.mark.skipif(not netpbm_available(), reason="Netpbm not available")
    def test_save_netpbm_filename_l_mode(self, tmp_path: Path) -> None:
        with Image.open(TEST_GIF) as im:
            im_l = im.convert("L")
            self.assert_save_filename_check(tmp_path, im_l, GifImagePlugin._save_netpbm)