carrierwave 2.0.1 → 2.2.1
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 +79 -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 +1 -1
- 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 +15 -8
- data/lib/carrierwave/storage/fog.rb +26 -8
- 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 +62 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a16b1f5ad9e05370bb6ad6381f5d94b36d3233c3ddbbd4782b54d3a01fb6a747
|
4
|
+
data.tar.gz: a5093ecbce4d1ee217c6b78b57f6c50d6ecad9cff0c3b865a22ebbbd196743aa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 561070ea4b8d2eb9b6e606e4eb465aa3c6ecf3c5664102b5de9ada7317adbc8c8c2561b68baed39acb656cdece7509455e359b3f5ef9cb0e0c85202458c9ac02
|
7
|
+
data.tar.gz: 386f211d2fb219185543d330e84cbc7331ef8fe0f48992a9ef98f965e96dce2b7ec8731317951867bfc68bf7496c08211cc840003130cc20154dd4173b095d47
|
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,34 @@ 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
|
+
### conditional process
|
365
|
+
|
366
|
+
If you want to use conditional process, you can only use `if` statement.
|
367
|
+
|
368
|
+
See `carrierwave/uploader/processing.rb` for details.
|
369
|
+
|
370
|
+
```ruby
|
371
|
+
class MyUploader < CarrierWave::Uploader::Base
|
372
|
+
process :scale => [200, 200], :if => :image?
|
373
|
+
|
374
|
+
def image?(carrier_wave_sanitized_file)
|
375
|
+
true
|
376
|
+
end
|
377
|
+
end
|
378
|
+
```
|
379
|
+
|
380
|
+
### Nested versions
|
381
|
+
|
356
382
|
It is possible to nest versions within versions:
|
357
383
|
|
358
384
|
```ruby
|
@@ -707,6 +733,9 @@ CarrierWave.configure do |config|
|
|
707
733
|
config.fog_directory = 'name_of_bucket' # required
|
708
734
|
config.fog_public = false # optional, defaults to true
|
709
735
|
config.fog_attributes = { cache_control: "public, max-age=#{365.days.to_i}" } # optional, defaults to {}
|
736
|
+
# For an application which utilizes multiple servers but does not need caches persisted across requests,
|
737
|
+
# uncomment the line :file instead of the default :storage. Otherwise, it will use AWS as the temp cache store.
|
738
|
+
# config.cache_storage = :file
|
710
739
|
end
|
711
740
|
```
|
712
741
|
|
@@ -787,30 +816,43 @@ end
|
|
787
816
|
That's it! You can still use the `CarrierWave::Uploader#url` method to return
|
788
817
|
the url to the file on Rackspace Cloud Files.
|
789
818
|
|
790
|
-
## Using Google Storage
|
819
|
+
## Using Google Cloud Storage
|
791
820
|
|
792
|
-
[Fog](http://github.com/fog/fog-google) is used to support Google Storage
|
821
|
+
[Fog](http://github.com/fog/fog-google) is used to support Google Cloud Storage. Ensure you have it in your Gemfile:
|
793
822
|
|
794
823
|
```ruby
|
795
824
|
gem "fog-google"
|
796
|
-
gem "google-api-client", "> 0.8.5", "< 0.9"
|
797
|
-
gem "mime-types"
|
798
825
|
```
|
799
826
|
|
800
|
-
You'll need to configure a directory (also known as a bucket)
|
827
|
+
You'll need to configure a directory (also known as a bucket) and the credentials in the initializer.
|
801
828
|
For the sake of performance it is assumed that the directory already exists, so please create it if need be.
|
802
829
|
|
803
830
|
Please read the [fog-google README](https://github.com/fog/fog-google/blob/master/README.md) on how to get credentials.
|
804
831
|
|
832
|
+
For Google Storage JSON API (recommended):
|
833
|
+
```ruby
|
834
|
+
CarrierWave.configure do |config|
|
835
|
+
config.fog_provider = 'fog/google'
|
836
|
+
config.fog_credentials = {
|
837
|
+
provider: 'Google',
|
838
|
+
google_project: 'my-project',
|
839
|
+
google_json_key_string: 'xxxxxx'
|
840
|
+
# or use google_json_key_location if using an actual file
|
841
|
+
}
|
842
|
+
config.fog_directory = 'google_cloud_storage_bucket_name'
|
843
|
+
end
|
844
|
+
```
|
805
845
|
|
846
|
+
For Google Storage XML API:
|
806
847
|
```ruby
|
807
848
|
CarrierWave.configure do |config|
|
808
|
-
|
809
|
-
|
810
|
-
|
811
|
-
|
812
|
-
|
813
|
-
|
849
|
+
config.fog_provider = 'fog/google'
|
850
|
+
config.fog_credentials = {
|
851
|
+
provider: 'Google',
|
852
|
+
google_storage_access_key_id: 'xxxxxx',
|
853
|
+
google_storage_secret_access_key: 'yyyyyy'
|
854
|
+
}
|
855
|
+
config.fog_directory = 'google_cloud_storage_bucket_name'
|
814
856
|
end
|
815
857
|
```
|
816
858
|
|
@@ -954,10 +996,10 @@ errors:
|
|
954
996
|
carrierwave_processing_error: failed to be processed
|
955
997
|
carrierwave_integrity_error: is not of an allowed file type
|
956
998
|
carrierwave_download_error: could not be downloaded
|
957
|
-
|
958
|
-
|
959
|
-
|
960
|
-
|
999
|
+
extension_allowlist_error: "You are not allowed to upload %{extension} files, allowed types: %{allowed_types}"
|
1000
|
+
extension_denylist_error: "You are not allowed to upload %{extension} files, prohibited types: %{prohibited_types}"
|
1001
|
+
content_type_allowlist_error: "You are not allowed to upload %{content_type} files, allowed types: %{allowed_types}"
|
1002
|
+
content_type_denylist_error: "You are not allowed to upload %{content_type} files"
|
961
1003
|
rmagick_processing_error: "Failed to manipulate with rmagick, maybe it is not an image?"
|
962
1004
|
mini_magick_processing_error: "Failed to manipulate with MiniMagick, maybe it is not an image? Original Error: %{e}"
|
963
1005
|
min_size_error: "File size should be greater than %{min_size}"
|
@@ -1005,12 +1047,12 @@ end
|
|
1005
1047
|
Will add these callbacks:
|
1006
1048
|
|
1007
1049
|
```ruby
|
1008
|
-
after_save :store_avatar!
|
1009
1050
|
before_save :write_avatar_identifier
|
1051
|
+
after_save :store_previous_changes_for_avatar
|
1010
1052
|
after_commit :remove_avatar!, on: :destroy
|
1011
1053
|
after_commit :mark_remove_avatar_false, on: :update
|
1012
|
-
after_save :store_previous_changes_for_avatar
|
1013
1054
|
after_commit :remove_previously_stored_avatar, on: :update
|
1055
|
+
after_commit :store_avatar!, on: [:create, :update]
|
1014
1056
|
```
|
1015
1057
|
|
1016
1058
|
If you want to skip any of these callbacks (eg. you want to keep the existing
|
@@ -1030,6 +1072,8 @@ See [CONTRIBUTING.md](https://github.com/carrierwaveuploader/carrierwave/blob/ma
|
|
1030
1072
|
|
1031
1073
|
## License
|
1032
1074
|
|
1075
|
+
The MIT License (MIT)
|
1076
|
+
|
1033
1077
|
Copyright (c) 2008-2015 Jonas Nicklas
|
1034
1078
|
|
1035
1079
|
Permission is hereby granted, free of charge, to any person obtaining
|
@@ -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
@@ -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)
|