From df0e9bc4a75cd3353885d96c337db7cfa94f9b75 Mon Sep 17 00:00:00 2001 From: evazion Date: Tue, 25 Oct 2022 19:21:32 -0500 Subject: [PATCH] uploads: fix it being possible to upload .mkv files as .webm. Fix it being possible to upload arbitrary .mkv files and have them be treated as .webm. This was possible because WebM uses the Matroska container format, and we only checked for the Matroska header, not that the file was actually a WebM. There were only 6 such files in production: * https://danbooru.donmai.us/posts?tags=exif:Matroska:DocType=matroska * https://danbooru.donmai.us/posts/5522036 * https://danbooru.donmai.us/posts/4743498 * https://danbooru.donmai.us/posts/3925427 * https://danbooru.donmai.us/posts/3147897 * https://danbooru.donmai.us/posts/2965862 * https://danbooru.donmai.us/posts/2430436 These videos are playable in Chrome, but not in Firefox, since Firefox doesn't support .mkv files (it supports some, depending on which codecs are used, but not .mkv files in general). --- app/logical/media_file.rb | 7 ++++++- app/logical/media_file/video.rb | 11 +++++++++++ test/components/post_preview_component_test.rb | 2 +- test/files/webm/test-512x512.mkv | Bin 0 -> 9148 bytes test/files/{ => webm}/test-512x512.webm | Bin test/functional/uploads_controller_test.rb | 9 ++++++++- test/unit/media_file_test.rb | 16 +++++++++++----- test/unit/post_query_builder_test.rb | 2 +- 8 files changed, 38 insertions(+), 9 deletions(-) create mode 100644 test/files/webm/test-512x512.mkv rename test/files/{ => webm}/test-512x512.webm (100%) diff --git a/app/logical/media_file.rb b/app/logical/media_file.rb index 66ea8cdd6..fad6da362 100644 --- a/app/logical/media_file.rb +++ b/app/logical/media_file.rb @@ -54,7 +54,12 @@ class MediaFile :png when /\ACWS/, /\AFWS/, /\AZWS/ :swf - when /\x1a\x45\xdf\xa3/n + + # This detects the Matroska (.mkv) header. WebM files have a DocType of "webm", which is checked later in `MediaFile::Video#is_supported?`. + # + # https://www.rfc-editor.org/rfc/rfc8794.html#section-8.1 + # https://www.webmproject.org/docs/container/ + when /\A\x1a\x45\xdf\xa3/n :webm # https://www.ftyps.com diff --git a/app/logical/media_file/video.rb b/app/logical/media_file/video.rb index 0cc1ca4e3..197f01b3d 100644 --- a/app/logical/media_file/video.rb +++ b/app/logical/media_file/video.rb @@ -15,6 +15,17 @@ class MediaFile::Video < MediaFile preview_frame.preview(max_width, max_height, **options) end + def is_supported? + case file_ext + when :webm + metadata["Matroska:DocType"] == "webm" + when :mp4 + true + else + false + end + end + private def video diff --git a/test/components/post_preview_component_test.rb b/test/components/post_preview_component_test.rb index c32794fa7..06003769a 100644 --- a/test/components/post_preview_component_test.rb +++ b/test/components/post_preview_component_test.rb @@ -20,7 +20,7 @@ class PostPreviewComponentTest < ViewComponent::TestCase context "for a video post" do should "render" do - @post = create(:post_with_file, filename: "test-512x512.webm").reload + @post = create(:post_with_file, filename: "webm/test-512x512.webm").reload node = render_preview(@post, current_user: User.anonymous) assert_equal(post_path(@post), node.css("article a").attr("href").value) diff --git a/test/files/webm/test-512x512.mkv b/test/files/webm/test-512x512.mkv new file mode 100644 index 0000000000000000000000000000000000000000..36664387273dddd1a0d74f60c773a026ebbad492 GIT binary patch literal 9148 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 metatag" do - post = create(:post, media_asset: create(:media_asset, file: "test/files/test-512x512.webm")) + post = create(:post, media_asset: create(:media_asset, file: "test/files/webm/test-512x512.webm")) assert_tag_match([post], "duration:0.48") assert_tag_match([post], "duration:>0.4")