From ab4835cda6b78e8d1eae6c2e3a1bee8ce21bb82b Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Wed, 14 Apr 2021 22:11:59 +1000 Subject: [PATCH] Resolved FIXME by reading mandatory FITS header items --- Tests/images/hopper_naxis_zero.fits | Bin 0 -> 54720 bytes Tests/test_file_fitsstub.py | 23 +++++++++++--- src/PIL/FitsStubImagePlugin.py | 45 +++++++++++++++++++++------- 3 files changed, 54 insertions(+), 14 deletions(-) create mode 100644 Tests/images/hopper_naxis_zero.fits diff --git a/Tests/images/hopper_naxis_zero.fits b/Tests/images/hopper_naxis_zero.fits new file mode 100644 index 0000000000000000000000000000000000000000..580cf3a2c003c6c4998e7c8ac4a1e85926fb6b33 GIT binary patch literal 54720 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 literal 0 HcmV?d00001 diff --git a/Tests/test_file_fitsstub.py b/Tests/test_file_fitsstub.py index 6dc7c4602f5..c77457947ef 100644 --- a/Tests/test_file_fitsstub.py +++ b/Tests/test_file_fitsstub.py @@ -1,3 +1,5 @@ +from io import BytesIO + import pytest from PIL import FitsStubImagePlugin, Image @@ -11,10 +13,8 @@ def test_open(): # Assert assert im.format == "FITS" - - # Dummy data from the stub - assert im.mode == "F" - assert im.size == (1, 1) + assert im.size == (128, 128) + assert im.mode == "L" def test_invalid_file(): @@ -35,6 +35,21 @@ def test_load(): im.load() +def test_truncated_fits(): + # No END to headers + image_data = b"SIMPLE = T" + b" " * 50 + b"TRUNCATE" + with pytest.raises(OSError): + FitsStubImagePlugin.FITSStubImageFile(BytesIO(image_data)) + + +def test_naxis_zero(): + # This test image has been manually hexedited + # to set the number of data axes to zero + with pytest.raises(ValueError): + with Image.open("Tests/images/hopper_naxis_zero.fits"): + pass + + def test_save(): # Arrange with Image.open(TEST_FILE) as im: diff --git a/src/PIL/FitsStubImagePlugin.py b/src/PIL/FitsStubImagePlugin.py index c2ce8651c8a..2e78f7798e5 100644 --- a/src/PIL/FitsStubImagePlugin.py +++ b/src/PIL/FitsStubImagePlugin.py @@ -38,21 +38,46 @@ class FITSStubImageFile(ImageFile.StubImageFile): format_description = "FITS" def _open(self): - offset = self.fp.tell() - if not _accept(self.fp.read(6)): - raise SyntaxError("Not a FITS file") - - # FIXME: add more sanity checks here; mandatory header items - # include SIMPLE, BITPIX, NAXIS, etc. + headers = {} + while True: + header = self.fp.read(80) + if not header: + raise OSError("Truncated FITS file") + break + keyword = header[:8].strip() + if keyword == b"END": + break + value = header[8:].strip() + if value.startswith(b"="): + value = value[1:].strip() + if not headers and (not _accept(keyword) or value != b"T"): + raise SyntaxError("Not a FITS file") + headers[keyword] = value + + naxis = int(headers[b"NAXIS"]) + if naxis == 0: + raise ValueError("No image data") + elif naxis == 1: + self._size = 1, int(headers[b"NAXIS1"]) + else: + self._size = int(headers[b"NAXIS1"]), int(headers[b"NAXIS2"]) + + number_of_bits = int(headers[b"BITPIX"]) + if number_of_bits == 8: + self.mode = "L" + elif number_of_bits == 16: + self.mode = "I" + # rawmode = "I;16S" + elif number_of_bits == 32: + self.mode = "I" + elif number_of_bits in (-32, -64): + self.mode = "F" + # rawmode = "F" if number_of_bits == -32 else "F;64F" self.fp.seek(offset) - # make something up - self.mode = "F" - self._size = 1, 1 - loader = self._load() if loader: loader.open(self)