diff --git a/app/logical/media_file/image.rb b/app/logical/media_file/image.rb index 8da9c066e..175d44deb 100644 --- a/app/logical/media_file/image.rb +++ b/app/logical/media_file/image.rb @@ -40,7 +40,7 @@ class MediaFile::Image < MediaFile def frame_count case file_ext when :gif, :webp - image.get("n-pages") if image.get_fields.include?("n-pages") + n_pages when :png metadata.fetch("PNG:AnimationFrames", 1) when :avif @@ -50,6 +50,13 @@ class MediaFile::Image < MediaFile end end + # @return [Integer, nil] The frame count for gif and webp images, or possibly nil if the file doesn't have a frame count or is corrupt. + def n_pages + image.get("n-pages") + rescue Vips::Error + nil + end + def frame_rate return nil if !is_animated? || frame_count.nil? || duration.nil? || duration == 0 frame_count / duration diff --git a/test/files/gif/corrupt-static.gif b/test/files/gif/corrupt-static.gif new file mode 100644 index 000000000..9b183cbbf Binary files /dev/null and b/test/files/gif/corrupt-static.gif differ diff --git a/test/unit/media_file_test.rb b/test/unit/media_file_test.rb index 6bf8efa56..3e55381f4 100644 --- a/test/unit/media_file_test.rb +++ b/test/unit/media_file_test.rb @@ -471,6 +471,18 @@ class MediaFileTest < ActiveSupport::TestCase assert_equal("89a", @metadata["GIF:GIFVersion"]) assert_equal(6, @metadata.count) end + + should "not raise an exception when reading the frame count" do + @file = MediaFile.open("test/files/gif/corrupt-static.gif") + @metadata = @file.metadata + + assert_equal(true, @file.is_corrupt?) + assert_equal(nil, @file.frame_count) + assert_equal("File format error", @metadata["ExifTool:Error"]) + assert_equal("89a", @metadata["GIF:GIFVersion"]) + assert_equal(6, @metadata.count) + assert_nothing_raised { @file.attributes } + end end context "a corrupt PNG" do