uploads: fix "ArgumentError: string contains null byte" error
Fix an error when trying to upload a file larger than the file size limit. In this case we tried to dump the whole HTTP response into the error message, which included the binary file itself, which caused this exception because it contained null bytes.
This commit is contained in:
@@ -148,12 +148,12 @@ module Danbooru
|
||||
response = get(url)
|
||||
|
||||
raise DownloadError, "Downloading #{response.uri} failed with code #{response.status}" if response.status != 200
|
||||
raise FileTooLargeError, response if @max_size && response.content_length.to_i > @max_size
|
||||
raise FileTooLargeError, "File size too large (size: #{response.content_length.to_i.to_formatted_s(:human_size)}; max size: #{@max_size.to_formatted_s(:human_size)})" if @max_size && response.content_length.to_i > @max_size
|
||||
|
||||
size = 0
|
||||
response.body.each do |chunk|
|
||||
size += chunk.size
|
||||
raise FileTooLargeError if @max_size && size > @max_size
|
||||
raise FileTooLargeError, "File size too large (max size: #{@max_size.to_formatted_s(:human_size)})" if @max_size && size > @max_size
|
||||
file.write(chunk)
|
||||
end
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ class MediaAsset < ApplicationRecord
|
||||
|
||||
validates :md5, uniqueness: { conditions: -> { where(status: [:processing, :active]) } }
|
||||
validates :file_ext, inclusion: { in: %w[jpg png gif mp4 webm swf zip], message: "Not an image or video" }
|
||||
validates :file_size, numericality: { less_than_or_equal_to: Danbooru.config.max_file_size }
|
||||
validates :file_size, numericality: { less_than_or_equal_to: Danbooru.config.max_file_size, message: ->(asset, _) { "too large (size: #{asset.file_size.to_formatted_s(:human_size)}; max size: #{Danbooru.config.max_file_size.to_formatted_s(:human_size)})" } }
|
||||
validates :duration, numericality: { less_than_or_equal_to: MAX_VIDEO_DURATION, message: "must be less than #{MAX_VIDEO_DURATION} seconds", allow_nil: true }, on: :create # XXX should allow admins to bypass
|
||||
validate :validate_resolution, on: :create
|
||||
|
||||
|
||||
@@ -177,18 +177,32 @@ class UploadsControllerTest < ActionDispatch::IntegrationTest
|
||||
assert_match("Not an image or video", Upload.last.error)
|
||||
end
|
||||
|
||||
should "fail if the file size is too large" do
|
||||
skip "flaky test"
|
||||
Danbooru.config.stubs(:max_file_size).returns(1.kilobyte)
|
||||
context "for a file larger than the file size limit" do
|
||||
setup do
|
||||
skip "flaky test"
|
||||
Danbooru.config.stubs(:max_file_size).returns(1.kilobyte)
|
||||
end
|
||||
|
||||
file = Rack::Test::UploadedFile.new("test/files/test.jpg")
|
||||
post_auth uploads_path(format: :json), @user, params: { upload: { file: file }}
|
||||
perform_enqueued_jobs
|
||||
should "fail for a direct file upload" do
|
||||
create_upload!("test/files/test.jpg", user: @user)
|
||||
|
||||
assert_response 201
|
||||
assert_match("File size must be less than or equal to", Upload.last.error)
|
||||
assert_response 201
|
||||
assert_match("File size too large", Upload.last.error)
|
||||
end
|
||||
|
||||
Danbooru.config.unstub(:max_file_size)
|
||||
should "fail for a source upload with a Content-Length header" do
|
||||
create_upload!("https://nghttp2.org/httpbin/bytes/2000", user: @user)
|
||||
|
||||
assert_response 201
|
||||
assert_match("File size too large", Upload.last.error)
|
||||
end
|
||||
|
||||
should "fail for a source upload without a Content-Length header" do
|
||||
create_upload!("https://nghttp2.org/httpbin/stream-bytes/2000", user: @user)
|
||||
|
||||
assert_response 201
|
||||
assert_match("File size too large", Upload.last.error)
|
||||
end
|
||||
end
|
||||
|
||||
context "for a corrupted image" do
|
||||
|
||||
Reference in New Issue
Block a user