rack 3.0.6.1 → 3.0.7

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
  SHA256:
3
- metadata.gz: b43a4c41d97b3e6b9790b04c0713ac20814fa986310ccd17918baaaf3f94b260
4
- data.tar.gz: a461e437f8cf4591d39d4a84fdceec6ffddb3d11c67fc5a4bdf74926e18d80bc
3
+ metadata.gz: 6d78a46e82a591436bcb6103319864e8f4148e56de71e1fc18d3e7c8b2e97751
4
+ data.tar.gz: bbc8b98ab7d2a4c80876e840fe04d20e99b973d274ae5366544154a5cacba4df
5
5
  SHA512:
6
- metadata.gz: cb7fcf3c2fa1cd168ff0373246160eec7fa6d94a6b4e5d88438f2239cf79e8b9df708626b32603f63368c1133ca7b3fb00d16a292ca5214a7740c558201c1a0f
7
- data.tar.gz: 64d3a5fb0603f6f12760bd2ff95a118985eb843b1875d36c9f9f2af37ca413f311e3c566f5861efb159349d9958ef2c78f8d537ba618009d0ca3ac91047d6d53
6
+ metadata.gz: 699070faa7af77eb112f78684073725f304d17604afbd6fec37316ad020903f148ade1c070458999d526d4d49077f47abafca5c1ce1e4d7c12ef7a9bdb4fce5d
7
+ data.tar.gz: 8e0573a8dc26d426a3fd7b2f770b343cb1ea1c1e57f51261a7c8af745bf5d37c5bb637d4a6170a9e904a1dcb8a69b909a6f8c4bb8dae8791800b88cf7d06fd64
data/CHANGELOG.md CHANGED
@@ -2,10 +2,22 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. For info on how to format all future additions to this file please reference [Keep A Changelog](https://keepachangelog.com/en/1.0.0/).
4
4
 
5
+ ## [3.0.7] - 2023-03-16
6
+
7
+ - Make query parameters without `=` have `nil` values. ([#2059](https://github.com/rack/rack/pull/2059), [@jeremyevans])
8
+
5
9
  ## [3.0.6.1] - 2023-03-13
6
10
 
7
11
  - [CVE-2023-27539] Avoid ReDoS in header parsing
8
12
 
13
+ ## [3.0.6] - 2023-03-13
14
+
15
+ - Add `QueryParser#missing_value` for handling missing values + tests. ([#2052](https://github.com/rack/rack/pull/2052), [@ioquatix])
16
+
17
+ ## [3.0.5] - 2023-03-13
18
+
19
+ - Split form/query parsing into two steps. ([#2038](https://github.com/rack/rack/pull/2038), [@matthewd](https://github.com/matthewd))
20
+
9
21
  ## [3.0.4.1] - 2023-03-02
10
22
 
11
23
  - [CVE-2023-27530] Introduce multipart_total_part_limit to limit total parts
@@ -54,13 +54,11 @@ module Rack
54
54
  RACK_RESPONSE_FINISHED = 'rack.response_finished'
55
55
  RACK_REQUEST_FORM_INPUT = 'rack.request.form_input'
56
56
  RACK_REQUEST_FORM_HASH = 'rack.request.form_hash'
57
- RACK_REQUEST_FORM_PAIRS = 'rack.request.form_pairs'
58
57
  RACK_REQUEST_FORM_VARS = 'rack.request.form_vars'
59
58
  RACK_REQUEST_FORM_ERROR = 'rack.request.form_error'
60
59
  RACK_REQUEST_COOKIE_HASH = 'rack.request.cookie_hash'
61
60
  RACK_REQUEST_COOKIE_STRING = 'rack.request.cookie_string'
62
61
  RACK_REQUEST_QUERY_HASH = 'rack.request.query_hash'
63
- RACK_REQUEST_QUERY_PAIRS = 'rack.request.query_pairs'
64
62
  RACK_REQUEST_QUERY_STRING = 'rack.request.query_string'
65
63
  RACK_METHODOVERRIDE_ORIGINAL_METHOD = 'rack.methodoverride.original_method'
66
64
  end
@@ -13,31 +13,6 @@ module Rack
13
13
  module Multipart
14
14
  MULTIPART_BOUNDARY = "AaB03x"
15
15
 
16
- # Accumulator for multipart form data, conforming to the QueryParser API.
17
- # In future, the Parser could return the pair list directly, but that would
18
- # change its API.
19
- class ParamList # :nodoc:
20
- def self.make_params
21
- new
22
- end
23
-
24
- def self.normalize_params(params, key, value)
25
- params << [key, value]
26
- end
27
-
28
- def initialize
29
- @pairs = []
30
- end
31
-
32
- def <<(pair)
33
- @pairs << pair
34
- end
35
-
36
- def to_params_hash
37
- @pairs
38
- end
39
- end
40
-
41
16
  class << self
42
17
  def parse_multipart(env, params = Rack::Utils.default_query_parser)
43
18
  io = env[RACK_INPUT]
@@ -39,42 +39,19 @@ module Rack
39
39
  @param_depth_limit = param_depth_limit
40
40
  end
41
41
 
42
- # Originally stolen from Mongrel, now with some modifications:
42
+ # Stolen from Mongrel, with some small modifications:
43
43
  # Parses a query string by breaking it up at the '&'. You can also use this
44
44
  # to parse cookies by changing the characters used in the second parameter
45
45
  # (which defaults to '&').
46
- #
47
- # Returns an array of 2-element arrays, where the first element is the
48
- # key and the second element is the value.
49
- def split_query(qs, separator = nil, &unescaper)
50
- pairs = []
51
-
52
- if qs && !qs.empty?
53
- unescaper ||= method(:unescape)
54
-
55
- qs.split(separator ? (COMMON_SEP[separator] || /[#{separator}] */n) : DEFAULT_SEP).each do |p|
56
- next if p.empty?
57
- pair = p.split('=', 2).map!(&unescaper)
58
- pair << nil if pair.length == 1
59
- pairs << pair
60
- end
61
- end
62
-
63
- pairs
64
- rescue ArgumentError => e
65
- raise InvalidParameterError, e.message, e.backtrace
66
- end
67
-
68
- # Parses a query string by breaking it up at the '&'. You can also use this
69
- # to parse cookies by changing the characters used in the second parameter
70
- # (which defaults to '&').
71
- #
72
- # Returns a hash where each value is a string (when a key only appears once)
73
- # or an array of strings (when a key appears more than once).
74
46
  def parse_query(qs, separator = nil, &unescaper)
47
+ unescaper ||= method(:unescape)
48
+
75
49
  params = make_params
76
50
 
77
- split_query(qs, separator, &unescaper).each do |k, v|
51
+ (qs || '').split(separator ? (COMMON_SEP[separator] || /[#{separator}] */n) : DEFAULT_SEP).each do |p|
52
+ next if p.empty?
53
+ k, v = p.split('=', 2).map!(&unescaper)
54
+
78
55
  if cur = params[k]
79
56
  if cur.class == Array
80
57
  params[k] << v
@@ -86,7 +63,7 @@ module Rack
86
63
  end
87
64
  end
88
65
 
89
- params.to_h
66
+ return params.to_h
90
67
  end
91
68
 
92
69
  # parse_nested_query expands a query string into structural types. Supported
@@ -97,11 +74,17 @@ module Rack
97
74
  def parse_nested_query(qs, separator = nil)
98
75
  params = make_params
99
76
 
100
- split_query(qs, separator).each do |k, v|
101
- _normalize_params(params, k, v, 0)
77
+ unless qs.nil? || qs.empty?
78
+ (qs || '').split(separator ? (COMMON_SEP[separator] || /[#{separator}] */n) : DEFAULT_SEP).each do |p|
79
+ k, v = p.split('=', 2).map! { |s| unescape(s) }
80
+
81
+ _normalize_params(params, k, v, 0)
82
+ end
102
83
  end
103
84
 
104
- params.to_h
85
+ return params.to_h
86
+ rescue ArgumentError => e
87
+ raise InvalidParameterError, e.message, e.backtrace
105
88
  end
106
89
 
107
90
  # normalize_params recursively expands parameters into structural types. If
@@ -113,14 +96,6 @@ module Rack
113
96
  _normalize_params(params, name, v, 0)
114
97
  end
115
98
 
116
- # This value is used by default when a parameter is missing (nil). This
117
- # usually happens when a parameter is specified without an `=value` part.
118
- # The default value is an empty string, but this can be overridden by
119
- # subclasses.
120
- def missing_value
121
- String.new
122
- end
123
-
124
99
  private def _normalize_params(params, name, v, depth)
125
100
  raise ParamsTooDeepError if depth >= param_depth_limit
126
101
 
@@ -155,8 +130,6 @@ module Rack
155
130
 
156
131
  return if k.empty?
157
132
 
158
- v ||= missing_value
159
-
160
133
  if after == ''
161
134
  if k == '[]' && depth != 0
162
135
  return [v]
data/lib/rack/request.rb CHANGED
@@ -483,22 +483,11 @@ module Rack
483
483
  # Returns the data received in the query string.
484
484
  def GET
485
485
  if get_header(RACK_REQUEST_QUERY_STRING) == query_string
486
- if query_hash = get_header(RACK_REQUEST_QUERY_HASH)
487
- return query_hash
488
- end
489
- end
490
-
491
- set_header(RACK_REQUEST_QUERY_HASH, expand_params(query_param_list))
492
- end
493
-
494
- def query_param_list
495
- if get_header(RACK_REQUEST_QUERY_STRING) == query_string
496
- get_header(RACK_REQUEST_QUERY_PAIRS)
486
+ get_header(RACK_REQUEST_QUERY_HASH)
497
487
  else
498
- query_pairs = split_query(query_string, '&')
499
- set_header RACK_REQUEST_QUERY_STRING, query_string
500
- set_header RACK_REQUEST_QUERY_HASH, nil
501
- set_header(RACK_REQUEST_QUERY_PAIRS, query_pairs)
488
+ query_hash = parse_query(query_string, '&')
489
+ set_header(RACK_REQUEST_QUERY_STRING, query_string)
490
+ set_header(RACK_REQUEST_QUERY_HASH, query_hash)
502
491
  end
503
492
  end
504
493
 
@@ -507,16 +496,6 @@ module Rack
507
496
  # This method support both application/x-www-form-urlencoded and
508
497
  # multipart/form-data.
509
498
  def POST
510
- if get_header(RACK_REQUEST_FORM_INPUT).equal?(get_header(RACK_INPUT))
511
- if form_hash = get_header(RACK_REQUEST_FORM_HASH)
512
- return form_hash
513
- end
514
- end
515
-
516
- set_header(RACK_REQUEST_FORM_HASH, expand_params(body_param_list))
517
- end
518
-
519
- def body_param_list
520
499
  if error = get_header(RACK_REQUEST_FORM_ERROR)
521
500
  raise error.class, error.message, cause: error.cause
522
501
  end
@@ -524,36 +503,36 @@ module Rack
524
503
  begin
525
504
  rack_input = get_header(RACK_INPUT)
526
505
 
527
- form_pairs = nil
528
-
529
- # If the form data has already been memoized from the same
530
- # input:
531
- if get_header(RACK_REQUEST_FORM_INPUT).equal?(rack_input)
532
- if form_pairs = get_header(RACK_REQUEST_FORM_PAIRS)
533
- return form_pairs
506
+ # If the form hash was already memoized:
507
+ if form_hash = get_header(RACK_REQUEST_FORM_HASH)
508
+ # And it was memoized from the same input:
509
+ if get_header(RACK_REQUEST_FORM_INPUT).equal?(rack_input)
510
+ return form_hash
534
511
  end
535
512
  end
536
513
 
514
+ # Otherwise, figure out how to parse the input:
537
515
  if rack_input.nil?
538
- form_pairs = []
516
+ set_header RACK_REQUEST_FORM_INPUT, nil
517
+ set_header(RACK_REQUEST_FORM_HASH, {})
539
518
  elsif form_data? || parseable_data?
540
- unless form_pairs = Rack::Multipart.extract_multipart(self, Rack::Multipart::ParamList)
541
- form_vars = rack_input.read
519
+ unless set_header(RACK_REQUEST_FORM_HASH, parse_multipart)
520
+ form_vars = get_header(RACK_INPUT).read
542
521
 
543
522
  # Fix for Safari Ajax postings that always append \0
544
523
  # form_vars.sub!(/\0\z/, '') # performance replacement:
545
524
  form_vars.slice!(-1) if form_vars.end_with?("\0")
546
525
 
547
526
  set_header RACK_REQUEST_FORM_VARS, form_vars
548
- form_pairs = split_query(form_vars, '&')
527
+ set_header RACK_REQUEST_FORM_HASH, parse_query(form_vars, '&')
549
528
  end
529
+
530
+ set_header RACK_REQUEST_FORM_INPUT, get_header(RACK_INPUT)
531
+ get_header RACK_REQUEST_FORM_HASH
550
532
  else
551
- form_pairs = []
533
+ set_header RACK_REQUEST_FORM_INPUT, get_header(RACK_INPUT)
534
+ set_header(RACK_REQUEST_FORM_HASH, {})
552
535
  end
553
-
554
- set_header RACK_REQUEST_FORM_INPUT, rack_input
555
- set_header RACK_REQUEST_FORM_HASH, nil
556
- set_header(RACK_REQUEST_FORM_PAIRS, form_pairs)
557
536
  rescue => error
558
537
  set_header(RACK_REQUEST_FORM_ERROR, error)
559
538
  raise
@@ -693,28 +672,6 @@ module Rack
693
672
  Rack::Multipart.extract_multipart(self, query_parser)
694
673
  end
695
674
 
696
- def split_query(query, d = '&')
697
- query_parser = query_parser()
698
- unless query_parser.respond_to?(:split_query)
699
- query_parser = Utils.default_query_parser
700
- unless query_parser.respond_to?(:split_query)
701
- query_parser = QueryParser.make_default(0)
702
- end
703
- end
704
-
705
- query_parser.split_query(query, d)
706
- end
707
-
708
- def expand_params(pairs, query_parser = query_parser())
709
- params = query_parser.make_params
710
-
711
- pairs.each do |key, value|
712
- query_parser.normalize_params(params, key, value)
713
- end
714
-
715
- params.to_params_hash
716
- end
717
-
718
675
  def split_header(value)
719
676
  value ? value.strip.split(/[,\s]+/) : []
720
677
  end
data/lib/rack/version.rb CHANGED
@@ -25,7 +25,7 @@ module Rack
25
25
  VERSION
26
26
  end
27
27
 
28
- RELEASE = "3.0.6.1"
28
+ RELEASE = "3.0.7"
29
29
 
30
30
  # Return the Rack release as a dotted string.
31
31
  def self.release
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.6.1
4
+ version: 3.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Leah Neukirchen
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-03-13 00:00:00.000000000 Z
11
+ date: 2023-03-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest
@@ -149,7 +149,7 @@ metadata:
149
149
  changelog_uri: https://github.com/rack/rack/blob/main/CHANGELOG.md
150
150
  documentation_uri: https://rubydoc.info/github/rack/rack
151
151
  source_code_uri: https://github.com/rack/rack
152
- post_install_message:
152
+ post_install_message:
153
153
  rdoc_options: []
154
154
  require_paths:
155
155
  - lib
@@ -164,8 +164,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
164
164
  - !ruby/object:Gem::Version
165
165
  version: '0'
166
166
  requirements: []
167
- rubygems_version: 3.0.3.1
168
- signing_key:
167
+ rubygems_version: 3.4.6
168
+ signing_key:
169
169
  specification_version: 4
170
170
  summary: A modular Ruby webserver interface.
171
171
  test_files: []