Reputation: 521
I am developing a tool which retrieves a JPG from an API and processes it. The source of the image cannot be trusted and I want to test if the image is a valid JPG (which is the only image type allowed).
I encountered an error with PIL that I am unable to fix. Below is my code:
image = StringIO(base64.b64decode(download['file']))
img = Image.open(image)
if img.verify():
print 'Valid image'
else:
print 'Invalid image'
However, it seems that img.verify() returns None. I can call other functions on the open image like img.size() which returns the size. I get the following output when I try to debug the code:
img = Image.open(image)
print img
print img.size()
print img.verify()
[2018-01-09 20:56:43,715: WARNING/Worker-1] <PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=2577x1715 at 0x7F16E17DC9D0>
[2018-01-09 20:56:43,716: WARNING/Worker-1] (2577, 1715)
[2018-01-09 20:56:43,716: WARNING/Worker-1] None
Has someone encountered the same issue?
Upvotes: 9
Views: 24634
Reputation: 3234
According to the docs, Image#verify (or the PIL docs for verify) raises an exception if there is a problem with the image and does nothing otherwise.
To use #verify
, you probably want something like this:
image = StringIO(base64.b64decode(download['file']))
img = Image.open(image)
try:
img.verify()
print('Valid image')
except Exception:
print('Invalid image')
Additionally, you might want to also check that the image is actually a JPG by looking at the image format:
if img.format == 'JPEG':
print('JPEG image')
else:
print('Invalid image type')
Upvotes: 15
Reputation: 1342
In addition to verify
and checking the .format
field, if you're loading images from untrustworthy (and possibly genuinely malicious) sources over the web, you should worry about zip bombs.
Pillow (but not, I think, original PIL) has a DecompressionBombWarning
which is triggered when an image tries to exceed Image.MAX_IMAGE_PIXELS
(a value you can set yourself, prior to attempting to load an image). The default value of that, on my install, is a very generous 85 Mpixels.
A fuller discussion about this Pillow feature is at this discussion.
Upvotes: 5