From dc15c81e67da4df932233c3c40f6fada206c71e3 Mon Sep 17 00:00:00 2001
From: Eugen Rochko <eugen@zeonfederated.com>
Date: Mon, 9 Mar 2020 02:19:07 +0100
Subject: [PATCH] Change video uploads to enforce certain limits (#13218)

- Dimensions at most 1920x1200
- Frame rate at most 60
---
 app/models/media_attachment.rb | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/app/models/media_attachment.rb b/app/models/media_attachment.rb
index 3fd4f231c..49e2e5e27 100644
--- a/app/models/media_attachment.rb
+++ b/app/models/media_attachment.rb
@@ -126,6 +126,9 @@ class MediaAttachment < ApplicationRecord
   IMAGE_LIMIT = 10.megabytes
   VIDEO_LIMIT = 40.megabytes
 
+  MAX_VIDEO_MATRIX_LIMIT = 2_304_000 # 1920x1200px
+  MAX_VIDEO_FRAME_RATE   = 60
+
   belongs_to :account,          inverse_of: :media_attachments, optional: true
   belongs_to :status,           inverse_of: :media_attachments, optional: true
   belongs_to :scheduled_status, inverse_of: :media_attachments, optional: true
@@ -223,6 +226,7 @@ class MediaAttachment < ApplicationRecord
   before_create :set_processing
 
   before_post_process :set_type_and_extension
+  before_post_process :check_video_dimensions
 
   before_save :set_meta
 
@@ -295,6 +299,17 @@ class MediaAttachment < ApplicationRecord
     self.processing = delay_processing? ? :queued : :complete
   end
 
+  def check_video_dimensions
+    return unless (video? || gifv?) && file.queued_for_write[:original].present?
+
+    movie = FFMPEG::Movie.new(file.queued_for_write[:original].path)
+
+    return unless movie.valid?
+
+    raise Mastodon::DimensionsValidationError, "#{movie.width}x#{movie.height} videos are not supported" if movie.width * movie.height > MAX_VIDEO_MATRIX_LIMIT
+    raise Mastodon::DimensionsValidationError, "#{movie.frame_rate.to_i}fps videos are not supported" if movie.frame_rate > MAX_VIDEO_FRAME_RATE
+  end
+
   def set_meta
     meta = populate_meta