Skip to content

Commit

Permalink
Check that _fp type is not DeferredError before use
Browse files Browse the repository at this point in the history
  • Loading branch information
radarhere committed Dec 30, 2024
1 parent a4f976c commit a136095
Show file tree
Hide file tree
Showing 10 changed files with 32 additions and 2 deletions.
3 changes: 3 additions & 0 deletions src/PIL/DcxImagePlugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

from . import Image
from ._binary import i32le as i32
from ._util import DeferredError
from .PcxImagePlugin import PcxImageFile

MAGIC = 0x3ADE68B1 # QUIZ: what's this value, then?
Expand Down Expand Up @@ -66,6 +67,8 @@ def _open(self) -> None:
def seek(self, frame: int) -> None:
if not self._seek_check(frame):
return
if isinstance(self._fp, DeferredError):
raise self._fp.ex

Check warning on line 71 in src/PIL/DcxImagePlugin.py

View check run for this annotation

Codecov / codecov/patch

src/PIL/DcxImagePlugin.py#L71

Added line #L71 was not covered by tests
self.frame = frame
self.fp = self._fp
self.fp.seek(self._offset[frame])
Expand Down
3 changes: 3 additions & 0 deletions src/PIL/FliImagePlugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
from ._binary import i16le as i16
from ._binary import i32le as i32
from ._binary import o8
from ._util import DeferredError

#
# decoder
Expand Down Expand Up @@ -134,6 +135,8 @@ def seek(self, frame: int) -> None:
self._seek(f)

def _seek(self, frame: int) -> None:
if isinstance(self._fp, DeferredError):
raise self._fp.ex
if frame == 0:
self.__frame = -1
self._fp.seek(self.__rewind)
Expand Down
3 changes: 3 additions & 0 deletions src/PIL/GifImagePlugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
from ._binary import i16le as i16
from ._binary import o8
from ._binary import o16le as o16
from ._util import DeferredError

if TYPE_CHECKING:
from . import _imaging
Expand Down Expand Up @@ -167,6 +168,8 @@ def seek(self, frame: int) -> None:
raise EOFError(msg) from e

def _seek(self, frame: int, update_image: bool = True) -> None:
if isinstance(self._fp, DeferredError):
raise self._fp.ex
if frame == 0:
# rewind
self.__offset = 0
Expand Down
3 changes: 3 additions & 0 deletions src/PIL/ImImagePlugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
from typing import IO, Any

from . import Image, ImageFile, ImagePalette
from ._util import DeferredError

# --------------------------------------------------------------------
# Standard tags
Expand Down Expand Up @@ -290,6 +291,8 @@ def is_animated(self) -> bool:
def seek(self, frame: int) -> None:
if not self._seek_check(frame):
return
if isinstance(self._fp, DeferredError):
raise self._fp.ex

Check warning on line 295 in src/PIL/ImImagePlugin.py

View check run for this annotation

Codecov / codecov/patch

src/PIL/ImImagePlugin.py#L294-L295

Added lines #L294 - L295 were not covered by tests

self.frame = frame

Expand Down
2 changes: 1 addition & 1 deletion src/PIL/Image.py
Original file line number Diff line number Diff line change
Expand Up @@ -604,7 +604,7 @@ def __enter__(self):
return self

def _close_fp(self):
if getattr(self, "_fp", False):
if getattr(self, "_fp", False) and not isinstance(self._fp, DeferredError):
if self._fp != self.fp:
self._fp.close()
self._fp = DeferredError(ValueError("Operation on closed image"))
Expand Down
5 changes: 5 additions & 0 deletions src/PIL/MpoImagePlugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
TiffImagePlugin,
)
from ._binary import o32le
from ._util import DeferredError


def _save(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None:
Expand Down Expand Up @@ -125,11 +126,15 @@ def _after_jpeg_open(self, mpheader: dict[int, Any] | None = None) -> None:
self.readonly = 1

def load_seek(self, pos: int) -> None:
if isinstance(self._fp, DeferredError):
raise self._fp.ex

Check warning on line 130 in src/PIL/MpoImagePlugin.py

View check run for this annotation

Codecov / codecov/patch

src/PIL/MpoImagePlugin.py#L130

Added line #L130 was not covered by tests
self._fp.seek(pos)

def seek(self, frame: int) -> None:
if not self._seek_check(frame):
return
if isinstance(self._fp, DeferredError):
raise self._fp.ex
self.fp = self._fp
self.offset = self.__mpoffsets[frame]

Expand Down
3 changes: 3 additions & 0 deletions src/PIL/PngImagePlugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
from ._binary import o8
from ._binary import o16be as o16
from ._binary import o32be as o32
from ._util import DeferredError

if TYPE_CHECKING:
from . import _imaging
Expand Down Expand Up @@ -869,6 +870,8 @@ def seek(self, frame: int) -> None:

def _seek(self, frame: int, rewind: bool = False) -> None:
assert self.png is not None
if isinstance(self._fp, DeferredError):
raise self._fp.ex

self.dispose: _imaging.ImagingCore | None
dispose_extent = None
Expand Down
5 changes: 5 additions & 0 deletions src/PIL/PsdImagePlugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
from ._binary import i32be as i32
from ._binary import si16be as si16
from ._binary import si32be as si32
from ._util import DeferredError

MODES = {
# (photoshop mode, bits) -> (pil mode, required channels)
Expand Down Expand Up @@ -148,6 +149,8 @@ def layers(
) -> list[tuple[str, str, tuple[int, int, int, int], list[ImageFile._Tile]]]:
layers = []
if self._layers_position is not None:
if isinstance(self._fp, DeferredError):
raise self._fp.ex

Check warning on line 153 in src/PIL/PsdImagePlugin.py

View check run for this annotation

Codecov / codecov/patch

src/PIL/PsdImagePlugin.py#L153

Added line #L153 was not covered by tests
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)
Expand All @@ -167,6 +170,8 @@ def is_animated(self) -> bool:
def seek(self, layer: int) -> None:
if not self._seek_check(layer):
return
if isinstance(self._fp, DeferredError):
raise self._fp.ex

Check warning on line 174 in src/PIL/PsdImagePlugin.py

View check run for this annotation

Codecov / codecov/patch

src/PIL/PsdImagePlugin.py#L174

Added line #L174 was not covered by tests

# seek to given layer (1..max)
try:
Expand Down
3 changes: 3 additions & 0 deletions src/PIL/SpiderImagePlugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
from typing import IO, TYPE_CHECKING, Any, cast

from . import Image, ImageFile
from ._util import DeferredError


def isInt(f: Any) -> int:
Expand Down Expand Up @@ -178,6 +179,8 @@ def seek(self, frame: int) -> None:
raise EOFError(msg)
if not self._seek_check(frame):
return
if isinstance(self._fp, DeferredError):
raise self._fp.ex

Check warning on line 183 in src/PIL/SpiderImagePlugin.py

View check run for this annotation

Codecov / codecov/patch

src/PIL/SpiderImagePlugin.py#L182-L183

Added lines #L182 - L183 were not covered by tests
self.stkoffset = self.hdrlen + frame * (self.hdrlen + self.imgbytes)
self.fp = self._fp
self.fp.seek(self.stkoffset)
Expand Down
4 changes: 3 additions & 1 deletion src/PIL/TiffImagePlugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
from ._binary import o8
from ._deprecate import deprecate
from ._typing import StrOrBytesPath
from ._util import is_path
from ._util import DeferredError, is_path
from .TiffTags import TYPES

if TYPE_CHECKING:
Expand Down Expand Up @@ -1212,6 +1212,8 @@ def seek(self, frame: int) -> None:
self._im = None

def _seek(self, frame: int) -> None:
if isinstance(self._fp, DeferredError):
raise self._fp.ex
self.fp = self._fp

while len(self._frame_pos) <= frame:
Expand Down

0 comments on commit a136095

Please sign in to comment.