FIX: automatically timeout long running image magick commands (#12670)

Previously certain images may lead to convert / identify to run for unreasonable
amounts of time

This adds a maximum amount of time these commands can run prior to forcing
them to stop
This commit is contained in:
Sam
2021-04-12 13:55:54 +10:00
committed by GitHub
parent b6337b72f1
commit 5deda5ef3e
6 changed files with 37 additions and 9 deletions

View File

@ -125,7 +125,15 @@ class UploadCreator
if is_image
if @image_info.type.to_s == 'svg'
w, h = Discourse::Utils.execute_command("identify", "-format", "%w %h", @file.path).split(' ') rescue [0, 0]
w, h = [0, 0]
begin
w, h = Discourse::Utils
.execute_command("identify", "-format", "%w %h", @file.path, timeout: Upload::MAX_IDENTIFY_SECONDS)
.split(' ')
rescue
# use default 0, 0
end
else
w, h = @image_info.size
end
@ -264,6 +272,7 @@ class UploadCreator
extract_image_info!
end
MAX_CONVERT_FORMAT_SECONDS = 20
def execute_convert(from, to, opts = {})
command = [
"convert",
@ -277,7 +286,11 @@ class UploadCreator
command << "-quality" << opts[:quality].to_s if opts[:quality]
command << to
Discourse::Utils.execute_command(*command, failure_message: I18n.t("upload.png_to_jpg_conversion_failure_message"))
Discourse::Utils.execute_command(
*command,
failure_message: I18n.t("upload.png_to_jpg_conversion_failure_message"),
timeout: MAX_CONVERT_FORMAT_SECONDS
)
end
def should_alter_quality?
@ -354,13 +367,14 @@ class UploadCreator
@image_info.orientation.to_i > 1
end
MAX_FIX_ORIENTATION_TIME = 5
def fix_orientation!
path = @file.path
OptimizedImage.ensure_safe_paths!(path)
path = OptimizedImage.prepend_decoder!(path, nil, filename: "image.#{@image_info.type}")
Discourse::Utils.execute_command('convert', path, '-auto-orient', path)
Discourse::Utils.execute_command('convert', path, '-auto-orient', path, timeout: MAX_FIX_ORIENTATION_TIME)
extract_image_info!
end
@ -458,7 +472,7 @@ class UploadCreator
OptimizedImage.ensure_safe_paths!(@file.path)
command = ["identify", "-format", "%n\\n", @file.path]
frames = Discourse::Utils.execute_command(*command).to_i rescue 1
frames = Discourse::Utils.execute_command(*command, timeout: Upload::MAX_IDENTIFY_SECONDS).to_i rescue 1
frames > 1
else