kt-paperclip 8.0.0 → 8.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +16 -5
- data/lib/paperclip/media_type_spoof_detector.rb +44 -6
- data/lib/paperclip/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 71b12469bab65eb2861d1170c154ecf1a08f6a0591806096f3d49f598f4ec115
|
|
4
|
+
data.tar.gz: 12efe7db20633834994b3b1836cc697ff21dbf1bd37851346d1bd5e0961aa045
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6db416b89eaa01127e3b8eb7ac7615a19d840a236ea114be4814675d61765fa53f25e25b351b5d9438badf06ab3a20ec036565a418f47dbbcd97563d96e0f91f
|
|
7
|
+
data.tar.gz: 8aa390b628e9926d17c9de71e0dfe861fe2197762fff916064e1b61bd18fda5e3d2f6eda291d4e208e36ecb2fa3fc98ca366e5a28c479f7dde00b02736be2765
|
data/README.md
CHANGED
|
@@ -90,7 +90,7 @@ Requirements
|
|
|
90
90
|
|
|
91
91
|
### Ruby and Rails
|
|
92
92
|
|
|
93
|
-
Paperclip now requires Ruby version **>= 2.
|
|
93
|
+
Paperclip now requires Ruby version **>= 2.7** and Rails version **>= 5.2**
|
|
94
94
|
(only if you're going to use Paperclip with Ruby on Rails).
|
|
95
95
|
|
|
96
96
|
### ImageMagick Image Processor
|
|
@@ -139,7 +139,7 @@ Paperclip is distributed as a gem, which is how it should be used in your app.
|
|
|
139
139
|
Include the gem in your Gemfile:
|
|
140
140
|
|
|
141
141
|
```ruby
|
|
142
|
-
gem "kt-paperclip", "~>
|
|
142
|
+
gem "kt-paperclip", "~> 8.0"
|
|
143
143
|
```
|
|
144
144
|
|
|
145
145
|
Or, if you want to get the latest, you can get master from the main paperclip repository:
|
|
@@ -375,8 +375,10 @@ validates_attachment :avatar,
|
|
|
375
375
|
content_type: ["image/jpeg", "image/gif", "image/png"]
|
|
376
376
|
```
|
|
377
377
|
|
|
378
|
-
`Paperclip::ContentTypeDetector`
|
|
379
|
-
|
|
378
|
+
`Paperclip::ContentTypeDetector` uses the file's extension as a hint when the contents alone are
|
|
379
|
+
ambiguous, so the stored `content_type` is not by itself proof of what a file contains. The check
|
|
380
|
+
that ignores the filename entirely is `validates_media_type_spoof_detection` (see Security
|
|
381
|
+
Validations below); use it alongside your `content_type` validation.
|
|
380
382
|
|
|
381
383
|
### Duplicate error messages
|
|
382
384
|
|
|
@@ -444,17 +446,26 @@ being uploaded as JPEGs, but will not prevent GIFs from being uploaded with a
|
|
|
444
446
|
`.jpg` extension. This validation will only add validation errors to the form. It
|
|
445
447
|
will not cause errors to be raised.
|
|
446
448
|
|
|
449
|
+
The type is detected from the file's contents only, using magic-number detection plus the Unix
|
|
450
|
+
`file` utility. The filename is never consulted. Where `file` is unavailable the check falls back
|
|
451
|
+
to magic-number detection alone, which cannot identify text-based formats; content it cannot
|
|
452
|
+
identify at all is accepted rather than rejected.
|
|
453
|
+
|
|
447
454
|
This can sometimes cause false validation errors in applications that use custom
|
|
448
455
|
file extensions. In these cases you may wish to add your custom extension to the
|
|
449
456
|
list of content type mappings by creating `config/initializers/paperclip.rb`:
|
|
450
457
|
|
|
451
458
|
```ruby
|
|
452
|
-
# Allow ".foo" as an extension for files
|
|
459
|
+
# Allow ".foo" as an extension for files whose contents are detected as "text/plain".
|
|
453
460
|
Paperclip.options[:content_type_mappings] = {
|
|
454
461
|
foo: %w(text/plain)
|
|
455
462
|
}
|
|
456
463
|
```
|
|
457
464
|
|
|
465
|
+
The value is the type the *contents* detect as (what `file -b --mime` reports), not the type you
|
|
466
|
+
would like the extension to mean. Text-based formats such as SVG and CSV are the usual reason to
|
|
467
|
+
need one.
|
|
468
|
+
|
|
458
469
|
---
|
|
459
470
|
|
|
460
471
|
Defaults
|
|
@@ -42,12 +42,27 @@ module Paperclip
|
|
|
42
42
|
end
|
|
43
43
|
|
|
44
44
|
def calculated_type_mismatch?
|
|
45
|
-
supplied_media_type.
|
|
46
|
-
|
|
45
|
+
return false if supplied_media_type.blank?
|
|
46
|
+
# Fast path: the magic number already supports the supplied type, no shell out needed.
|
|
47
|
+
return false if supplied_type_consistent_with?(type_from_magic)
|
|
48
|
+
# The bytes told us nothing at all, so there is nothing to contradict the supplied type.
|
|
49
|
+
return false if calculated_content_types.empty?
|
|
50
|
+
|
|
51
|
+
!supplied_type_consistent_with?(type_from_file_command)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# The supplied type is supported by the bytes if it shares their media type, or if it is a
|
|
55
|
+
# specialization of what the bytes resolved to: image/svg+xml is a child of application/xml,
|
|
56
|
+
# which is all the magic number of an SVG with an XML declaration can tell us.
|
|
57
|
+
def supplied_type_consistent_with?(type)
|
|
58
|
+
return false if type.blank?
|
|
59
|
+
|
|
60
|
+
type.include?(supplied_media_type) ||
|
|
61
|
+
!!Marcel::Magic.child?(supplied_content_type, type)
|
|
47
62
|
end
|
|
48
63
|
|
|
49
64
|
def mapping_override_mismatch?
|
|
50
|
-
|
|
65
|
+
(Array(mapped_content_type) & calculated_content_types).empty?
|
|
51
66
|
end
|
|
52
67
|
|
|
53
68
|
def supplied_content_type
|
|
@@ -66,12 +81,35 @@ module Paperclip
|
|
|
66
81
|
@media_types_from_name ||= content_types_from_name.collect(&:media_type)
|
|
67
82
|
end
|
|
68
83
|
|
|
84
|
+
# Every type the file's *contents* resolve to. The filename is deliberately never consulted
|
|
85
|
+
# here -- trusting it is what let a renamed file pass this check (kreeti/kt-paperclip#173).
|
|
86
|
+
def calculated_content_types
|
|
87
|
+
@calculated_content_types ||=
|
|
88
|
+
# Both sources return nil, never a blank string, when they come up empty.
|
|
89
|
+
[type_from_magic, type_from_file_command].compact.uniq
|
|
90
|
+
end
|
|
91
|
+
|
|
69
92
|
def calculated_content_type
|
|
70
|
-
@calculated_content_type ||=
|
|
93
|
+
@calculated_content_type ||= calculated_content_types.first.to_s
|
|
71
94
|
end
|
|
72
95
|
|
|
73
|
-
|
|
74
|
-
|
|
96
|
+
# Note the absence of a `name:` argument. Marcel lets the filename decide when the bytes carry
|
|
97
|
+
# no magic number of their own, which is exactly what spoof detection must not allow.
|
|
98
|
+
def type_from_magic
|
|
99
|
+
return @type_from_magic if defined?(@type_from_magic)
|
|
100
|
+
|
|
101
|
+
type = Marcel::MimeType.for(Pathname.new(@file.path))
|
|
102
|
+
# Marcel::MimeType returns 'application/octet-stream' if it can't find a valid type.
|
|
103
|
+
@type_from_magic = type == ContentTypeDetector::SENSIBLE_DEFAULT ? nil : type
|
|
104
|
+
rescue Errno::ENOENT => e
|
|
105
|
+
Paperclip.log("Error while determining content type: #{e}")
|
|
106
|
+
@type_from_magic = nil
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def type_from_file_command
|
|
110
|
+
return @type_from_file_command if defined?(@type_from_file_command)
|
|
111
|
+
|
|
112
|
+
@type_from_file_command = Commands::UnixFile.detect_content_type(@file.path)
|
|
75
113
|
end
|
|
76
114
|
|
|
77
115
|
def mapped_content_type
|
data/lib/paperclip/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: kt-paperclip
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 8.0.
|
|
4
|
+
version: 8.0.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Surendra Singhi
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-10-14 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activemodel
|