diff --git a/Gemfile b/Gemfile index 2a37757af..af86a8ba9 100644 --- a/Gemfile +++ b/Gemfile @@ -36,6 +36,7 @@ gem 'jquery-rails' gem 'webpacker', '>= 4.0.x' gem 'retriable' gem 'sidekiq' +gem 'marcel' # bookmarks for later, if they are needed # gem 'sidekiq-worker-killer' gem 'sidekiq-unique-jobs' @@ -45,7 +46,6 @@ gem 'request_store' gem 'elasticsearch-model' gem 'elasticsearch-rails' - gem 'mailgun-ruby' # needed for looser jpeg header compat diff --git a/Gemfile.lock b/Gemfile.lock index 24e457839..01d7f2366 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -459,6 +459,7 @@ DEPENDENCIES jquery-rails listen mailgun-ruby + marcel mechanize memoist minitest-ci diff --git a/app/logical/upload_service/utils.rb b/app/logical/upload_service/utils.rb index 9031b1988..01df5085a 100644 --- a/app/logical/upload_service/utils.rb +++ b/app/logical/upload_service/utils.rb @@ -6,18 +6,20 @@ class UploadService IMAGE_TYPES = %i[original large preview crop] def file_header_to_file_ext(file) - # TODO: marcel? - case File.read(file.path, 16) - when /^\xff\xd8/n - "jpg" - when /^GIF87a/, /^GIF89a/ - "gif" - when /^\x89PNG\r\n\x1a\n/n - "png" - when /^\x1a\x45\xdf\xa3/n - "webm" - else - "bin" + File.open file.path do |bin| + mime_type = Marcel::MimeType.for(bin) + case mime_type + when "image/jpeg" + "jpg" + when "image/gif" + "gif" + when "image/png" + "png" + when "video/webm" + "webm" + else + mime_type + end end end @@ -44,11 +46,8 @@ class UploadService image_size = ImageSpec.new(file.path) yield(image_size.width, image_size.height) - elsif upload.file_ext == "bin" - yield(0, 0) - else - raise ArgumentError, "unhandled file type (#{upload.file_ext})" # should not happen + yield(0, 0) end end diff --git a/app/models/post_replacement.rb b/app/models/post_replacement.rb index 9d18d8603..2fb9d1d2d 100644 --- a/app/models/post_replacement.rb +++ b/app/models/post_replacement.rb @@ -38,10 +38,6 @@ class PostReplacement < ApplicationRecord %w(jpg jpeg gif png).include?(file_ext) end - def is_flash? - %w(swf).include?(file_ext) - end - def is_video? %w(webm).include?(file_ext) end @@ -114,8 +110,8 @@ class PostReplacement < ApplicationRecord def update_file_attributes self.file_ext = UploadService::Utils.file_header_to_file_ext(replacement_file) - if file_ext == "bin" - self.errors.add(:base, "Unknown or invalid file format") + if Danbooru.config.max_file_sizes.keys.exclude? file_ext + self.errors.add(:base, "Unknown or invalid file format: #{file_ext}") throw :abort end self.file_size = replacement_file.size diff --git a/app/models/upload.rb b/app/models/upload.rb index 0b7a09516..5d8a2bf25 100644 --- a/app/models/upload.rb +++ b/app/models/upload.rb @@ -15,14 +15,15 @@ class Upload < ApplicationRecord end def validate_file_integrity(record) - if record.file_ext.in?(["jpg", "jpeg", "gif", "png"]) && DanbooruImageResizer.is_corrupt?(record.file.path) + if record.is_image? && DanbooruImageResizer.is_corrupt?(record.file.path) record.errors[:file] << "File is corrupt" end end def validate_file_ext(record) - if record.file_ext == "bin" - record.errors.add(:file_ext, "is invalid (only JPEG, PNG, GIF, and WebM files are allowed") + if Danbooru.config.max_file_sizes.keys.exclude? record.file_ext + record.errors.add(:file_ext, "#{record.file_ext} is invalid (only JPEG, PNG, GIF, and WebM files are allowed") + throw :abort end end @@ -118,10 +119,6 @@ class Upload < ApplicationRecord %w(jpg jpeg gif png).include?(file_ext) end - def is_flash? - %w(swf).include?(file_ext) - end - def is_video? %w(webm).include?(file_ext) end diff --git a/config/danbooru_default_config.rb b/config/danbooru_default_config.rb index aff1f4237..27131cd13 100644 --- a/config/danbooru_default_config.rb +++ b/config/danbooru_default_config.rb @@ -375,13 +375,10 @@ fart' def max_file_sizes { - 'jpg' => 100.megabytes, - 'gif' => 20.megabytes, - 'png' => 100.megabytes, - 'swf' => 0, - 'webm' => 100.megabytes, - 'mp4' => 100.megabytes, - 'zip' => 0 + 'jpg' => 100.megabytes, + 'gif' => 20.megabytes, + 'png' => 100.megabytes, + 'webm' => 100.megabytes } end