Class: UploaderImageDimensionsValidator
- Inherits:
-
ActiveModel::Validations::FileContentTypeValidator
- Object
- ActiveModel::Validations::FileContentTypeValidator
- UploaderImageDimensionsValidator
- Defined in:
- app/validators/uploader_image_dimensions_validator.rb
Instance Method Summary collapse
- #check_validity! ⇒ Object
- #extract_image(file) ⇒ Object
- #validate_each(record, attribute, value) ⇒ Object
- #validate_image_size(record, attribute, file, uploader) ⇒ Object
Methods inherited from ActiveModel::Validations::FileContentTypeValidator
Instance Method Details
#check_validity! ⇒ Object
62 |
# File 'app/validators/uploader_image_dimensions_validator.rb', line 62 def check_validity!; end |
#extract_image(file) ⇒ Object
48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'app/validators/uploader_image_dimensions_validator.rb', line 48 def extract_image(file) return unless file.try(:content_type).to_s.start_with?("image") if uploaded_file?(file) Vips::Image.new_from_file(file.path) elsif file.is_a?(ActiveStorage::Attached) && file.blob.persisted? Vips::Image.new_from_buffer(file.blob.download, "") end rescue ActiveStorage::FileNotFoundError, Vips::Error # Although the blob is persisted, the file is not available to download and analyze # after committing the record nil end |
#validate_each(record, attribute, value) ⇒ Object
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
# File 'app/validators/uploader_image_dimensions_validator.rb', line 9 def validate_each(record, attribute, value) begin values = parse_values(value) rescue JSON::ParserError record.errors.add attribute, :invalid return end return if values.empty? uploader = record.attached_uploader(attribute) || record.send(attribute) return unless uploader.is_a?(Decidim::ApplicationUploader) values.each do |val| validate_image_size(record, attribute, val, uploader) end end |
#validate_image_size(record, attribute, file, uploader) ⇒ Object
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'app/validators/uploader_image_dimensions_validator.rb', line 27 def validate_image_size(record, attribute, file, uploader) return unless uploader.validable_dimensions return if (image = extract_image(file)).blank? # A simple check to avoid DoS with maliciously crafted images, or just to # avoid reckless users that upload images with too many pixels. # # See https://hackerone.com/reports/390 max_dimension = [image.width, image.height].max record.errors.add attribute, I18n.t("decidim.errors.files.file_resolution_too_large") if max_dimension > uploader.max_image_height_or_width rescue Vips::Error # The error may happen because of many reasons but most commonly the image # exceeds the default maximum dimensions set for libvips when the image # fails to load. # # Note that the error can also happen because of other reasons than only # the image dimensions being too large. But as we do not really know the # reason every time, we default to that error. record.errors.add attribute, I18n.t("decidim.errors.files.file_cannot_be_processed") end |