This repository has been archived by the owner on Aug 26, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 19
/
bombshelter.rb
81 lines (66 loc) · 1.99 KB
/
bombshelter.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
require 'carrierwave/bombshelter/version'
require 'fastimage'
require 'i18n'
require 'carrierwave'
files = Dir[File.expand_path(
'../../locale/*.yml', __FILE__
)]
I18n.load_path = files.concat I18n.load_path
module CarrierWave
module BombShelter
FILE_WRAPPERS = [
CarrierWave::SanitizedFile,
CarrierWave::Uploader::Base
]
def self.included(base)
base.class_eval do # or `module_eval`
# `before` puts callback in the end of queue, but we need to run this
# callback first.
# before :cache, :protect_from_image_bomb!
self._before_callbacks = _before_callbacks.merge(
cache: [:protect_from_image_bomb!] + _before_callbacks[:cache]
)
end
end
def max_pixel_dimensions
[4096, 4096]
end
def image_type_whitelist
[:jpeg, :png, :gif]
end
private
def protect_from_image_bomb!(new_file)
image = FastImage.new(get_file(new_file))
check_image_type!(image)
check_pixel_dimensions!(image)
end
def check_image_type!(image)
return if image.type && image_type_whitelist.include?(image.type)
raise CarrierWave::IntegrityError,
I18n.translate(:'errors.messages.unsupported_image_type')
end
def check_pixel_dimensions!(image)
max_sizes = max_pixel_dimensions
return if image.size &&
image.size[0] <= max_sizes[0] &&
image.size[1] <= max_sizes[1]
raise CarrierWave::IntegrityError,
I18n.translate(
:'errors.messages.pixel_dimensions_error',
x_size: max_sizes[0], y_size: max_sizes[1]
)
end
def get_file(file)
return file.url if in_fog?(file)
return get_file(file.file) if is_wrapped?(file)
file
end
def in_fog?(file)
defined?(CarrierWave::Storage::Fog) &&
file.is_a?(CarrierWave::Storage::Fog::File)
end
def is_wrapped?(file)
FILE_WRAPPERS.any? { |wrapper| file.is_a?(wrapper) }
end
end
end