melinath / django-daguerre

On-the-fly image manipulation for Django.
http://django-daguerre.readthedocs.org/
BSD 3-Clause "New" or "Revised" License
85 stars 15 forks source link

Don't choke on invalid images (such as PSD files.) #26

Closed melinath closed 11 years ago

melinath commented 11 years ago

It turns out that PSD files can be read by PIL, but not written - and they don't play nice with the way that django tries to introspect image width and height. Normally this would be caught when trying to upload an image in the first place. However, if the PSD is uploaded by other methods (such as a FileField or similar) and then adjusted by daguerre, it causes problems.

I think there are two potential solutions: One, catch some/any exceptions during path setting and raise a DoesNotExist, or two, check for specific file endings on the file storage paths. I prefer option one, with specific exceptions. (In this case TypeError.)

TypeError: 'NoneType' object is unsubscriptable

Stacktrace (most recent call last):

  File "django/core/handlers/base.py", line 178, in get_response
    signals.got_request_exception.send(sender=self.__class__, request=request)

  File "django/template/response.py", line 104, in render
    self._set_content(self.rendered_content)

  File "django/template/response.py", line 81, in rendered_content
    content = template.render(context)

  File "django/template/base.py", line 142, in render
    context.render_context.pop()

  File "django/template/base.py", line 134, in _render
    return self.nodelist.render(context)

  File "django/template/base.py", line 823, in render
    bit = self.render_node(node, context)

  File "django/template/base.py", line 837, in render_node
    return node.render(context)

  File "django/template/loader_tags.py", line 123, in render
    return compiled_parent._render(context)

  File "django/template/base.py", line 134, in _render
    return self.nodelist.render(context)

  File "django/template/base.py", line 823, in render
    bit = self.render_node(node, context)

  File "django/template/base.py", line 837, in render_node
    return node.render(context)

  File "django/template/loader_tags.py", line 123, in render
    return compiled_parent._render(context)

  File "django/template/base.py", line 134, in _render
    return self.nodelist.render(context)

  File "django/template/base.py", line 823, in render
    bit = self.render_node(node, context)

  File "django/template/base.py", line 837, in render_node
    return node.render(context)

  File "django/template/loader_tags.py", line 62, in render
    result = block.nodelist.render(context)

  File "django/template/base.py", line 823, in render
    bit = self.render_node(node, context)

  File "django/template/base.py", line 837, in render_node
    return node.render(context)

  File "django/template/loader_tags.py", line 62, in render
    result = block.nodelist.render(context)

  File "django/template/base.py", line 823, in render
    bit = self.render_node(node, context)

  File "django/template/base.py", line 837, in render_node
    return node.render(context)

  File "django/template/defaulttags.py", line 192, in render
    nodelist.append(node.render(context))

  File "django/template/defaulttags.py", line 192, in render
    nodelist.append(node.render(context))

  File "daguerre/templatetags/daguerre.py", line 38, in render
    pass

  File "daguerre/models.py", line 50, in for_storage_path
    image.image = storage_path

  File "django/db/models/fields/files.py", line 308, in __set__
    self.field.update_dimension_fields(instance, force=True)

  File "django/db/models/fields/files.py", line 378, in update_dimension_fields
    width = file.width

  File "django/core/files/images.py", line 15, in _get_width
    return self._get_image_dimensions()[0]
melinath commented 11 years ago

Another option is to convert all images except for a select few (.gif, .jpg, .png) to .png internally.