From 47f5c23fe87ae17a81d7559b6ecf8d2e5556c6fb Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Wed, 8 May 2019 12:05:33 +1000 Subject: [PATCH] Handle unexpected ICO image sizes --- Tests/images/hopper_unexpected.ico | Bin 0 -> 1406 bytes Tests/test_file_ico.py | 7 +++++++ src/PIL/IcoImagePlugin.py | 19 +++++++++++++++---- 3 files changed, 22 insertions(+), 4 deletions(-) create mode 100644 Tests/images/hopper_unexpected.ico diff --git a/Tests/images/hopper_unexpected.ico b/Tests/images/hopper_unexpected.ico new file mode 100644 index 0000000000000000000000000000000000000000..639828ae0452648d95902e7998d5785ae39fc137 GIT binary patch literal 1406 zcmbtTX;>Ro6g^pICdo|Jk^~wE84?IhLRrHSAZ!6@Tc{${g4#-Ji>M$}Dp+i7U9d>4 zLVjx@>d1#a=120i zAytn=;^roM;CDEY;_`!0v5?E6T6K2F=*)7_fc_jS`Z6roEWvLx!kgfPK((_<2CO~+ zjkyvUQv_nwJ~(nmAS5)yD7IoveilY69N1o-jG?d-(NZVW)B~vosSj$3?+R^!J%1X> zC3}(6FpHe}S$Jw@;Vhm)cQ_LhH6o%B4@N587$XR*4jkpq5(>*!AggH?>>2H_1V#~` z9);Dt4d(O_WK{GKFBQYYjaCsV+!(F&Ktp%T(A_CyT4a?DBcXa23R45(vPawOrlPQ@7IqhZuY^|eudlBjP6$f$QxuN~QaP_P+bO?AjCTNRV5 zPOU--`ROedF3I-+hLoSmOq*~>0 z8MN3*e8HIbpKtP*P9&{F!eOwi2Ju!KIF>X?HYMezl(hM;pVff`#5uAkCJiY#J<=?l zmEPBPbipI0#Ow;Q?RVBtwubMZx|8wJ@R*ete~4-LhP4vbTO=3;ZCOPkIQ zEn|a1u8!4e*RfzZeeAqi`uDUvbQ$a0#G&y89$M^!H!nfaj z|HF?z{rtu|=)>f8xofo_^-p+it&O=FYu$?YsM)d+)pdf&C9&v+LU3lh;jM zf5VN_H{E>8t$TJ{HWa;l_==IyE61)HpSXJG=JU2}J^z9WFY3Q|+rTA*+b``nv$Jdc zS=}4X?&&>eW8b-(R<1g^W%Zg<)~;(kwe7Ui&uFh-cJwg~$2KlM?)Vi=%_p3AQn;+V zqOvMdT~oX0sKrZ`)-BA;%FfBn3+5LT7KMsSN}b6rF~#jkP4lKN@c9E72BXPrnHOiZ c+2a%DI}(#5fhkpLhUGLQ8$lmy&i|PH0XqQsRR910 literal 0 HcmV?d00001 diff --git a/Tests/test_file_ico.py b/Tests/test_file_ico.py index f6244e0868d..97fb781b35d 100644 --- a/Tests/test_file_ico.py +++ b/Tests/test_file_ico.py @@ -83,3 +83,10 @@ def test_only_save_relevant_sizes(self): self.assertEqual( im_saved.info['sizes'], {(16, 16), (24, 24), (32, 32), (48, 48)}) + + def test_unexpected_size(self): + # This image has been manually hexedited to state that it is 16x32 + # while the image within is still 16x16 + im = self.assert_warning(UserWarning, + Image.open, "Tests/images/hopper_unexpected.ico") + self.assertEqual(im.size, (16, 16)) diff --git a/src/PIL/IcoImagePlugin.py b/src/PIL/IcoImagePlugin.py index c1c0775daf9..0f5c03400eb 100644 --- a/src/PIL/IcoImagePlugin.py +++ b/src/PIL/IcoImagePlugin.py @@ -23,6 +23,7 @@ import struct +import warnings from io import BytesIO from . import Image, ImageFile, BmpImagePlugin, PngImagePlugin @@ -143,14 +144,17 @@ def sizes(self): """ return {(h['width'], h['height']) for h in self.entry} + def getentryindex(self, size, bpp=False): + for (i, h) in enumerate(self.entry): + if size == h['dim'] and (bpp is False or bpp == h['color_depth']): + return i + return 0 + def getimage(self, size, bpp=False): """ Get an image from the icon """ - for (i, h) in enumerate(self.entry): - if size == h['dim'] and (bpp is False or bpp == h['color_depth']): - return self.frame(i) - return self.frame(0) + return self.frame(self.getentryindex(size, bpp)) def frame(self, idx): """ @@ -282,6 +286,13 @@ def load(self): im.load() self.im = im.im self.mode = im.mode + if im.size != self.size: + warnings.warn("Image was not the expected size") + + index = self.ico.getentryindex(self.size) + sizes = list(self.info['sizes']) + sizes[index] = im.size + self.info['sizes'] = set(sizes) self.size = im.size def load_seek(self):