From 8dc2880a9c7d2e026cda92eb2cd780acfd0772c4 Mon Sep 17 00:00:00 2001
From: Jimmy Cai <hi@jimmycai.com>
Date: Wed, 11 Oct 2023 22:51:42 +0200
Subject: [PATCH] feat: add file types whitelist for image processing (#885)

Add `allowedTypes` and `resizableTypes` to `imageProcessing` configuration

Prior to this commit, SVG images were not processed by `render-image.html` because SVG does not have a physical dimension like JPEG. This logic was done using a conditional.

I have now realised that Hugo can be very slow when resizing `gif` images. So I created this whitelist mechanism:

- `allowedTypes`: image types with width and height attributes
- `resizableTypes`: image types that can be resized

Here's a list of media types: bmp, gif, jpeg, png, svg+xml, tiff, webp

https://gohugo.io/templates/output-formats/#media-types
---
 config/_default/params.yaml                | 11 ++++++++++-
 layouts/_default/_markup/render-image.html | 16 ++++++++++------
 2 files changed, 20 insertions(+), 7 deletions(-)

diff --git a/config/_default/params.yaml b/config/_default/params.yaml
index 0136dd9..17c824d 100644
--- a/config/_default/params.yaml
+++ b/config/_default/params.yaml
@@ -11,7 +11,7 @@ featuredImageField: image
 rssFullContent: true
 
 # Path to favicon, relative to assets folder
-favicon: 
+favicon:
 
 footer:
   # Year when site was first published
@@ -146,6 +146,15 @@ colorScheme:
   default: auto
 
 imageProcessing:
+  allowedTypes:
+    - jpeg
+    - png
+    - gif
+    - webp
+  resizableTypes:
+    - jpeg
+    - png
+    - webp
   cover:
     enabled: true
   content:
diff --git a/layouts/_default/_markup/render-image.html b/layouts/_default/_markup/render-image.html
index 5577736..cdabeb5 100644
--- a/layouts/_default/_markup/render-image.html
+++ b/layouts/_default/_markup/render-image.html
@@ -4,20 +4,24 @@
 {{- $Width := 0 -}}
 {{- $Height := 0 -}}
 {{- $Srcset := "" -}}
-
-{{/* SVG and external images won't work with gallery layout, because their width and height attributes are unknown */}}
+{{- $imageProcessing := .Page.Site.Params.imageProcessing.content.enabled -}}
+{{- $allowedTypes := .Page.Site.Params.ImageProcessing.AllowedTypes -}}
+{{- $resizableTypes := .Page.Site.Params.ImageProcessing.ResizableTypes -}}
 {{- $galleryImage := false -}}
 
 {{- if $image -}}
-	{{- $notSVG := ne (path.Ext .Destination) ".svg" -}}
+	{{- $type := $image.MediaType.SubType -}}
+	{{- $allowed := in $allowedTypes $type -}}
+    {{- $resizable := in $resizableTypes $type -}}
+    {{- $imageProcessing := and $imageProcessing $resizable -}}
 	{{- $Permalink = $image.RelPermalink -}}
 
-	{{- if $notSVG -}}
+	{{- if $allowed -}}
 		{{- $Width = $image.Width -}}
 		{{- $Height = $image.Height -}}
 		{{- $galleryImage = true -}}
 
-		{{- if .Page.Site.Params.imageProcessing.content.enabled -}}
+		{{- if $imageProcessing -}}
 			{{- $small := $image.Resize `480x` -}}
 			{{- $big := $image.Resize `1024x` -}}
 			{{- $Srcset = printf `%s 480w, %s 1024w` $small.RelPermalink $big.RelPermalink -}}
@@ -38,4 +42,4 @@
 		data-flex-grow="{{ div (mul $image.Width 100) $image.Height }}"
 		data-flex-basis="{{ div (mul $image.Width 240) $image.Height }}px"
 	{{ end }}
->
\ No newline at end of file
+>