sprockets 3.0.0.beta.2 → 3.0.0.beta.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2dcb1bab6dcd806bd08e5f467aa057cd75004be8
4
- data.tar.gz: 86037ea057923f8b2afd7dbffdea6d72f3596d02
3
+ metadata.gz: d80e59406f8e4f42c73b61fc3aa9a8e7b6cd6b37
4
+ data.tar.gz: fb62b74a69585406a2a5b0628d668ca5e2d50467
5
5
  SHA512:
6
- metadata.gz: ce12f8ec442a3d4a3cef5352f12a6c83151ff4dd717ce0fb94d31811ca9f3c80953a3f52e3f582eb5ecb42d0af05d2e5320fe925c3c55e4b8b61fd6280ff4ef8
7
- data.tar.gz: fbe0b9468d6e81a596517d4b4ecda0faf34ef84027ac7340ea2b603bc7635585ed2f93fa7e215e9c1062df1990c46222aefefd97caa4ba54a2dfcafa68c21811
6
+ metadata.gz: 2b1ba31c1909eba6bb44ad66959b731cd1cef3b8d3c6775ba522da5bf0b825407c0c74587aa8810fffb1df34ec2e696def2990b48e0dcfae4ffac9dfd6270ea7
7
+ data.tar.gz: a4d49277f457e15d2f9562654a7dcd9e9cda745d867f36446f3a649bafda9d2f017ba05c0e30acadbb5f6006c7f97990dbeb8b613eb33b8f6a6333723aa8d97b
data/README.md CHANGED
@@ -399,6 +399,10 @@ submit a pull request.
399
399
  * Rename Asset#digest to Asset#hexdigest. Asset#digest is deprecated and will
400
400
  return a raw byte String in 4.x.
401
401
 
402
+ **2.12.3** (October 28, 2014)
403
+
404
+ * Security: Fix directory traversal bug in development mode server.
405
+
402
406
  **2.12.2** (September 5, 2014)
403
407
 
404
408
  * Ensure internal asset lookups calls are still restricted to load paths within
@@ -127,7 +127,7 @@ module Sprockets
127
127
  @source
128
128
  else
129
129
  # File is read everytime to avoid memory bloat of large binary files
130
- File.open(filename, 'rb') { |f| f.read }
130
+ File.binread(filename)
131
131
  end
132
132
  end
133
133
 
@@ -14,16 +14,21 @@ module Sprockets
14
14
  #
15
15
  # Returns String path and Hash of symbolized parameters.
16
16
  def self.parse(str)
17
- uri = URI(str)
17
+ scheme, _, host, port, _, path, _, query, _ = URI.split(str)
18
18
 
19
- unless uri.scheme == 'file'
19
+ unless scheme == 'file'
20
20
  raise URI::InvalidURIError, "expected file:// scheme: #{str}"
21
21
  end
22
22
 
23
- path = URI::Generic::DEFAULT_PARSER.unescape(uri.path)
23
+ path = URI::Generic::DEFAULT_PARSER.unescape(path)
24
24
  path.force_encoding(Encoding::UTF_8)
25
25
 
26
- params = uri.query.to_s.split('&').reduce({}) do |h, p|
26
+ # Hack for parsing Windows "file://C:/Users/IEUser" paths
27
+ if host && port == ""
28
+ path = "#{host}:#{path}"
29
+ end
30
+
31
+ params = query.to_s.split('&').reduce({}) do |h, p|
27
32
  k, v = p.split('=', 2)
28
33
  h.merge(k.to_sym => v || true)
29
34
  end
@@ -176,7 +176,9 @@ module Sprockets
176
176
  processors = bundled_processors.any? ? bundled_processors : processed_processors
177
177
  processors += unwrap_encoding_processors(params[:encoding])
178
178
 
179
- if processors.any?
179
+ # Read into memory and process if theres a processor pipeline or the
180
+ # content type is text.
181
+ if processors.any? || mime_type_charset_detecter(type)
180
182
  asset.merge!(process(
181
183
  [method(:read_input)] + processors,
182
184
  asset[:uri],
@@ -52,6 +52,9 @@ module Sprockets
52
52
  elsif klass == Fixnum
53
53
  digest << 'Fixnum'
54
54
  digest << obj.to_s
55
+ elsif klass == Bignum
56
+ digest << 'Bignum'
57
+ digest << obj.to_s
55
58
  elsif klass == TrueClass
56
59
  digest << 'TrueClass'
57
60
  elsif klass == FalseClass
@@ -64,6 +64,19 @@ module Sprockets
64
64
  end
65
65
  end
66
66
 
67
+ # Internal: Get detecter function for MIME type.
68
+ #
69
+ # mime_type - String MIME type
70
+ #
71
+ # Returns Proc detector or nil if none is available.
72
+ def mime_type_charset_detecter(mime_type)
73
+ if type = mime_types[mime_type]
74
+ if detect = type[:charset]
75
+ return detect
76
+ end
77
+ end
78
+ end
79
+
67
80
  # Public: Read file on disk with MIME type specific encoding.
68
81
  #
69
82
  # filename - String path
@@ -72,15 +85,13 @@ module Sprockets
72
85
  # Returns String file contents transcoded to UTF-8 or in its external
73
86
  # encoding.
74
87
  def read_file(filename, content_type = nil)
75
- data = File.open(filename, 'rb') { |f| f.read }
88
+ data = File.binread(filename)
76
89
 
77
- if type = mime_types[content_type]
78
- if charset = type[:charset]
79
- data = charset.call(data).encode(Encoding::UTF_8)
80
- end
90
+ if detect = mime_type_charset_detecter(content_type)
91
+ detect.call(data).encode(Encoding::UTF_8, :universal_newline => true)
92
+ else
93
+ data
81
94
  end
82
-
83
- data
84
95
  end
85
96
 
86
97
  # Public: Mapping of supported HTTP Content/Transfer encodings
@@ -42,7 +42,7 @@ module Sprockets
42
42
  # Returns an empty `Array` if the directory does not exist.
43
43
  def entries(path)
44
44
  if File.directory?(path)
45
- Dir.entries(path).reject { |entry| entry =~ /^\.|~$|^\#.*\#$/ }.sort
45
+ Dir.entries(path, :encoding => Encoding.default_internal).reject { |entry| entry =~ /^\.|~$|^\#.*\#$/ }.sort
46
46
  else
47
47
  []
48
48
  end
@@ -54,9 +54,12 @@ module Sprockets
54
54
  #
55
55
  # Returns true if path is absolute, otherwise false.
56
56
  if File::ALT_SEPARATOR
57
+ require 'pathname'
58
+
57
59
  # On Windows, ALT_SEPARATOR is \
60
+ # Delegate to Pathname nice the logic gets complex.
58
61
  def absolute_path?(path)
59
- path[0] == File::SEPARATOR || path[0] == File::ALT_SEPARATOR
62
+ Pathname.new(path).absolute?
60
63
  end
61
64
  else
62
65
  def absolute_path?(path)
@@ -64,6 +67,12 @@ module Sprockets
64
67
  end
65
68
  end
66
69
 
70
+ if File::ALT_SEPARATOR
71
+ SEPARATOR_PATTERN = "#{Regexp.quote(File::SEPARATOR)}|#{Regexp.quote(File::ALT_SEPARATOR)}"
72
+ else
73
+ SEPARATOR_PATTERN = "#{Regexp.quote(File::SEPARATOR)}"
74
+ end
75
+
67
76
  # Internal: Check if path is explicitly relative.
68
77
  # Starts with "./" or "../".
69
78
  #
@@ -71,7 +80,7 @@ module Sprockets
71
80
  #
72
81
  # Returns true if path is relative, otherwise false.
73
82
  def relative_path?(path)
74
- path =~ /^\.\.?($|\/)/ ? true : false
83
+ path =~ /^\.\.?($|#{SEPARATOR_PATTERN})/ ? true : false
75
84
  end
76
85
 
77
86
  # Internal: Get relative path for root path and subpath.
@@ -110,7 +110,8 @@ module Sprockets
110
110
 
111
111
  if absolute_path?(path)
112
112
  path = File.expand_path(path)
113
- if file?(path) && (accept.nil? || resolve_path_transform_type(path, accept))
113
+ if paths_split(self.paths, path) && file?(path) &&
114
+ (accept.nil? || resolve_path_transform_type(path, accept))
114
115
  filename = path
115
116
  type = resolve_path_transform_type(path, accept)
116
117
  end
@@ -32,16 +32,16 @@ module Sprockets
32
32
  # Extract the path from everything after the leading slash
33
33
  path = Rack::Utils.unescape(env['PATH_INFO'].to_s.sub(/^\//, ''))
34
34
 
35
- # URLs containing a `".."` are rejected for security reasons.
36
- if forbidden_request?(path)
37
- return forbidden_response
38
- end
39
-
40
35
  # Strip fingerprint
41
36
  if fingerprint = path_fingerprint(path)
42
37
  path = path.sub("-#{fingerprint}", '')
43
38
  end
44
39
 
40
+ # URLs containing a `".."` are rejected for security reasons.
41
+ if forbidden_request?(path)
42
+ return forbidden_response
43
+ end
44
+
45
45
  # Look up the asset.
46
46
  options = {}
47
47
  options[:bundle] = !body_only?(env)
@@ -115,7 +115,7 @@ module Sprockets
115
115
  #
116
116
  # http://example.org/assets/../../../etc/passwd
117
117
  #
118
- path.include?("..")
118
+ path.include?("..") || absolute_path?(path)
119
119
  end
120
120
 
121
121
  # Returns a 200 OK response tuple
@@ -271,7 +271,7 @@ module Sprockets
271
271
  # # => "0aa2105d29558f3eb790d411d7d8fb66"
272
272
  #
273
273
  def path_fingerprint(path)
274
- path[/-([0-9a-f]{7,128})\.[^.]+$/, 1]
274
+ path[/-([0-9a-f]{7,128})\.[^.]+\z/, 1]
275
275
  end
276
276
  end
277
277
  end
@@ -1,3 +1,3 @@
1
1
  module Sprockets
2
- VERSION = "3.0.0.beta.2"
2
+ VERSION = "3.0.0.beta.3"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sprockets
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0.beta.2
4
+ version: 3.0.0.beta.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sam Stephenson
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-10-10 00:00:00.000000000 Z
12
+ date: 2014-10-28 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rack