FEATURE: consider SVG as an image when authorized

This commit is contained in:
Régis Hanol 2014-11-03 19:54:10 +01:00
parent bab4f48eeb
commit bdb78ce76a
5 changed files with 58 additions and 12 deletions

View file

@ -269,7 +269,7 @@ Discourse.Utilities = {
@param {String} path The path @param {String} path The path
**/ **/
isAnImage: function(path) { isAnImage: function(path) {
return (/\.(png|jpg|jpeg|gif|bmp|tif|tiff)$/i).test(path); return (/\.(png|jpg|jpeg|gif|bmp|tif|tiff|svg|webp)$/i).test(path);
}, },
/** /**
@ -279,7 +279,7 @@ Discourse.Utilities = {
**/ **/
allowsAttachments: function() { allowsAttachments: function() {
return Discourse.Utilities.authorizesAllExtensions() || return Discourse.Utilities.authorizesAllExtensions() ||
!(/((png|jpg|jpeg|gif|bmp|tif|tiff)(,\s)?)+$/i).test(Discourse.Utilities.authorizedExtensions()); !(/((png|jpg|jpeg|gif|bmp|tif|tiff|svg|webp)(,\s)?)+$/i).test(Discourse.Utilities.authorizedExtensions());
}, },
displayErrorForUpload: function(data) { displayErrorForUpload: function(data) {

View file

@ -31,9 +31,16 @@ class OptimizedImage < ActiveRecord::Base
extension = File.extname(original_path) extension = File.extname(original_path)
temp_file = Tempfile.new(["discourse-thumbnail", extension]) temp_file = Tempfile.new(["discourse-thumbnail", extension])
temp_path = temp_file.path temp_path = temp_file.path
original_path += "[0]" unless opts[:allow_animation]
if resize(original_path, temp_path, width, height) if extension =~ /\.svg$/i
FileUtils.cp(original_path, temp_path)
resized = true
else
original_path << "[0]" unless opts[:allow_animation]
resized = resize(original_path, temp_path, width, height)
end
if resized
thumbnail = OptimizedImage.create!( thumbnail = OptimizedImage.create!(
upload_id: upload.id, upload_id: upload.id,
sha1: Digest::SHA1.file(temp_path).hexdigest, sha1: Digest::SHA1.file(temp_path).hexdigest,

View file

@ -75,13 +75,24 @@ class Upload < ActiveRecord::Base
# deal with width & height for images # deal with width & height for images
if FileHelper.is_image?(filename) if FileHelper.is_image?(filename)
begin begin
if filename =~ /\.svg$/i
svg = Nokogiri::XML(file).at_css("svg")
width, height = svg["width"].to_i, svg["height"].to_i
if width == 0 || height == 0
upload.errors.add(:base, I18n.t("upload.images.size_not_found"))
else
upload.width, upload.height = ImageSizer.resize(width, height)
end
else
# fix orientation first # fix orientation first
Upload.fix_image_orientation(file.path) Upload.fix_image_orientation(file.path)
# retrieve image info # retrieve image info
image_info = FastImage.new(file, raise_on_failure: true) image_info = FastImage.new(file, raise_on_failure: true)
# compute image aspect ratio # compute image aspect ratio
upload.width, upload.height = ImageSizer.resize(*image_info.size) upload.width, upload.height = ImageSizer.resize(*image_info.size)
# make sure we're at the beginning of the file (FastImage moves the pointer) end
# make sure we're at the beginning of the file
# (FastImage and Nokogiri move the pointer)
file.rewind file.rewind
rescue FastImage::ImageFetchFailure rescue FastImage::ImageFetchFailure
upload.errors.add(:base, I18n.t("upload.images.fetch_failure")) upload.errors.add(:base, I18n.t("upload.images.fetch_failure"))

3
spec/fixtures/images/image.svg vendored Normal file
View file

@ -0,0 +1,3 @@
<svg width="100" height="50">
<text x="25" y="25">Discourse</text>
</svg>

After

Width:  |  Height:  |  Size: 76 B

View file

@ -15,11 +15,15 @@ describe Upload do
let(:user_id) { 1 } let(:user_id) { 1 }
let(:url) { "http://domain.com" } let(:url) { "http://domain.com" }
let(:image) { file_from_fixtures("logo.png") }
let(:image_filename) { "logo.png" } let(:image_filename) { "logo.png" }
let(:image) { file_from_fixtures(image_filename) }
let(:image_filesize) { File.size(image) } let(:image_filesize) { File.size(image) }
let(:image_sha1) { Digest::SHA1.file(image).hexdigest } let(:image_sha1) { Digest::SHA1.file(image).hexdigest }
let(:image_svg_filename) { "image.svg" }
let(:image_svg) { file_from_fixtures(image_svg_filename) }
let(:image_svg_filesize) { File.size(image_svg) }
let(:attachment_path) { __FILE__ } let(:attachment_path) { __FILE__ }
let(:attachment) { File.new(attachment_path) } let(:attachment) { File.new(attachment_path) }
let(:attachment_filename) { File.basename(attachment_path) } let(:attachment_filename) { File.basename(attachment_path) }
@ -96,6 +100,27 @@ describe Upload do
upload.url.should == url upload.url.should == url
end end
context "when svg is authorized" do
before { SiteSetting.stubs(:authorized_extensions).returns("svg") }
it "consider SVG as an image" do
store = {}
Discourse.expects(:store).returns(store)
store.expects(:store_upload).returns(url)
upload = Upload.create_for(user_id, image_svg, image_svg_filename, image_svg_filesize)
upload.user_id.should == user_id
upload.original_filename.should == image_svg_filename
upload.filesize.should == image_svg_filesize
upload.width.should == 100
upload.height.should == 50
upload.url.should == url
end
end
end end
context ".get_from_url" do context ".get_from_url" do