mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-12-25 17:36:18 +03:00
Merge pull request #4370 from uploadcare/jpeg-multiple-app13
Handle multiple and malformed JPEG APP13 markers
This commit is contained in:
commit
5965437402
BIN
Tests/images/app13-multiple.jpg
Normal file
BIN
Tests/images/app13-multiple.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 78 KiB |
|
@ -676,6 +676,13 @@ class TestFileJpeg(PillowTestCase):
|
|||
with Image.open("Tests/images/app13.jpg") as im:
|
||||
self.assertNotIn("photoshop", im.info)
|
||||
|
||||
def test_photoshop_malformed_and_multiple(self):
|
||||
with Image.open("Tests/images/app13-multiple.jpg") as im:
|
||||
self.assertIn("photoshop", im.info)
|
||||
self.assertEqual(24, len(im.info["photoshop"]))
|
||||
apps_13_lengths = [len(v) for k, v in im.applist if k == "APP13"]
|
||||
self.assertEqual([65504, 24], apps_13_lengths)
|
||||
|
||||
|
||||
@unittest.skipUnless(is_win32(), "Windows only")
|
||||
class TestFileCloseW32(PillowTestCase):
|
||||
|
|
|
@ -100,30 +100,25 @@ def APP(self, marker):
|
|||
# reassemble the profile, rather than assuming that the APP2
|
||||
# markers appear in the correct sequence.
|
||||
self.icclist.append(s)
|
||||
elif marker == 0xFFED:
|
||||
if s[:14] == b"Photoshop 3.0\x00":
|
||||
blocks = s[14:]
|
||||
# parse the image resource block
|
||||
offset = 0
|
||||
photoshop = {}
|
||||
while blocks[offset : offset + 4] == b"8BIM":
|
||||
elif marker == 0xFFED and s[:14] == b"Photoshop 3.0\x00":
|
||||
# parse the image resource block
|
||||
offset = 14
|
||||
photoshop = self.info.setdefault("photoshop", {})
|
||||
while s[offset : offset + 4] == b"8BIM":
|
||||
try:
|
||||
offset += 4
|
||||
# resource code
|
||||
try:
|
||||
code = i16(blocks, offset)
|
||||
except struct.error:
|
||||
break
|
||||
code = i16(s, offset)
|
||||
offset += 2
|
||||
# resource name (usually empty)
|
||||
name_len = i8(blocks[offset])
|
||||
# name = blocks[offset+1:offset+1+name_len]
|
||||
offset = 1 + offset + name_len
|
||||
if offset & 1:
|
||||
offset += 1
|
||||
name_len = i8(s[offset])
|
||||
# name = s[offset+1:offset+1+name_len]
|
||||
offset += 1 + name_len
|
||||
offset += offset & 1 # align
|
||||
# resource data block
|
||||
size = i32(blocks, offset)
|
||||
size = i32(s, offset)
|
||||
offset += 4
|
||||
data = blocks[offset : offset + size]
|
||||
data = s[offset : offset + size]
|
||||
if code == 0x03ED: # ResolutionInfo
|
||||
data = {
|
||||
"XResolution": i32(data[:4]) / 65536,
|
||||
|
@ -132,10 +127,11 @@ def APP(self, marker):
|
|||
"DisplayedUnitsY": i16(data[12:]),
|
||||
}
|
||||
photoshop[code] = data
|
||||
offset = offset + size
|
||||
if offset & 1:
|
||||
offset += 1
|
||||
self.info["photoshop"] = photoshop
|
||||
offset += size
|
||||
offset += offset & 1 # align
|
||||
except struct.error:
|
||||
break # insufficient data
|
||||
|
||||
elif marker == 0xFFEE and s[:5] == b"Adobe":
|
||||
self.info["adobe"] = i16(s, 5)
|
||||
# extract Adobe custom properties
|
||||
|
|
Loading…
Reference in New Issue
Block a user