Repository: python-pillow/Pillow

Issue:
Issue opening a .ico file
### What did you do?
I tried to open a .ico file from a BytesIO object, to use as the icon for my program.
### What did you expect to happen?
The file would be opened successfully and the icon used for the program
### What actually happened?
An error was raised, specifically `builtins.ValueError: This is not one of the allowed sizes of this image`
### What are your OS, Python and Pillow versions?

* OS: Windows 10
* Python: 3.7.3
* Pillow: 6.0.0

Please include **code** that reproduces the issue and whenever possible, an **image** that demonstrates the issue. Please upload images to GitHub, not to third-party file hosting sites. If necessary, add the image to a zip or tar archive.

The best reproductions are self-contained scripts with minimal dependencies. If you are using a framework such as plone, Django, or buildout, try to replicate the issue just using Pillow. 

```python
from zlib import decompress
from PIL.Image import open as imageopen
from PIL.ImageTk import PhotoImage
from io import BytesIO
icon = b"\xadW\tP\x93g\x1a\xfeAZ\xab\xd5Z\xc5\xda\xd9\x9d\xedj\xdb\xe9\xacV\xa9\xd2Z@Q\xc0**r\x88\x1c\x06\x04\x82\xdc\x87@\x94+ \xe1\x0cG\x12.\tI\x08\x81p\x87p\xdfG\x00\x05\x8a\x80 (xPE\xb4\xd5\xaa\xdd\xba;\xbb\xed\xb8u\xb7;\xbb3\xcf\xbe\t\xb2\xd3\xd9\xedtl\xa7\x7f\xe6\xc9\xfb\xfd\xdf\xff}\xef\xf3^\xff\xf7}?\xc3\xe8\xd1o\x93\x15\xa3\xfdg\xea^g\x98\r\x0c\xc3l&l\"P\xb7\xae\x7f\xe92|u\x11?\xf7\xb2\xb6>\xf8\xf6\xa1\x83\x87\xbd\xecl\xed\xe5\xc7\x1c\x9dF\x9d\x9c\\\x1e:;\xb9<u:\xe6\xfc\xd4\xc1\xc1\xf1\x91\xcda\xdb\xf1\xfd\xfb\x0f\x14\xef1\xdf\xebejb\xf6\x0e\xf3+]vv\xf6\xdb\x9d\x1c\x9d\x14l/\xf6C_\xff@\xf8\xfa\x87\xc0\xdb\'\x04l\x9fPxy\x07\xc3\xc3+\x08\xee\x9e\x01`\xb9\x9f\x84\xebqO\xb8\xb8\xb0`o\x7f\xf4\xe1>\xabOJ\xcdLw\x1b\xffR^g\'\xe77\\]\\\xb3\xfd\xfc\xfc\xff\x19\x16\xc6AhX$N\x9f\x8eAj\xfc\x19\x14\xa4z\xa14\xc3\x0eU\xc2\xa3\xa8\x128\xe8\xda\xf9)l\xf0b\xc2\xe1\xe7\x1f\x0cW76\\]\xdd\xe1\xe8\xe8\xf4/\x8b\xbdVy&;M\xde\xfc9\xdc\xac\xe3n\xc6l\xb6\xf7\x15N\xc4\x19p\"\x13\x10\x1f\xc7\x85B\x10\x8c\xf6\x1cc\xf4\x89~\x87~\xc1K8\x9f\xc9` \x83@R\xd7\x16,G\xbf\xe8\xf7h\xcb\xdd\tyV0N\x85\x86\xc2\xd9\x95\r\x17W\x16\x0e\x1f<<C9\xf9\xe8E\xb8==\xbc\xf6\x05\x07\x85|\xc5\x8d#\xde\x04>\x8a\x84\x1ct\xe5\xbc\x0f\r\x9fAO\x1a\xf1d\xbf\x8ca\xc9\x16\x8c\x96|\x84\xf1\xb2\x9d\x98\xa8\xd8\x891j\x0f\x15nF?=\xeb\xa5q}\xe9z\xe8\xcd\xff\x08\xe2\xf4S\xf0`\x07R,N\xc0\xc1\xfe\xe8\xd7d\xc3\x81\x9f\xe2>\xe9\xedm\x14\x11\x1e\xfe\x84\x97\x98\x86\xf4\xf4\x1c\xd4\xe48\xa3;}\x15:\x92\x88[\xb0\x1a#\xc5&\xb8\\\xed\x8c)\x957.\xd7\xf8`R\xe5\xa3\x93ZL\xd5\xb0I\xba`Da\x8e^\xe1Z\xb4\'2\xd0d\xbd\x8e\x9a\\W\x04\x04r(\x16\xee\xb0\xb7;\xfag\x93\x8fMw\xfc\x18w`\x80\xff\xfa\x88\x88\x88\xa9\x8c\x0c!\x84\xc2s\xa8\x11\x1cA\x0b\x8fA\x0bqwg\x19`Xn\x82\xb12G\x8c)\xed1\xaa\xb4!y\x84\xeemI.\xc1\x8e\xe2q\x14\xe3\xe5N\xb8Xb\x81\x1e\xd1J\xb4\x90\r\xed\xc9\xcbP\x97{\x8cl\x88\xc0q\xd6\t\xd8\xd8\xd8\xce\x90\r\xffW\x0fa\xa1\xa7\x84YYB\xe4\xe6\xcbP\x96\xe5\n5W\x1f\r\t\xc4\x9fB\xbe\x8b\xf41P\xb0\x0eC\x92w0$\xfd\x03\x06\xa5[Hn\xc7\xa0\xcc\x98\xda\x14{\xd9\x87\x18.\xfa\x90\xda[qA\xb2\t\x03\xe7\xd6\xa1Gh\xa0\x9b\xdb@>4&\x18\xa0L\xc8\xa2\xf7%\x10nn\x9e\xb0\xb2\xfc$\xf7\x87\xdc\x14\xf3\xadii\xfc\xbfK\xa4J\x14\xe5\xc4B\x19\xb5\x02*.\xa3\xe3o\"\xff[S\x19tP\xaduf1\xe8\x12\x10Hv\x93\xfe\x1e\xd1\xcb\xe8&\xf4\x08\x17e\x97P\x0f\x9dT\x8bmT\'-\xc94W\xcbM\xa8\x8dcPs\xf65\xe4\xa6\x86\x83\xe5F\xef\xa9\x0b\xeb{S\xd3]\x1f,\xf1scb\xe42Y1\xe4E\xc5\x10GoC\xc9i\x9a\x13\xcf\xa0\xfe\xecs\xfb\x13\x17\xf5h\xa5\xd6\x1e\xdd\xbd\xd66\x92\xcd\xc9\x8b}KR\xfbLk\xf7\x12\xea\x13\x16u)\xcf0(M\xdc\r\xed\xbb|\xc2\x83\x8d\x03\xfb\xadK\xb5\xdc\xb1\xd1Q\x1b\x85Y\x82\xc7\x15U\xb5(\xc8\x8c\x86\xd0\x9fAY\x0c\x03\x15\xd9\xac\xa6yug\x17\xa5:n\xb1\xad\xa2g\xd5Q\xcb\xa0N\xde\x88\xda\x84\r\xa8\xa58\xa9\x97\xc6\xfc\x08\xb4\xdcZ\xff\xcbi\x9e8\xcc\x00\xc2\xe4pZ\xb3\xfc\xe0\xe2\xec\xfa\xc4\xcct\xd7\xbbg\xe3\xe3\xdc\x14\xc5\xa5\xa8\xac\xacA&\xc7\x0c\xf9\xc146\x9aA\x15\xa1Z\xcb\x15\xbbhK\r\xc9\n\x8aKC\xda\xfb\xb8\xac)\xc2\x83\x07\x0f0si\x18u)\xef\xe9\xc6UF.\x8e\xaf\xd1\x82\xe6j\xf3\xa7mWEQ?\xddWh\xf9C\x19\xe4q-\x11\x12\xc2\x81\xa7\xd7I\xaa\x03+/~Z\x9aL\xadn\x84\xb2H\x8a$\xdf\xf5(<E\xba\xb8+Q\xcd{\x17\xb5\x89\xefQ\xdeV\xa1\x8cx\xcb\xa3\xd6\xa0\xab\xf08\x1e\xdd\xbb\x8d\xc7\x0b7\xd1#\xdeE\xeb\xd1\x16\xd4\xf3\xb7\xd2\xb3\xd5h\x12\x9a\xa1.u3\xaa\xe2\xdf\xa4\xb9\xef\xa02\xc6\x808\xd7@\xcd7\xa6\xfb\xb7QJ:$\xe1\x0cDao!.\xfa\x0c\xbcO\xfa\xe3\x88\x8dmInN\xce\xc5\xb6\xd6\x0eHD\x89\xe0y\xbe\xa2\xb3\xb12~\x1df\x86\xdb0\xd2!C)g\x05\x9aD\xfbpe\xa8\x1e}J?4\x0b\xcc\xd0%vEwi0\x14\x11\xaf\xe8l\x9b\xeeS`\xbc\xab\x88\x9e\x99\xe0\xea\xa0\x1a\x13\x17\x9ai\x1d<\x84\xb9\xa9\x01,|6\x87\tM#\x1aD\x87u\xbee\x06\xacA\n7\x0c>\xbeApvv\x19/\x92J\x1euu\xf7#\'\xc5\x0f\t\'(F4\xa6\x88\xb0p\xa5\x1dCMB\xd4&m\xc6\x97\xf7\xefC\xa3\x0c\x82\x9c\xfa\x15a\x0c\xe4d\xe3hS\x1a\xfa\x9b$\xa8\xe0n\xc0\x83\xf994\xe4\x1c\x83,\x90\xc1\x8d\x91s\x98\x18\xa8\xc6\xec\x85||~k\x06\xd5g\xdf\xa6\xdc\xafB\x15o#\n\xc3\xf4\x90\xea\xad\x0f>\xd7\x9b\xd6\x830x\x9c\xf0|\\\xaeT~\xab\xe9\x1bDV<\x0bqn\x0c\xf2C(NT\x03\xb7&\x9b\xd0\xaf\xe6\xe1\xdaP>n_\xbb\x06\xc5\x19C\xc8)~\n\x0e\x03)\x8di\x16\xec\xc4\xad\x1b\xd7\xa1\xce<\x84\x85\xd9Q\xa8\x85N\x90P\xed\xce\x9cO\xc5\xa5\xfe\x16\xdc\x18m\xc4\x80:\x13%\x91\xbf\x81\x92\xfb\x16\x14\x91\xabQ@v\'z0\xe0\xc7\xb2\x10z\x8ar\xc0>\xf9\xb4\xaa\xa2\xe2\xdb\x0b\x83#\xc8\x8cwG\xb4\x0b\x83l\xf2A\x1a\xb1\n\xf7\xae\x0fc\xb0Y\x86/\xe7\'1\xde\xa7\x82$D\x1fE\xc4\xaf\x85\x96\xbf\x86\xf7>\xee\x93\xdf\x9de\xe9\xb8{}\x02\xb5Bg\x14\xf82\xb86,\xc3X_\x194e\xbe\x18nS@\x19k\x8c\xb9\x89\x01\x0c6\x15@\xe4\xa7\xa7\xf315\x86\x85\xb0\xf0(\xf8\xfa\xf8>\xad,/\x7f8\xfc\xe9(D\xc9\xc1\x88p\xa4\xfc\x90\x0e\xe9\xe9\xf5\xb8\xd8\x9c\x07Mi4\xee\xdf\x9a\xc2\xa7\x9d\n]L\x8a#\x16\xa1\xe5o\xc8\xd8\x89\'\x8f\x1fc\\\xd3\x84\xb9\xb1\x0e\xa8\xd2\xacP\x1a\xbd\x9e\xe2\xdf\x81\xa1\xfadHCW\xa1M\xec\x85\x96\x02\xda\x1f\xba\xe4P\xc6oA\xa6\x0f\x83hW\x03$G\xfb\x82C{\xb9\x9f\xaf\xff\xa3re\xe9\xc8\xf8\xf8$dy\x19\x08\xb4{\x19)l\x069\x14\xc7\x82\xd07P\x18\xf4\x1af\x06$\x98\x1c\xea\x83,l\xa5n]*\xa5u\xa4\x90b4\\}\x1a\x7f\xf9\xeb3\xa8R\xf7\xa2(t\xb1\xbf4R\x0f\xc5\x9ce\x90\x93\x8dr\xca\x93\x8cbU\x12\xbd\x12\xf94^D~\xa5z3\xe0\xb8\xacA\x12\x97\x83\xc8\xa88\x9c\xf4\xf6\x19W\xc8\x8b\xa4\x97.M\xa0Q]\x03?\xfbu\x88=\xce\xe0\\\xf8o\xf1\xd9\xf4\x14\xbak\x04\xa8\x8a\xdb\x84\x99\xb1~4\xe6\xb1h\r[\te\xe4r\xd4$\x19\xe3\xab/\xbe\xc0dg!\x94\x9c\x97P\x11kH\xef\x9a\xa1N\x96\x93,\x8bY\x8f\xb2\xd87QJ\xb2\xf8\xccr\xaa;\x06Y~\x8c.\xf6\xe1\xac\xb7\x90\xccK@L\xecY\xda\x0b\xdc\x15\x05\xf9y\xac\xa1\xc1!\x0c\x0f_\xc4i\xef=\x08\xb1\xa3\xfa\xf0Y\x83\xab\x1a\x05\x86U\xc9(\x890DS\xfa\x1e\x0c\xa9\xb2\xd1)\x0e%\x04b\xaa\xa7\x1a\xa3\xf5I\xa8\xa6\xba\xaaM\xd8\x82Z\xde6\xa8yF\xd4\xfe@\x07\x15o;T\t;Pu\xd6\x18e\\#\xca\xa7\xa1\xce\xf7\xb0\xa3\x14\xff\x80CHI\xe1#&\x86\x8bcG\x8fy\xe6f\x8b6\xb6\xb7\xb6>\xbev\xed\x06\xf2\xb3\x12\xe1\xb9\x9fA\x0c\xc5 ?h-ji~c\xaa\x05\xea\x92>DC\xd2\x0e\xb4\t\xac\xe9,\xe2\x80\xd6tZk\x88\xb7%}7Z\xf8\xe6$\xcd\x17\xe5s4\xf3w\xa31\xcd\x1c\r){Q\x9fb\x05)g\x13bY\x0c|l\x0c\xc0O\x88Br2\x1f\xe1\xe1\x9c\xafm\x8f\xd8\xea\xce\xa9\xa5\n\xb9lvf\x16\x83\x17\x06\xe1\xefd\x04_\x1b\x06)\xde\xaf\xea\xf4v\t\xac\x08\x16\xe8\x16\xec%\x98\xd39d7\xc1\x1c}\xd9V\xe8\xcb\xb1\x84FdAm\xcb\xe7\xb0\x82&{\xb1\xafGh\x85^\xd1\'h\xcf\xb4B\x9a\xcfk\xf0=D\xfe{\xec\x82P\x90\x8b\xd4T>\xd8^\xde\x8a\xa5\xfdO\x9c\x97\xbb\xa5\xbf\xaf\xf7\xd9\xed\xdb\xf3(\x16\x8b\xe0b\xb9\x02A\x94\x07\xe9\x99w1Vd\x87!\xf1\x01\x1d>-\xb4\xc6\x88\xc4\x1a\x17\xa5\x071*\xb3&\x1c\xc0\xa8\xf4\x00\xc6\xa8=&\xa3>]\xff\xa1\xe7c\x0ea\xb2\xc4\x11\xf2\xa8\xf7\x10h\xcb\xc0\xc3z-\x04i<\x88\xb2\xf3\xc0\xe5\xc6\xfd\x83\xce\xd4F?<\x03\x94\x95\x14g\xce\xce\xce`v\xf6:\x92\xa2\xfc\xe0\xbcG\x0f\xc1\x0e\xfaP\xa5\x98\xe2f\xbd\x1f\xaeV{`\xba\xd2\rW\xabN`\xa6Z\x0b\x0f\xcc\xd6\x9cx\x0e\x8f\xff\xe2j\x95;\xae\xab\xbcp\xbb1\x10\r\x94\x8b`{=\xb0,\r\x90\x18\x15\x88\xc2B9\x04t\xc6\xf1\xf3\xf5\xcb\xfe\xdf\xf3O\xe1\xb9|\xc3\xa6\xc6\xfa\x89;\xf3\xf3\x98\xb84\x89\xc8\x00G8\xeeb\xe0\x7fD\x0f\x95\x94\xc3\xcf5\xa9xt!\x03\xf7z\x12p\xa7+\x0e\xf3\x9d\\\xdc\xe9\x8c\xd5A\xdb^\xe8\x8a\xa71\x89x<\x98\x89\x07\xfd|\xd4\xa4\xeeG\x80\x8d\x1e\\\xf6\xe8#6\xe48\x8a\x15e\xc4/C\xd4\x99\xa8i\xd6q\xd6\x86\x1f;\x03J\x0b\xf2\xb7j\xba;\xbf\xbaw\xef.&\xc9\x06\xad\xcd\x0e\xbbV\x80e\xc1 -h\x1b\x86k\x12\xf0d\xa6\x19O\xe75xv\xa7\x17\xdf\xcdw\xe1\xbb\x85n<\xbb\xdb\x8b\xbf\xdd\xd1\xe0O\xb3\xad\x18\xa9MDz\xf0v\xb8\xeee\xe0d\xb1\x1a<\xd2Q^Q\reY%\xd2R\xd3\x9ex\xb3\xbd\x8d~\xea\x0c,\x93\x88-4\xbd\xdd\x0f\xef.,\xe0\xfa\xf5\x9bT\x0f9`;l\x87\xed\xc7\x0c\xdc\xac\xf4\x91\xe0\xb3\r\x15\"\x1f\x0c\xd6\xe7a\xaa\xb7\x12S}\xd5\x18j\xc8\xa7>\xda\xbf|>\x80\xbb\xd52\xd8\x9b2\xf0u\xde\x89<a:\xd4uMP\xa9j)\xee\x82?\x06\xf8\xf9\xef{\x91o\x00ia\x81QGk\xf3\xe4\xdc\xdc\r\xdc\xbb\xf79.\x8e\x8c\xe0\x9c \x05\x81,K8\xee]\x03;\x13}8\x9a1p6_\xa6\x83\xa3\x99\x1eq.\xc31\x8b\xb5\x08v\xff\x04\"~\"\xea\xea\x1a\xd0\xde\xd1\x85:u\x1d232\xa7\x82\x83\x82v\xfc\x9co\xa0\"\x89\xd8\xb0\xaa\\\x9992<\xf4\xf7\xf9\xf9\xdb\x98\xa7\xba\xb8<9\x89\x96\x065\x8a\xf2EH\xe7\x9d\xa6:\r@Rt\x00\xbd\xd3\x1c\x14\xe6fAUY\x89\x9e\x9e^\x9c??\x88\xee\xee\x1e\x94+\xcb\xbf\xe7%$\x888\xe1\x11\xeb\x7f\xe9w\xa0\\\"\xde\xaa\xaa\xaa\x90\r\xf4k\xee_\xbd2\x8d\xb9\x9b7\ts\xd0\xaeW\xd3Wfpez\x06S\x97\xa7\xa1]\xc3GF.\xa2\xb7\xa7\x07\xd5U\xd5\x0f\x84\x02\x81<\x9e\xcb5\xfa\xb5\xbe\x83\xc5\xe7\xf26\xcaeR\xb7\xea\xca\nISC\xfdHg{\xdb\xc3\xae\x8e\x8eo:\xdaZ\xbfijl|D\xfb\xe8\x88D,\x96f\xa6\xf3\xdd\xc9\xe7M/\xaa\x17\xf7\x97\x03$\xfe\xcd0\x96\xdf3\xcc\xc6o\x19f\xcd}\x86Y>\xcc0\xcb\xb4Ha\x18\xbd%\xbc\xa8\xce\x1f\xceY\xd2\xa3\xd5\xa9\xd5\xad\xe5\xd0ri9\xb5\xdc\xff\x01\xbc\'\x04\xa2"

dec = decompress(icon, -15)

iconphoto = PhotoImage(imageopen(BytesIO(dec)))
```
Weirdly, the exact same code worked perfectly in Python 3.6. Doing some investigating, it appears that here:
```python
@size.setter
def size(self, value):
    if value not in self.info['sizes']:
        raise ValueError(
            "This is not one of the allowed sizes of this image")
    self._size = value
```
`self.info['sizes']` is being set incorrectly, because the .ico file is 32x32.


Discussion:
When you say that it worked perfectly in Python 3.6, I imagine that you were using an earlier version of Pillow. This error was introduced in Pillow 5.3.0.

I've created PR #3836 to resolve this.
Oh, interesting, thanks!

Resolving patch:
diff --git a/src/PIL/IcoImagePlugin.py b/src/PIL/IcoImagePlugin.py
--- 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,7 +286,15 @@ def load(self):
         im.load()
         self.im = im.im
         self.mode = im.mode
-        self.size = im.size
+        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):
         # Flag the ImageFile.Parser so that it


Test patch:
diff --git a/Tests/images/hopper_unexpected.ico b/Tests/images/hopper_unexpected.ico
new file mode 100644
Binary files /dev/null and b/Tests/images/hopper_unexpected.ico differ
diff --git a/Tests/test_file_ico.py b/Tests/test_file_ico.py
--- 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))