mirror of
				https://github.com/python-pillow/Pillow.git
				synced 2025-11-04 01:47:47 +03:00 
			
		
		
		
	Do not read layers when opening
This commit is contained in:
		
							parent
							
								
									d879f39711
								
							
						
					
					
						commit
						804fe7bbf8
					
				| 
						 | 
				
			
			@ -4,7 +4,7 @@ import warnings
 | 
			
		|||
 | 
			
		||||
import pytest
 | 
			
		||||
 | 
			
		||||
from PIL import Image, PsdImagePlugin, UnidentifiedImageError
 | 
			
		||||
from PIL import Image, PsdImagePlugin
 | 
			
		||||
 | 
			
		||||
from .helper import assert_image_equal_tofile, assert_image_similar, hopper, is_pypy
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -150,14 +150,6 @@ def test_combined_larger_than_size() -> None:
 | 
			
		|||
@pytest.mark.parametrize(
 | 
			
		||||
    "test_file,raises",
 | 
			
		||||
    [
 | 
			
		||||
        (
 | 
			
		||||
            "Tests/images/timeout-1ee28a249896e05b83840ae8140622de8e648ba9.psd",
 | 
			
		||||
            UnidentifiedImageError,
 | 
			
		||||
        ),
 | 
			
		||||
        (
 | 
			
		||||
            "Tests/images/timeout-598843abc37fc080ec36a2699ebbd44f795d3a6f.psd",
 | 
			
		||||
            UnidentifiedImageError,
 | 
			
		||||
        ),
 | 
			
		||||
        ("Tests/images/timeout-c8efc3fded6426986ba867a399791bae544f59bc.psd", OSError),
 | 
			
		||||
        ("Tests/images/timeout-dedc7a4ebd856d79b4359bbcc79e8ef231ce38f6.psd", OSError),
 | 
			
		||||
    ],
 | 
			
		||||
| 
						 | 
				
			
			@ -167,3 +159,17 @@ def test_crashes(test_file: str, raises) -> None:
 | 
			
		|||
        with pytest.raises(raises):
 | 
			
		||||
            with Image.open(f):
 | 
			
		||||
                pass
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.parametrize(
 | 
			
		||||
    "test_file",
 | 
			
		||||
    [
 | 
			
		||||
        "Tests/images/timeout-1ee28a249896e05b83840ae8140622de8e648ba9.psd",
 | 
			
		||||
        "Tests/images/timeout-598843abc37fc080ec36a2699ebbd44f795d3a6f.psd",
 | 
			
		||||
    ],
 | 
			
		||||
)
 | 
			
		||||
def test_layer_crashes(test_file: str) -> None:
 | 
			
		||||
    with open(test_file, "rb") as f:
 | 
			
		||||
        with Image.open(f) as im:
 | 
			
		||||
            with pytest.raises(SyntaxError):
 | 
			
		||||
                im.layers
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,6 +18,7 @@
 | 
			
		|||
from __future__ import annotations
 | 
			
		||||
 | 
			
		||||
import io
 | 
			
		||||
from functools import cached_property
 | 
			
		||||
 | 
			
		||||
from . import Image, ImageFile, ImagePalette
 | 
			
		||||
from ._binary import i8
 | 
			
		||||
| 
						 | 
				
			
			@ -118,18 +119,17 @@ class PsdImageFile(ImageFile.ImageFile):
 | 
			
		|||
        #
 | 
			
		||||
        # layer and mask information
 | 
			
		||||
 | 
			
		||||
        self.layers = []
 | 
			
		||||
        self._layers_position = None
 | 
			
		||||
 | 
			
		||||
        size = i32(read(4))
 | 
			
		||||
        if size:
 | 
			
		||||
            end = self.fp.tell() + size
 | 
			
		||||
            size = i32(read(4))
 | 
			
		||||
            if size:
 | 
			
		||||
                _layer_data = io.BytesIO(ImageFile._safe_read(self.fp, size))
 | 
			
		||||
                self.layers = _layerinfo(_layer_data, size)
 | 
			
		||||
                self._layers_position = self.fp.tell()
 | 
			
		||||
                self._layers_size = size
 | 
			
		||||
            self.fp.seek(end)
 | 
			
		||||
        self.n_frames = len(self.layers)
 | 
			
		||||
        self.is_animated = self.n_frames > 1
 | 
			
		||||
        self._n_frames: int | None = None
 | 
			
		||||
 | 
			
		||||
        #
 | 
			
		||||
        # image descriptor
 | 
			
		||||
| 
						 | 
				
			
			@ -141,6 +141,26 @@ class PsdImageFile(ImageFile.ImageFile):
 | 
			
		|||
        self.frame = 1
 | 
			
		||||
        self._min_frame = 1
 | 
			
		||||
 | 
			
		||||
    @cached_property
 | 
			
		||||
    def layers(self):
 | 
			
		||||
        layers = []
 | 
			
		||||
        if self._layers_position is not None:
 | 
			
		||||
            self._fp.seek(self._layers_position)
 | 
			
		||||
            _layer_data = io.BytesIO(ImageFile._safe_read(self._fp, self._layers_size))
 | 
			
		||||
            layers = _layerinfo(_layer_data, self._layers_size)
 | 
			
		||||
        self._n_frames = len(layers)
 | 
			
		||||
        return layers
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def n_frames(self) -> int:
 | 
			
		||||
        if self._n_frames is None:
 | 
			
		||||
            self._n_frames = len(self.layers)
 | 
			
		||||
        return self._n_frames
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def is_animated(self) -> bool:
 | 
			
		||||
        return len(self.layers) > 1
 | 
			
		||||
 | 
			
		||||
    def seek(self, layer: int) -> None:
 | 
			
		||||
        if not self._seek_check(layer):
 | 
			
		||||
            return
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue
	
	Block a user