FIX: Upload's content is the only source of truth for the file type.

This commit is contained in:
Guo Xiang Tan 2018-08-07 13:15:00 +08:00
parent d1860a4f7d
commit 2b57239389
4 changed files with 26 additions and 8 deletions

View File

@ -107,14 +107,12 @@ class UploadsController < ApplicationController
else else
tempfile = file.tempfile tempfile = file.tempfile
filename = file.original_filename filename = file.original_filename
content_type = file.content_type
end end
return { errors: [I18n.t("upload.file_missing")] } if tempfile.nil? return { errors: [I18n.t("upload.file_missing")] } if tempfile.nil?
opts = { opts = {
type: type, type: type,
content_type: content_type,
for_private_message: for_private_message, for_private_message: for_private_message,
pasted: pasted, pasted: pasted,
} }

View File

@ -14,7 +14,6 @@ class UploadCreator
# Available options # Available options
# - type (string) # - type (string)
# - content_type (string)
# - origin (string) # - origin (string)
# - for_group_message (boolean) # - for_group_message (boolean)
# - for_theme (boolean) # - for_theme (boolean)
@ -39,6 +38,10 @@ class UploadCreator
extract_image_info! extract_image_info!
return @upload if @upload.errors.present? return @upload if @upload.errors.present?
image_type = @image_info.type.to_s
basename = File.basename(@filename, File.extname(@filename))
@filename = "#{basename}.#{image_type}"
if @filename[/\.svg$/i] if @filename[/\.svg$/i]
whitelist_svg! whitelist_svg!
elsif !Rails.env.test? elsif !Rails.env.test?
@ -76,7 +79,7 @@ class UploadCreator
@upload.sha1 = sha1 @upload.sha1 = sha1
@upload.url = "" @upload.url = ""
@upload.origin = @opts[:origin][0...1000] if @opts[:origin] @upload.origin = @opts[:origin][0...1000] if @opts[:origin]
@upload.extension = File.extname(@filename)[1..10] @upload.extension = image_type
if FileHelper.is_image?(@filename) if FileHelper.is_image?(@filename)
@upload.width, @upload.height = ImageSizer.resize(*@image_info.size) @upload.width, @upload.height = ImageSizer.resize(*@image_info.size)
@ -91,10 +94,10 @@ class UploadCreator
# store the file and update its url # store the file and update its url
File.open(@file.path) do |f| File.open(@file.path) do |f|
url = Discourse.store.store_upload(f, @upload, @opts[:content_type]) url = Discourse.store.store_upload(f, @upload)
if url.present? if url.present?
@upload.url = url @upload.update!(url: url)
@upload.save
else else
@upload.errors.add(:url, I18n.t("upload.store_failure", upload_id: @upload.id, user_id: user_id)) @upload.errors.add(:url, I18n.t("upload.store_failure", upload_id: @upload.id, user_id: user_id))
end end
@ -154,7 +157,6 @@ class UploadCreator
if File.size(jpeg_tempfile.path) < filesize * 0.85 if File.size(jpeg_tempfile.path) < filesize * 0.85
@file = jpeg_tempfile @file = jpeg_tempfile
@filename = (File.basename(@filename, ".*").presence || I18n.t("image").presence || "image") + ".jpg" @filename = (File.basename(@filename, ".*").presence || I18n.t("image").presence || "image") + ".jpg"
@opts[:content_type] = "image/jpeg"
extract_image_info! extract_image_info!
else else
jpeg_tempfile&.close jpeg_tempfile&.close

BIN
spec/fixtures/images/png_as.jpg vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 B

View File

@ -163,6 +163,24 @@ describe UploadsController do
message = JSON.parse(response.body)["errors"] message = JSON.parse(response.body)["errors"]
expect(message).to contain_exactly(I18n.t("upload.images.size_not_found")) expect(message).to contain_exactly(I18n.t("upload.images.size_not_found"))
end end
describe 'when filename has the wrong extension' do
let(:file) do
Rack::Test::UploadedFile.new(file_from_fixtures("png_as.jpg"))
end
it 'should store the upload with the right extension' do
expect do
post "/uploads.json", params: { file: file, type: "avatar" }
end.to change { Upload.count }.by(1)
upload = Upload.last
expect(upload.extension).to eq('png')
expect(File.extname(upload.url)).to eq('.png')
expect(upload.original_filename).to eq('png_as.png')
end
end
end end
end end