carrierwave 2.0.0.rc → 2.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8d930fb9703b4bdb5ec81e14a01a5f07a260f39b52caed16978f193ddfd73159
4
- data.tar.gz: 83facb0af8dd50905b36510986a0215d3e6a03b765e83b6b063a6bc8ad7bbaf0
3
+ metadata.gz: 84145959d912145a2915ab7adb9ccbd6bf7a971ab00cef83fb7f5092c349c9c5
4
+ data.tar.gz: 9ba122388fb8ff36563001ea9144e4a1d523b7be78433fed2a971a82588de5c8
5
5
  SHA512:
6
- metadata.gz: aa813176c7dca0e42e9e131d405eeec2324741c7dff79fc4ceed9c5d16dabb52d967f6e40a025fe431412d91e1cfcb9fd043655271de7d615938f89f9f075179
7
- data.tar.gz: 16877c3b9ce32913719f0329b300bae18991de3d642702eed202639a2f9ecb0613e41c766f0ae9adf97d2d64247f86cb3cbdb47f75112542ba01dd82b3653539
6
+ metadata.gz: 70f718887e9f4223405d8f273cafaf429395725eead688918d454499a50063fdc748cc519440d2010f783cfa1ec3ba19f54b5e07dc644d195cbe6d59f1c5b6b2
7
+ data.tar.gz: 50907c92735e096c691a1ee7d440a2b83de736de3016b78c11796d0c558c283774236e5acf18abb552212816a38905986a6ec3ad0d956736f88c79ae99cd9aa6
data/README.md CHANGED
@@ -30,7 +30,7 @@ $ gem install carrierwave
30
30
  In Rails, add it to your Gemfile:
31
31
 
32
32
  ```ruby
33
- gem 'carrierwave', '>= 2.0.0.rc', '< 3.0'
33
+ gem 'carrierwave', '~> 2.0'
34
34
  ```
35
35
 
36
36
  Finally, restart the server to apply the changes.
@@ -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
- If you would like to crop images to a specific height and width you
339
- can use the alternative option of '''resize_to_fill'''. It will make sure
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
@@ -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,12 +23,22 @@ 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
- file = OpenURI.open_uri(process_uri(url.to_s), headers)
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(file)
41
+ CarrierWave::Downloader::RemoteFile.new(response)
31
42
  end
32
43
 
33
44
  ##
@@ -40,11 +51,33 @@ 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
- encoded_uri << '?' << URI.encode(uri_parts.join('?')) if uri_parts.any?
54
+ encoded_uri << '?' << Addressable::URI.encode(uri_parts.join('?')).gsub('%5B', '[').gsub('%5D', ']') if uri_parts.any?
44
55
  URI.parse(encoded_uri)
45
56
  rescue URI::InvalidURIError, Addressable::URI::InvalidURIError
46
57
  raise CarrierWave::DownloadError, "couldn't parse URL: #{uri}"
47
58
  end
59
+
60
+ ##
61
+ # If this returns true, SSRF protection will be bypassed.
62
+ # You can override this if you want to allow accessing specific local URIs that are not SSRF exploitable.
63
+ #
64
+ # === Parameters
65
+ #
66
+ # [uri (URI)] The URI where the remote file is stored
67
+ #
68
+ # === Examples
69
+ #
70
+ # class CarrierWave::Downloader::CustomDownloader < CarrierWave::Downloader::Base
71
+ # def skip_ssrf_protection?(uri)
72
+ # uri.hostname == 'localhost' && uri.port == 80
73
+ # end
74
+ # end
75
+ #
76
+ # my_uploader.downloader = CarrierWave::Downloader::CustomDownloader
77
+ #
78
+ def skip_ssrf_protection?(uri)
79
+ false
80
+ end
48
81
  end
49
82
  end
50
83
  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
- @file = file.is_a?(String) ? StringIO.new(file) : file
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(file.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
- if file.meta.include? 'content-disposition'
27
- match = file.meta['content-disposition'].match(/filename=(?:"([^"]+)"|([^";]+))/)
28
- match[1].presence || match[2].presence
29
- end
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(file.base_uri.path))
56
+ CGI.unescape(File.basename(uri.path))
34
57
  end
35
58
 
36
59
  def method_missing(*args, &block)
@@ -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.map do |cache_name|
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 || []).map do |url, header|
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
@@ -378,9 +378,15 @@ module CarrierWave
378
378
 
379
379
  def create_info_block(options)
380
380
  return nil unless options
381
- assignments = options.map { |k, v| "self.#{k} = #{v}" }
382
- code = "lambda { |img| " + assignments.join(";") + "}"
383
- eval code
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)
@@ -305,7 +305,7 @@ module CarrierWave
305
305
  def mkdir!(path, directory_permissions)
306
306
  options = {}
307
307
  options[:mode] = directory_permissions if directory_permissions
308
- FileUtils.mkdir_p(File.dirname(path), options) unless File.exist?(File.dirname(path))
308
+ FileUtils.mkdir_p(File.dirname(path), **options) unless File.exist?(File.dirname(path))
309
309
  end
310
310
 
311
311
  def chmod!(path, permissions)
@@ -161,6 +161,8 @@ module CarrierWave
161
161
  end
162
162
 
163
163
  class File
164
+ DEFAULT_S3_REGION = 'us-east-1'
165
+
164
166
  include CarrierWave::Utilities::Uri
165
167
 
166
168
  ##
@@ -194,7 +196,7 @@ module CarrierWave
194
196
  # [NilClass] no authenticated url available
195
197
  #
196
198
  def authenticated_url(options = {})
197
- if ['AWS', 'Google', 'Rackspace', 'OpenStack', 'AzureRM', 'Aliyun'].include?(@uploader.fog_credentials[:provider])
199
+ if ['AWS', 'Google', 'Rackspace', 'OpenStack', 'AzureRM', 'Aliyun', 'backblaze'].include?(@uploader.fog_credentials[:provider])
198
200
  # avoid a get by using local references
199
201
  local_directory = connection.directories.new(:key => @uploader.fog_directory)
200
202
  local_file = local_directory.files.new(:key => path)
@@ -384,9 +386,15 @@ module CarrierWave
384
386
  if valid_subdomain
385
387
  s3_subdomain = @uploader.fog_aws_accelerate ? "s3-accelerate" : "s3"
386
388
  "#{protocol}://#{@uploader.fog_directory}.#{s3_subdomain}.amazonaws.com/#{encoded_path}"
387
- else
388
- # directory is not a valid subdomain, so use path style for access
389
- "#{protocol}://s3.amazonaws.com/#{@uploader.fog_directory}/#{encoded_path}"
389
+ else # directory is not a valid subdomain, so use path style for access
390
+ region = @uploader.fog_credentials[:region].to_s
391
+ host = case region
392
+ when DEFAULT_S3_REGION, ''
393
+ 's3.amazonaws.com'
394
+ else
395
+ "s3.#{region}.amazonaws.com"
396
+ end
397
+ "#{protocol}://#{host}/#{@uploader.fog_directory}/#{encoded_path}"
390
398
  end
391
399
  end
392
400
  when 'Google'
@@ -1,3 +1,3 @@
1
1
  module CarrierWave
2
- VERSION = "2.0.0.rc"
2
+ VERSION = "2.1.1"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: carrierwave
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0.rc
4
+ version: 2.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jonas Nicklas
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-06-23 00:00:00.000000000 Z
11
+ date: 2021-02-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -94,6 +94,20 @@ dependencies:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
96
  version: '2.6'
97
+ - !ruby/object:Gem::Dependency
98
+ name: ssrf_filter
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '1.0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '1.0'
97
111
  - !ruby/object:Gem::Dependency
98
112
  name: pg
99
113
  requirement: !ruby/object:Gem::Requirement
@@ -347,7 +361,7 @@ homepage: https://github.com/carrierwaveuploader/carrierwave
347
361
  licenses:
348
362
  - MIT
349
363
  metadata: {}
350
- post_install_message:
364
+ post_install_message:
351
365
  rdoc_options:
352
366
  - "--main"
353
367
  require_paths:
@@ -359,13 +373,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
359
373
  version: 2.2.2
360
374
  required_rubygems_version: !ruby/object:Gem::Requirement
361
375
  requirements:
362
- - - ">"
376
+ - - ">="
363
377
  - !ruby/object:Gem::Version
364
- version: 1.3.1
378
+ version: '0'
365
379
  requirements: []
366
- rubyforge_project:
367
- rubygems_version: 2.7.8
368
- signing_key:
380
+ rubygems_version: 3.1.2
381
+ signing_key:
369
382
  specification_version: 4
370
383
  summary: Ruby file upload library
371
384
  test_files: []