don't create thumbnails for very large images

test plan:
 1. enable new files
 2. upload a sane-sized image file (jpg/gif/png)
    with less than 100 million pixels
 3. within a minute or so, a thumbnail image should
    be generated for the image, and visible after the
    new files page refreshes
 4. upload an image with more than 100 million pixels
    (the size of the file in bytes isn't relevant;
     you can use 100mpx.png, attached to the ticket,
     which is a 12800x8000 image which compresses down
     to 13K because it's solid blackness).
    Canvas should not generate a thumbnail for it.
    A generic icon should be used (not a solid black
    square).

fixes CNVS-17995

Change-Id: Ie5ed1f57de65fa105cb3f23ceb0b895b676375fe
Reviewed-on: https://gerrit.instructure.com/48973
Tested-by: Jenkins
Reviewed-by: James Williams  <jamesw@instructure.com>
QA-Review: Jahnavi Yetukuri <jyetukuri@instructure.com>
Product-Review: Jeremy Stanley <jeremy@instructure.com>
This commit is contained in:
Jeremy Stanley 2015-02-18 11:33:40 -07:00
parent d9dec69f83
commit c2719cabe1
7 changed files with 30 additions and 3 deletions

View File

@ -223,7 +223,6 @@ class Attachment < ActiveRecord::Base
# try an infer encoding if it would be useful to do so
send_later(:infer_encoding) if self.encoding.nil? && self.content_type =~ /text/ && self.context_type != 'SisBatch'
if respond_to?(:process_attachment_with_processing, true) && thumbnailable? && !attachment_options[:thumbnails].blank? && parent_id.nil?
temp_file = temp_path || create_temp_file
self.class.attachment_options[:thumbnails].each { |suffix, size| send_later_if_production(:create_thumbnail_size, suffix) }
end
end

View File

@ -30,7 +30,8 @@ class Thumbnail < ActiveRecord::Base
:storage => (Attachment.local_storage? ? :file_system : :s3),
:path_prefix => Attachment.file_store_config['path_prefix'],
:s3_access => :private,
:keep_profile => true
:keep_profile => true,
:thumbnail_max_image_size_pixels => Setting.get('thumbnail_max_image_size_pixels', 100_000_000)
)
before_save :set_namespace

View File

@ -281,6 +281,8 @@ module AttachmentFu # :nodoc:
res = self.create_or_update_thumbnail(tmp, target_size.to_s, actual_size)
rescue AWS::S3::Errors::NoSuchKey => e
logger.warn("error when trying to make thumbnail for attachment_id: #{self.id} (the image probably doesn't exist on s3) error details: #{e.inspect}")
rescue ThumbnailError => e
logger.warn("error creating thumbnail for attachment_id #{self.id}: #{e.inspect}")
ensure
tmp.unlink if tmp
end

View File

@ -28,6 +28,8 @@ module AttachmentFu # :nodoc:
def process_attachment_with_processing
return unless process_attachment_without_processing
with_image do |img|
max_image_size = attachment_options[:thumbnail_max_image_size_pixels]
raise ThumbnailError.new("source image too large") if max_image_size && img[:width] * img[:height] > max_image_size
resize_image_or_thumbnail! img
self.width = img[:width] if respond_to?(:width)
self.height = img[:height] if respond_to?(:height)

View File

@ -81,10 +81,15 @@ def stub_png_data(filename = 'test my file? hai!&.png', data = nil)
end
def jpeg_data_frd
fixture_path = '/test_image.jpg'
fixture_path = 'test_image.jpg'
fixture_file_upload(fixture_path, 'image/jpeg', true)
end
def one_hundred_megapixels_of_highly_compressed_png_data
fixture_path = '100mpx.png'
fixture_file_upload(fixture_path, 'image/png', true)
end
def crocodocable_attachment_model(opts={})
attachment_model({:content_type => 'application/pdf'}.merge(opts))
end

BIN
spec/fixtures/100mpx.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -983,6 +983,24 @@ describe Attachment do
end
end
describe "thumbnail source image size limitation" do
before(:once) do
local_storage! # s3 attachment data is stubbed out, so there is no image to identify the size of
course
end
it 'creates thumbnails for smaller images' do
att = @course.attachments.create! :uploaded_data => jpeg_data_frd, :filename => 'ok.jpg'
expect(att.thumbnail).not_to be_nil
expect(att.thumbnail.width).not_to be_nil
end
it 'does not create thumbnails for larger images' do
att = @course.attachments.create! :uploaded_data => one_hundred_megapixels_of_highly_compressed_png_data, :filename => '3vil.png'
expect(att.thumbnail).to be_nil
end
end
context "notifications" do
before :once do
course_model(:workflow_state => "available")