uploads: fix corrupted image detection.

* Fix corrupted image detection. We were shelling out to vips and trying
  to grep for error messages, but the error message for jpeg files changed.
  Now we load the file in ruby vips, which raises an error on failure.

* Don't attempt to redownload corrupted images. If a download completes
  without any errors yet the downloaded file is corrupt, then something is
  wrong at the source and redownloading is unlikely to help. Let the
  upload fail and the user retry if necessary.

* Validate that all uploads are uncorrupted, including files uploaded
  from a computer, not just files uploaded from a source.
This commit is contained in:
evazion
2020-04-13 14:05:21 -05:00
parent cc31eeafa4
commit dc6575dc76
7 changed files with 48 additions and 56 deletions

BIN
test/files/test-corrupt.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

BIN
test/files/test-corrupt.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 B

View File

@@ -1,4 +1,8 @@
module UploadTestHelper
def upload_from_file(filepath)
UploadService.new(file: upload_file(filepath)).start!
end
def upload_file(path)
file = Tempfile.new(binmode: true)
IO.copy_stream("#{Rails.root}/#{path}", file.path)

View File

@@ -34,28 +34,6 @@ class UploadServiceTest < ActiveSupport::TestCase
end
end
context "for a corrupt jpeg" do
setup do
@source = "https://cdn.donmai.us/original/93/f4/93f4dd66ef1eb11a89e56d31f9adc8d0.jpg"
@mock_upload = mock("upload")
@mock_upload.stubs(:source_url).returns(@source)
@mock_upload.stubs(:referer_url).returns(nil)
@bad_file = File.open("#{Rails.root}/test/files/test-corrupt.jpg", "rb")
Downloads::File.any_instance.stubs(:download!).returns([@bad_file, nil])
end
teardown do
@bad_file.close
end
should "retry three times" do
DanbooruImageResizer.expects(:validate_shell).times(4).returns(false)
assert_raise(UploadService::Utils::CorruptFileError) do
subject.get_file_for_upload(@mock_upload)
end
end
end
context "for a pixiv" do
setup do
@source = "http://www.pixiv.net/member_illust.php?mode=medium&illust_id=62247350"
@@ -1133,6 +1111,33 @@ class UploadServiceTest < ActiveSupport::TestCase
assert_equal("http://www.example.com", @upload.source)
end
end
context "for a corrupted image" do
should "fail for a corrupted jpeg" do
@bad_jpeg_path = "test/files/test-corrupt.jpg"
upload = upload_from_file(@bad_jpeg_path)
assert_match(/corrupt/, upload.status)
assert_equal(true, UploadService::Utils.corrupt?(@bad_jpeg_path))
end
should "fail for a corrupted gif" do
@bad_gif_path = "test/files/test-corrupt.gif"
upload = upload_from_file(@bad_gif_path)
assert_match(/corrupt/, upload.status)
assert_equal(true, UploadService::Utils.corrupt?(@bad_gif_path))
end
# https://schaik.com/pngsuite/pngsuite_xxx_png.html
should "fail for a corrupted png" do
@bad_png_path = "test/files/test-corrupt.png"
upload = upload_from_file(@bad_png_path)
assert_match(/corrupt/, upload.status)
assert_equal(true, UploadService::Utils.corrupt?(@bad_png_path))
end
end
end
context "#create_post_from_upload" do