FIX: Allow SVG uploads if dimensions are a fraction of a unit (#13409)

* FIX: Allow SVG uploads if dimensions are a fraction of a unit

`UploadCreator` counts the number of pixels in an file to determine if it is valid. `pixels` is calculated by multiplying the width and height of the image, as determined by FastImage.

SVG files can have their width/height expressed in a variety of different units of measurement. For example, ‘px’, ‘in’, ‘cm’, ‘mm’, ‘pt’, ‘pc’, etc are all valid within SVG files. If an image has a width of `0.5in`, FastImage may interpret this as being a width of `0`, meaning it will report the `size` as being `0`.

However, we don’t need to concern ourselves with the number of ‘pixels’ in a SVG files, as that is irrelevant for this file format, so we can skip over the check for `pixels == 0` when processing this file type.

* DEV: Speed up getting SVG dimensions

The `-ping` flag prevents the entire image from being rasterized before a result is returned. See:

https://imagemagick.org/script/command-line-options.php#ping
This commit is contained in:
jbrw
2021-06-17 15:56:11 -04:00
committed by GitHub
parent 04a3cd3814
commit fbfd1fd80b
6 changed files with 69 additions and 254 deletions

View File

@ -131,7 +131,7 @@ class UploadCreator
begin
w, h = Discourse::Utils
.execute_command("identify", "-format", "%w %h", @file.path, timeout: Upload::MAX_IDENTIFY_SECONDS)
.execute_command("identify", "-ping", "-format", "%w %h", @file.path, timeout: Upload::MAX_IDENTIFY_SECONDS)
.split(' ')
rescue
# use default 0, 0
@ -194,7 +194,7 @@ class UploadCreator
@upload.errors.add(:base, I18n.t("upload.images.not_supported_or_corrupted"))
elsif filesize <= 0
@upload.errors.add(:base, I18n.t("upload.empty"))
elsif pixels == 0
elsif pixels == 0 && @image_info.type.to_s != 'svg'
@upload.errors.add(:base, I18n.t("upload.images.size_not_found"))
elsif max_image_pixels > 0 && pixels >= max_image_pixels * 2
@upload.errors.add(:base, I18n.t("upload.images.larger_than_x_megapixels", max_image_megapixels: SiteSetting.max_image_megapixels * 2))