carrierwave 2.0.0 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of carrierwave might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/README.md +61 -35
- data/lib/carrierwave/downloader/base.rb +42 -5
- data/lib/carrierwave/downloader/remote_file.rb +31 -8
- data/lib/carrierwave/locale/en.yml +5 -4
- data/lib/carrierwave/mounter.rb +4 -3
- data/lib/carrierwave/processing.rb +1 -0
- data/lib/carrierwave/processing/mini_magick.rb +1 -1
- data/lib/carrierwave/processing/rmagick.rb +10 -4
- data/lib/carrierwave/processing/vips.rb +284 -0
- data/lib/carrierwave/sanitized_file.rb +13 -5
- data/lib/carrierwave/storage/fog.rb +23 -6
- data/lib/carrierwave/uploader/cache.rb +1 -1
- data/lib/carrierwave/uploader/content_type_blacklist.rb +17 -8
- data/lib/carrierwave/uploader/content_type_whitelist.rb +20 -8
- data/lib/carrierwave/uploader/extension_blacklist.rb +18 -10
- data/lib/carrierwave/uploader/extension_whitelist.rb +19 -10
- data/lib/carrierwave/uploader/url.rb +6 -3
- data/lib/carrierwave/uploader/versions.rb +1 -1
- data/lib/carrierwave/version.rb +1 -1
- data/lib/generators/templates/uploader.rb +2 -2
- metadata +37 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a6e511db9d3eebc43bd42613884cf42ba2ad5f236a438a609cccc67c6ce3d192
|
4
|
+
data.tar.gz: 20cef424394b5a40d27e73e8677161870c6d35f60734fd05cf2d0666f461b834
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 28aeace46926db2716ac4600a67cb3a318c553f8f04f533fcf19afaddbafc46489bc3df5d523bc878f5b77164d4110c69ddfe346944caeb46b0dd83df39d7ac9
|
7
|
+
data.tar.gz: dc271f6fdfd5a515295185265a53b0b894ecef7e1d72bdcaa062357dacd5c7e9bca54a818ffcd344a95b341628451f5b6e579b62587845148075f9db9de949f7
|
data/README.md
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
This gem provides a simple and extremely flexible way to upload files from Ruby applications.
|
4
4
|
It works well with Rack based web applications, such as Ruby on Rails.
|
5
5
|
|
6
|
-
[![Build Status](https://
|
6
|
+
[![Build Status](https://github.com/carrierwaveuploader/carrierwave/workflows/Test/badge.svg)](https://github.com/carrierwaveuploader/carrierwave/actions)
|
7
7
|
[![Code Climate](https://codeclimate.com/github/carrierwaveuploader/carrierwave.svg)](https://codeclimate.com/github/carrierwaveuploader/carrierwave)
|
8
8
|
[![SemVer](https://api.dependabot.com/badges/compatibility_score?dependency-name=carrierwave&package-manager=bundler&version-scheme=semver)](https://dependabot.com/compatibility-score.html?dependency-name=carrierwave&package-manager=bundler&version-scheme=semver)
|
9
9
|
|
@@ -94,7 +94,7 @@ a migration:
|
|
94
94
|
Open your model file and mount the uploader:
|
95
95
|
|
96
96
|
```ruby
|
97
|
-
class User <
|
97
|
+
class User < ApplicationRecord
|
98
98
|
mount_uploader :avatar, AvatarUploader
|
99
99
|
end
|
100
100
|
```
|
@@ -157,7 +157,7 @@ Open your model file and mount the uploader:
|
|
157
157
|
|
158
158
|
|
159
159
|
```ruby
|
160
|
-
class User <
|
160
|
+
class User < ApplicationRecord
|
161
161
|
mount_uploaders :avatars, AvatarUploader
|
162
162
|
serialize :avatars, JSON # If you use SQLite, add this line.
|
163
163
|
end
|
@@ -230,7 +230,7 @@ end
|
|
230
230
|
## Securing uploads
|
231
231
|
|
232
232
|
Certain files might be dangerous if uploaded to the wrong location, such as PHP
|
233
|
-
files or other script files. CarrierWave allows you to specify
|
233
|
+
files or other script files. CarrierWave allows you to specify an allowlist of
|
234
234
|
allowed extensions or content types.
|
235
235
|
|
236
236
|
If you're mounting the uploader, uploading a file with the wrong extension will
|
@@ -238,7 +238,7 @@ make the record invalid instead. Otherwise, an error is raised.
|
|
238
238
|
|
239
239
|
```ruby
|
240
240
|
class MyUploader < CarrierWave::Uploader::Base
|
241
|
-
def
|
241
|
+
def extension_allowlist
|
242
242
|
%w(jpg jpeg gif png)
|
243
243
|
end
|
244
244
|
end
|
@@ -249,45 +249,45 @@ Let's say we need an uploader that accepts only images. This can be done like th
|
|
249
249
|
|
250
250
|
```ruby
|
251
251
|
class MyUploader < CarrierWave::Uploader::Base
|
252
|
-
def
|
252
|
+
def content_type_allowlist
|
253
253
|
/image\//
|
254
254
|
end
|
255
255
|
end
|
256
256
|
```
|
257
257
|
|
258
|
-
You can use a
|
258
|
+
You can use a denylist to reject content types.
|
259
259
|
Let's say we need an uploader that reject JSON files. This can be done like this
|
260
260
|
|
261
261
|
```ruby
|
262
262
|
class NoJsonUploader < CarrierWave::Uploader::Base
|
263
|
-
def
|
263
|
+
def content_type_denylist
|
264
264
|
['application/text', 'application/json']
|
265
265
|
end
|
266
266
|
end
|
267
267
|
```
|
268
268
|
|
269
269
|
### CVE-2016-3714 (ImageTragick)
|
270
|
-
This version of CarrierWave has the ability to mitigate CVE-2016-3714. However, you **MUST** set a
|
270
|
+
This version of CarrierWave has the ability to mitigate CVE-2016-3714. However, you **MUST** set a content_type_allowlist in your uploaders for this protection to be effective, and you **MUST** either disable ImageMagick's default SVG delegate or use the RSVG delegate for SVG processing.
|
271
271
|
|
272
272
|
|
273
|
-
A valid
|
273
|
+
A valid allowlist that will restrict your uploader to images only, and mitigate the CVE is:
|
274
274
|
|
275
275
|
```ruby
|
276
276
|
class MyUploader < CarrierWave::Uploader::Base
|
277
|
-
def
|
277
|
+
def content_type_allowlist
|
278
278
|
[/image\//]
|
279
279
|
end
|
280
280
|
end
|
281
281
|
```
|
282
282
|
|
283
|
-
**WARNING**: A `
|
283
|
+
**WARNING**: A `content_type_allowlist` is the only form of allowlist or denylist supported by CarrierWave that can effectively mitigate against CVE-2016-3714. Use of `extension_allowlist` will not inspect the file headers, and thus still leaves your application open to the vulnerability.
|
284
284
|
|
285
285
|
### Filenames and unicode chars
|
286
286
|
|
287
287
|
Another security issue you should care for is the file names (see
|
288
288
|
[Ruby On Rails Security Guide](http://guides.rubyonrails.org/security.html#file-uploads)).
|
289
289
|
By default, CarrierWave provides only English letters, arabic numerals and some symbols as
|
290
|
-
|
290
|
+
allowlisted characters in the file name. If you want to support local scripts (Cyrillic letters, letters with diacritics and so on), you
|
291
291
|
have to override `sanitize_regexp` method. It should return regular expression which would match
|
292
292
|
all *non*-allowed symbols.
|
293
293
|
|
@@ -332,15 +332,13 @@ end
|
|
332
332
|
|
333
333
|
When this uploader is used, an uploaded image would be scaled to be no larger
|
334
334
|
than 800 by 800 pixels. The original aspect ratio will be kept.
|
335
|
-
A version called thumb is then created, which is scaled
|
336
|
-
to exactly 200 by 200 pixels.
|
337
335
|
|
338
|
-
|
339
|
-
|
336
|
+
A version called `:thumb` is then created, which is scaled
|
337
|
+
to exactly 200 by 200 pixels. The thumbnail uses `resize_to_fill` which makes sure
|
340
338
|
that the width and height specified are filled, only cropping
|
341
339
|
if the aspect ratio requires it.
|
342
340
|
|
343
|
-
The uploader could be used like this:
|
341
|
+
The above uploader could be used like this:
|
344
342
|
|
345
343
|
```ruby
|
346
344
|
uploader = AvatarUploader.new
|
@@ -353,6 +351,18 @@ uploader.thumb.url # => '/url/to/thumb_my_file.png' # size: 200x200
|
|
353
351
|
One important thing to remember is that process is called *before* versions are
|
354
352
|
created. This can cut down on processing cost.
|
355
353
|
|
354
|
+
### Processing Methods: mini_magick
|
355
|
+
|
356
|
+
- `convert` - Changes the image encoding format to the given format, eg. jpg
|
357
|
+
- `resize_to_limit` - Resize the image to fit within the specified dimensions while retaining the original aspect ratio. Will only resize the image if it is larger than the specified dimensions. The resulting image may be shorter or narrower than specified in the smaller dimension but will not be larger than the specified values.
|
358
|
+
- `resize_to_fit` - Resize the image to fit within the specified dimensions while retaining the original aspect ratio. The image may be shorter or narrower than specified in the smaller dimension but will not be larger than the specified values.
|
359
|
+
- `resize_to_fill` - Resize the image to fit within the specified dimensions while retaining the aspect ratio of the original image. If necessary, crop the image in the larger dimension. Optionally, a "gravity" may be specified, for example "Center", or "NorthEast".
|
360
|
+
- `resize_and_pad` - Resize the image to fit within the specified dimensions while retaining the original aspect ratio. If necessary, will pad the remaining area with the given color, which defaults to transparent (for gif and png, white for jpeg). Optionally, a "gravity" may be specified, as above.
|
361
|
+
|
362
|
+
See `carrierwave/processing/mini_magick.rb` for details.
|
363
|
+
|
364
|
+
### Nested versions
|
365
|
+
|
356
366
|
It is possible to nest versions within versions:
|
357
367
|
|
358
368
|
```ruby
|
@@ -707,6 +717,9 @@ CarrierWave.configure do |config|
|
|
707
717
|
config.fog_directory = 'name_of_bucket' # required
|
708
718
|
config.fog_public = false # optional, defaults to true
|
709
719
|
config.fog_attributes = { cache_control: "public, max-age=#{365.days.to_i}" } # optional, defaults to {}
|
720
|
+
# For an application which utilizes multiple servers but does not need caches persisted across requests,
|
721
|
+
# uncomment the line :file instead of the default :storage. Otherwise, it will use AWS as the temp cache store.
|
722
|
+
# config.cache_storage = :file
|
710
723
|
end
|
711
724
|
```
|
712
725
|
|
@@ -787,30 +800,43 @@ end
|
|
787
800
|
That's it! You can still use the `CarrierWave::Uploader#url` method to return
|
788
801
|
the url to the file on Rackspace Cloud Files.
|
789
802
|
|
790
|
-
## Using Google Storage
|
803
|
+
## Using Google Cloud Storage
|
791
804
|
|
792
|
-
[Fog](http://github.com/fog/fog-google) is used to support Google Storage
|
805
|
+
[Fog](http://github.com/fog/fog-google) is used to support Google Cloud Storage. Ensure you have it in your Gemfile:
|
793
806
|
|
794
807
|
```ruby
|
795
808
|
gem "fog-google"
|
796
|
-
gem "google-api-client", "> 0.8.5", "< 0.9"
|
797
|
-
gem "mime-types"
|
798
809
|
```
|
799
810
|
|
800
|
-
You'll need to configure a directory (also known as a bucket)
|
811
|
+
You'll need to configure a directory (also known as a bucket) and the credentials in the initializer.
|
801
812
|
For the sake of performance it is assumed that the directory already exists, so please create it if need be.
|
802
813
|
|
803
814
|
Please read the [fog-google README](https://github.com/fog/fog-google/blob/master/README.md) on how to get credentials.
|
804
815
|
|
816
|
+
For Google Storage JSON API (recommended):
|
817
|
+
```ruby
|
818
|
+
CarrierWave.configure do |config|
|
819
|
+
config.fog_provider = 'fog/google'
|
820
|
+
config.fog_credentials = {
|
821
|
+
provider: 'Google',
|
822
|
+
google_project: 'my-project',
|
823
|
+
google_json_key_string: 'xxxxxx'
|
824
|
+
# or use google_json_key_location if using an actual file
|
825
|
+
}
|
826
|
+
config.fog_directory = 'google_cloud_storage_bucket_name'
|
827
|
+
end
|
828
|
+
```
|
805
829
|
|
830
|
+
For Google Storage XML API:
|
806
831
|
```ruby
|
807
832
|
CarrierWave.configure do |config|
|
808
|
-
|
809
|
-
|
810
|
-
|
811
|
-
|
812
|
-
|
813
|
-
|
833
|
+
config.fog_provider = 'fog/google'
|
834
|
+
config.fog_credentials = {
|
835
|
+
provider: 'Google',
|
836
|
+
google_storage_access_key_id: 'xxxxxx',
|
837
|
+
google_storage_secret_access_key: 'yyyyyy'
|
838
|
+
}
|
839
|
+
config.fog_directory = 'google_cloud_storage_bucket_name'
|
814
840
|
end
|
815
841
|
```
|
816
842
|
|
@@ -954,10 +980,10 @@ errors:
|
|
954
980
|
carrierwave_processing_error: failed to be processed
|
955
981
|
carrierwave_integrity_error: is not of an allowed file type
|
956
982
|
carrierwave_download_error: could not be downloaded
|
957
|
-
|
958
|
-
|
959
|
-
|
960
|
-
|
983
|
+
extension_allowlist_error: "You are not allowed to upload %{extension} files, allowed types: %{allowed_types}"
|
984
|
+
extension_denylist_error: "You are not allowed to upload %{extension} files, prohibited types: %{prohibited_types}"
|
985
|
+
content_type_allowlist_error: "You are not allowed to upload %{content_type} files, allowed types: %{allowed_types}"
|
986
|
+
content_type_denylist_error: "You are not allowed to upload %{content_type} files"
|
961
987
|
rmagick_processing_error: "Failed to manipulate with rmagick, maybe it is not an image?"
|
962
988
|
mini_magick_processing_error: "Failed to manipulate with MiniMagick, maybe it is not an image? Original Error: %{e}"
|
963
989
|
min_size_error: "File size should be greater than %{min_size}"
|
@@ -1005,12 +1031,12 @@ end
|
|
1005
1031
|
Will add these callbacks:
|
1006
1032
|
|
1007
1033
|
```ruby
|
1008
|
-
after_save :store_avatar!
|
1009
1034
|
before_save :write_avatar_identifier
|
1035
|
+
after_save :store_previous_changes_for_avatar
|
1010
1036
|
after_commit :remove_avatar!, on: :destroy
|
1011
1037
|
after_commit :mark_remove_avatar_false, on: :update
|
1012
|
-
after_save :store_previous_changes_for_avatar
|
1013
1038
|
after_commit :remove_previously_stored_avatar, on: :update
|
1039
|
+
after_commit :store_avatar!, on: [:create, :update]
|
1014
1040
|
```
|
1015
1041
|
|
1016
1042
|
If you want to skip any of these callbacks (eg. you want to keep the existing
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'open-uri'
|
2
|
+
require 'ssrf_filter'
|
2
3
|
require 'addressable'
|
3
4
|
require 'carrierwave/downloader/remote_file'
|
4
5
|
|
@@ -22,16 +23,26 @@ module CarrierWave
|
|
22
23
|
def download(url, remote_headers = {})
|
23
24
|
headers = remote_headers.
|
24
25
|
reverse_merge('User-Agent' => "CarrierWave/#{CarrierWave::VERSION}")
|
26
|
+
uri = process_uri(url.to_s)
|
25
27
|
begin
|
26
|
-
|
28
|
+
if skip_ssrf_protection?(uri)
|
29
|
+
response = OpenURI.open_uri(process_uri(url.to_s), headers)
|
30
|
+
else
|
31
|
+
request = nil
|
32
|
+
response = SsrfFilter.get(uri, headers: headers) do |req|
|
33
|
+
request = req
|
34
|
+
end
|
35
|
+
response.uri = request.uri
|
36
|
+
response.value
|
37
|
+
end
|
27
38
|
rescue StandardError => e
|
28
39
|
raise CarrierWave::DownloadError, "could not download file: #{e.message}"
|
29
40
|
end
|
30
|
-
CarrierWave::Downloader::RemoteFile.new(
|
41
|
+
CarrierWave::Downloader::RemoteFile.new(response)
|
31
42
|
end
|
32
43
|
|
33
44
|
##
|
34
|
-
# Processes the given URL by parsing and escaping
|
45
|
+
# Processes the given URL by parsing it, and escaping if necessary. Public to allow overriding.
|
35
46
|
#
|
36
47
|
# === Parameters
|
37
48
|
#
|
@@ -40,11 +51,37 @@ module CarrierWave
|
|
40
51
|
def process_uri(uri)
|
41
52
|
uri_parts = uri.split('?')
|
42
53
|
encoded_uri = Addressable::URI.parse(uri_parts.shift).normalize.to_s
|
43
|
-
|
44
|
-
|
54
|
+
query = uri_parts.any? ? "?#{uri_parts.join('?')}" : ''
|
55
|
+
begin
|
56
|
+
URI.parse("#{encoded_uri}#{query}")
|
57
|
+
rescue URI::InvalidURIError
|
58
|
+
URI.parse("#{encoded_uri}#{URI::DEFAULT_PARSER.escape(query)}")
|
59
|
+
end
|
45
60
|
rescue URI::InvalidURIError, Addressable::URI::InvalidURIError
|
46
61
|
raise CarrierWave::DownloadError, "couldn't parse URL: #{uri}"
|
47
62
|
end
|
63
|
+
|
64
|
+
##
|
65
|
+
# If this returns true, SSRF protection will be bypassed.
|
66
|
+
# You can override this if you want to allow accessing specific local URIs that are not SSRF exploitable.
|
67
|
+
#
|
68
|
+
# === Parameters
|
69
|
+
#
|
70
|
+
# [uri (URI)] The URI where the remote file is stored
|
71
|
+
#
|
72
|
+
# === Examples
|
73
|
+
#
|
74
|
+
# class CarrierWave::Downloader::CustomDownloader < CarrierWave::Downloader::Base
|
75
|
+
# def skip_ssrf_protection?(uri)
|
76
|
+
# uri.hostname == 'localhost' && uri.port == 80
|
77
|
+
# end
|
78
|
+
# end
|
79
|
+
#
|
80
|
+
# my_uploader.downloader = CarrierWave::Downloader::CustomDownloader
|
81
|
+
#
|
82
|
+
def skip_ssrf_protection?(uri)
|
83
|
+
false
|
84
|
+
end
|
48
85
|
end
|
49
86
|
end
|
50
87
|
end
|
@@ -1,15 +1,36 @@
|
|
1
1
|
module CarrierWave
|
2
2
|
module Downloader
|
3
3
|
class RemoteFile
|
4
|
-
attr_reader :file
|
4
|
+
attr_reader :file, :uri
|
5
5
|
|
6
6
|
def initialize(file)
|
7
|
-
|
7
|
+
case file
|
8
|
+
when String
|
9
|
+
@file = StringIO.new(file)
|
10
|
+
when Net::HTTPResponse
|
11
|
+
@file = StringIO.new(file.body)
|
12
|
+
@content_type = file.content_type
|
13
|
+
@headers = file
|
14
|
+
@uri = file.uri
|
15
|
+
else
|
16
|
+
@file = file
|
17
|
+
@content_type = file.content_type
|
18
|
+
@headers = file.meta
|
19
|
+
@uri = file.base_uri
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def content_type
|
24
|
+
@content_type || 'application/octet-stream'
|
25
|
+
end
|
26
|
+
|
27
|
+
def headers
|
28
|
+
@headers || {}
|
8
29
|
end
|
9
30
|
|
10
31
|
def original_filename
|
11
32
|
filename = filename_from_header || filename_from_uri
|
12
|
-
mime_type = MiniMime.lookup_by_content_type(
|
33
|
+
mime_type = MiniMime.lookup_by_content_type(content_type)
|
13
34
|
unless File.extname(filename).present? || mime_type.blank?
|
14
35
|
filename = "#{filename}.#{mime_type.extension}"
|
15
36
|
end
|
@@ -23,14 +44,16 @@ module CarrierWave
|
|
23
44
|
private
|
24
45
|
|
25
46
|
def filename_from_header
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
47
|
+
return nil unless headers['content-disposition']
|
48
|
+
|
49
|
+
match = headers['content-disposition'].match(/filename=(?:"([^"]+)"|([^";]+))/)
|
50
|
+
return nil unless match
|
51
|
+
|
52
|
+
match[1].presence || match[2].presence
|
30
53
|
end
|
31
54
|
|
32
55
|
def filename_from_uri
|
33
|
-
CGI.unescape(File.basename(
|
56
|
+
CGI.unescape(File.basename(uri.path))
|
34
57
|
end
|
35
58
|
|
36
59
|
def method_missing(*args, &block)
|
@@ -4,11 +4,12 @@ en:
|
|
4
4
|
carrierwave_processing_error: failed to be processed
|
5
5
|
carrierwave_integrity_error: is not of an allowed file type
|
6
6
|
carrierwave_download_error: could not be downloaded
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
7
|
+
extension_allowlist_error: "You are not allowed to upload %{extension} files, allowed types: %{allowed_types}"
|
8
|
+
extension_denylist_error: "You are not allowed to upload %{extension} files, prohibited types: %{prohibited_types}"
|
9
|
+
content_type_allowlist_error: "You are not allowed to upload %{content_type} files, allowed types: %{allowed_types}"
|
10
|
+
content_type_denylist_error: "You are not allowed to upload %{content_type} files"
|
11
11
|
rmagick_processing_error: "Failed to manipulate with rmagick, maybe it is not an image?"
|
12
12
|
mini_magick_processing_error: "Failed to manipulate with MiniMagick, maybe it is not an image? Original Error: %{e}"
|
13
|
+
vips_processing_error: "Failed to manipulate with vips, maybe it is not an image? Original Error: %{e}"
|
13
14
|
min_size_error: "File size should be greater than %{min_size}"
|
14
15
|
max_size_error: "File size should be less than %{max_size}"
|
data/lib/carrierwave/mounter.rb
CHANGED
@@ -72,9 +72,10 @@ module CarrierWave
|
|
72
72
|
end
|
73
73
|
|
74
74
|
def cache_names=(cache_names)
|
75
|
+
cache_names = cache_names.reject(&:blank?)
|
75
76
|
return if cache_names.blank?
|
76
77
|
clear_unstaged
|
77
|
-
cache_names.
|
78
|
+
cache_names.each do |cache_name|
|
78
79
|
begin
|
79
80
|
uploader = blank_uploader
|
80
81
|
uploader.retrieve_from_cache!(cache_name)
|
@@ -91,7 +92,7 @@ module CarrierWave
|
|
91
92
|
@remote_urls = urls
|
92
93
|
|
93
94
|
clear_unstaged
|
94
|
-
urls.zip(remote_request_headers || []).
|
95
|
+
urls.zip(remote_request_headers || []).each do |url, header|
|
95
96
|
handle_error do
|
96
97
|
uploader = blank_uploader
|
97
98
|
uploader.download!(url, header || {})
|
@@ -113,7 +114,7 @@ module CarrierWave
|
|
113
114
|
end
|
114
115
|
|
115
116
|
def remove?
|
116
|
-
remove.present? && remove !~ /\A0|false$\z/
|
117
|
+
remove.present? && (remove == true || remove !~ /\A0|false$\z/)
|
117
118
|
end
|
118
119
|
|
119
120
|
def remove!
|
@@ -297,7 +297,7 @@ module CarrierWave
|
|
297
297
|
|
298
298
|
# backwards compatibility (we want to eventually move away from MiniMagick::Image)
|
299
299
|
if block
|
300
|
-
image = MiniMagick::Image.new(result.path, result)
|
300
|
+
image = ::MiniMagick::Image.new(result.path, result)
|
301
301
|
image = block.call(image)
|
302
302
|
result = image.instance_variable_get(:@tempfile)
|
303
303
|
end
|
@@ -228,7 +228,7 @@ module CarrierWave
|
|
228
228
|
height = dimension_from height
|
229
229
|
manipulate! do |img|
|
230
230
|
img.resize_to_fit!(width, height)
|
231
|
-
new_img = ::Magick::Image.new(width, height) {
|
231
|
+
new_img = ::Magick::Image.new(width, height) { |img| img.background_color = background == :transparent ? 'rgba(255,255,255,0)' : background.to_s }
|
232
232
|
if background == :transparent
|
233
233
|
filled = new_img.matte_floodfill(1, 1)
|
234
234
|
else
|
@@ -378,9 +378,15 @@ module CarrierWave
|
|
378
378
|
|
379
379
|
def create_info_block(options)
|
380
380
|
return nil unless options
|
381
|
-
|
382
|
-
|
383
|
-
|
381
|
+
proc do |img|
|
382
|
+
options.each do |k, v|
|
383
|
+
if v.is_a?(String) && (matches = v.match(/^["'](.+)["']/))
|
384
|
+
ActiveSupport::Deprecation.warn "Passing quoted strings like #{v} to #manipulate! is deprecated, pass them without quoting."
|
385
|
+
v = matches[1]
|
386
|
+
end
|
387
|
+
img.public_send(:"#{k}=", v)
|
388
|
+
end
|
389
|
+
end
|
384
390
|
end
|
385
391
|
|
386
392
|
def destroy_image(image)
|