Skip to content

Commit

Permalink
Use correct extension for thumbnails, fixes #54
Browse files Browse the repository at this point in the history
  • Loading branch information
johanneswilm committed Aug 16, 2022
1 parent 210b54c commit 39f8681
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 14 deletions.
25 changes: 11 additions & 14 deletions avatar/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,22 +34,21 @@ def avatar_path_handler(
if not filename:
# Filename already stored in database
filename = instance.avatar.name
if ext and settings.AVATAR_HASH_FILENAMES:
# An extension was provided, probably because the thumbnail
# is in a different format than the file. Use it. Because it's
# only enabled if AVATAR_HASH_FILENAMES is true, we can trust
# it won't conflict with another filename
if ext:
(root, oldext) = os.path.splitext(filename)
filename = root + "." + ext.lower()
else:
# File doesn't exist yet
(root, oldext) = os.path.splitext(filename)
if settings.AVATAR_HASH_FILENAMES:
(root, ext) = os.path.splitext(filename)
if settings.AVATAR_RANDOMIZE_HASHES:
filename = binascii.hexlify(os.urandom(16)).decode("ascii")
root = binascii.hexlify(os.urandom(16)).decode("ascii")
else:
filename = hashlib.md5(force_bytes(filename)).hexdigest()
filename = filename + ext
root = hashlib.md5(force_bytes(root)).hexdigest()
if ext:
filename = root + "." + ext.lower()
else:
filename = root + oldext.lower()
if width or height:
tmppath.extend(["resized", str(width), str(height)])
tmppath.append(os.path.basename(filename))
Expand All @@ -70,15 +69,15 @@ def find_extension(format):

class AvatarField(models.ImageField):
def __init__(self, *args, **kwargs):
super(AvatarField, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)

self.max_length = 1024
self.upload_to = avatar_file_path
self.storage = avatar_storage
self.blank = True

def deconstruct(self):
name, path, args, kwargs = super(models.ImageField, self).deconstruct()
name, path, args, kwargs = super().deconstruct()
return name, path, (), {}


Expand Down Expand Up @@ -116,7 +115,7 @@ def save(self, *args, **kwargs):
avatars.update(primary=False)
else:
avatars.delete()
super(Avatar, self).save(*args, **kwargs)
super().save(*args, **kwargs)

def thumbnail_exists(self, width, height=None):
return self.avatar.storage.exists(self.avatar_name(width, height))
Expand Down Expand Up @@ -162,8 +161,6 @@ def create_thumbnail(self, width, height=None, quality=None):
else:
thumb_file = File(orig)
thumb_name = self.avatar_name(width, height)
if self.avatar.storage.exists(thumb_name):
self.avatar.storage.delete(thumb_name)
thumb = self.avatar.storage.save(thumb_name, thumb_file)
except IOError:
thumb_file = File(orig)
Expand Down
1 change: 1 addition & 0 deletions avatar/templatetags/avatar_tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ def avatar_url(user, width=settings.AVATAR_DEFAULT_SIZE, height=None):
avatar_url = provider.get_avatar_url(user, width, height)
if avatar_url:
return avatar_url
return get_default_avatar_url()


@cache_result()
Expand Down
9 changes: 9 additions & 0 deletions docs/index.txt
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,15 @@ appear on the site. Listed below are those settings:
Path to the Django template to use for confirming a delete of a user's
avatar. Defaults to ``avatar/avatar/confirm_delete.html``.

.. py:data:: AVATAR_ALLOWED_MIMETYPES

Limit allowed avatar image uploads by their actual content payload and what image codecs we wish to support.
This limits website user content site attack vectors against image codec buffer overflow and similar bugs.
`You must have python-imaging library installed <https://github.com/ahupp/python-magic>`_.
Suggested safe setting: ``("image/png", "image/gif", "image/jpeg")``.
When enabled you'll get the following error on the form upload *File content is invalid. Detected: image/tiff Allowed content types are: image/png, image/gif, image/jpg*.


Management Commands
-------------------

Expand Down
6 changes: 6 additions & 0 deletions tests/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,12 @@ def test_automatic_thumbnail_creation_CMYK(self):
)
self.assertEqual(image.mode, "RGB")

def test_automatic_thumbnail_creation_image_type_conversion(self):
upload_helper(self, "django_pony_cmyk.jpg")
self.assertMediaFileExists(
f"/avatars/{self.user.id}/resized/80/80/django_pony_cmyk.png"
)

def test_thumbnail_transpose_based_on_exif(self):
upload_helper(self, "image_no_exif.jpg")
avatar = get_primary_avatar(self.user)
Expand Down

0 comments on commit 39f8681

Please sign in to comment.