Skip to content
This repository

Overlap un-compatibility previous param when parsing url query string #525

Closed
wants to merge 1 commit into from

2 participants

Mc.Spring James Tucker
Mc.Spring

It should not raise exception when parsing url query string. Because rack should not restrict how user accesses resources. This pull request use L2R principle for un-compatibility params overlap.

James Tucker raggi closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
21  lib/rack/utils.rb
@@ -110,21 +110,30 @@ def normalize_params(params, name, v = nil)
110 110
       if after == ""
111 111
         params[k] = v
112 112
       elsif after == "[]"
113  
-        params[k] ||= []
114  
-        raise TypeError, "expected Array (got #{params[k].class.name}) for param `#{k}'" unless params[k].is_a?(Array)
  113
+        # Overlap un-compatibility previous
  114
+        if params[k].nil? || !params[k].is_a?(Array)
  115
+          params[k] = []
  116
+        end
  117
+
115 118
         params[k] << v
116 119
       elsif after =~ %r(^\[\]\[([^\[\]]+)\]$) || after =~ %r(^\[\](.+)$)
  120
+        # Overlap un-compatibility previous
  121
+        if params[k].nil? || !params[k].is_a?(Array)
  122
+          params[k] = []
  123
+        end
  124
+
117 125
         child_key = $1
118  
-        params[k] ||= []
119  
-        raise TypeError, "expected Array (got #{params[k].class.name}) for param `#{k}'" unless params[k].is_a?(Array)
120 126
         if params_hash_type?(params[k].last) && !params[k].last.key?(child_key)
121 127
           normalize_params(params[k].last, child_key, v)
122 128
         else
123 129
           params[k] << normalize_params(params.class.new, child_key, v)
124 130
         end
125 131
       else
126  
-        params[k] ||= params.class.new
127  
-        raise TypeError, "expected Hash (got #{params[k].class.name}) for param `#{k}'" unless params_hash_type?(params[k])
  132
+        # Overlap un-compatibility previous
  133
+        if params[k].nil? || !params_hash_type?(params[k])
  134
+          params[k] = KeySpaceConstrainedParams.new
  135
+        end
  136
+
128 137
         params[k] = normalize_params(params[k], after, v)
129 138
       end
130 139
 
55  test/spec_utils.rb
@@ -6,7 +6,7 @@
6 6
 describe Rack::Utils do
7 7
 
8 8
   # A helper method which checks
9  
-  # if certain query parameters 
  9
+  # if certain query parameters
10 10
   # are equal.
11 11
   def equal_query_to(query)
12 12
     parts = query.split('&')
@@ -78,7 +78,7 @@ def kcodeu
78 78
       Rack::Utils.escape("ø".encode("ISO-8859-1")).should.equal "%F8"
79 79
     end
80 80
   end
81  
-  
  81
+
82 82
   should "not hang on escaping long strings that end in % (http://redmine.ruby-lang.org/issues/5149)" do
83 83
     lambda {
84 84
       timeout(1) do
@@ -191,17 +191,50 @@ def kcodeu
191 191
     Rack::Utils.parse_nested_query("x[y][][z]=1&x[y][][w]=a&x[y][][z]=2&x[y][][w]=3").
192 192
       should.equal "x" => {"y" => [{"z" => "1", "w" => "a"}, {"z" => "2", "w" => "3"}]}
193 193
 
194  
-    lambda { Rack::Utils.parse_nested_query("x[y]=1&x[y]z=2") }.
195  
-      should.raise(TypeError).
196  
-      message.should.equal "expected Hash (got String) for param `y'"
  194
+    # Test Hash overlap
  195
+    Rack::Utils.parse_nested_query("x=1&x[y]=2").
  196
+      should.equal "x" => {"y" => "2"}
  197
+
  198
+    Rack::Utils.parse_nested_query("x[]=1&x=2").
  199
+      should.equal "x" => "2"
  200
+
  201
+    Rack::Utils.parse_nested_query("x[]=1&x[y]=2").
  202
+      should.equal "x" => {"y" => "2"}
  203
+
  204
+    Rack::Utils.parse_nested_query("x[y]=1&x[y][z]=2").
  205
+      should.equal "x" => {"y" => {"z" => "2"}}
  206
+
  207
+    Rack::Utils.parse_nested_query("x[y][]=1&x[y]=2").
  208
+      should.equal "x" => {"y" => "2"}
  209
+
  210
+    Rack::Utils.parse_nested_query("x[y][]=1&x[y][z]=2").
  211
+      should.equal "x" => {"y" => {"z" => "2"}}
  212
+
  213
+    # Test Array overlap
  214
+    Rack::Utils.parse_nested_query("x=1&x[]=2").
  215
+      should.equal "x" => ["2"]
  216
+
  217
+    Rack::Utils.parse_nested_query("x[y]=1&x[]=2").
  218
+      should.equal "x" => ["2"]
  219
+
  220
+    Rack::Utils.parse_nested_query("x=1&x[][y]=2").
  221
+      should.equal "x" => [{"y" => "2"}]
  222
+
  223
+    Rack::Utils.parse_nested_query("x[y]=1&x[][y]=2").
  224
+      should.equal "x" => [{"y" => "2"}]
  225
+
  226
+    Rack::Utils.parse_nested_query("x[y][z]=1&x[y][]=2").
  227
+      should.equal "x" => {"y" => ["2"]}
  228
+
  229
+    # Test Hash & Array mix overlap
  230
+    Rack::Utils.parse_nested_query("x[y]=1&x[y][]=2").
  231
+      should.equal "x" => {"y" => ["2"]}
197 232
 
198  
-    lambda { Rack::Utils.parse_nested_query("x[y]=1&x[]=1") }.
199  
-      should.raise(TypeError).
200  
-      message.should.match(/expected Array \(got [^)]*\) for param `x'/)
  233
+    Rack::Utils.parse_nested_query("x[y]=1&x[y][][z]=2").
  234
+      should.equal "x" => {"y" => [{"z" => "2"}]}
201 235
 
202  
-    lambda { Rack::Utils.parse_nested_query("x[y]=1&x[y][][w]=2") }.
203  
-      should.raise(TypeError).
204  
-      message.should.equal "expected Array (got String) for param `y'"
  236
+    Rack::Utils.parse_nested_query("x[y]=1&x[y][]=2&x[y][][z]=3").
  237
+      should.equal "x" => {"y" => ["2", {"z" => "3"}]}
205 238
   end
206 239
 
207 240
   should "build query strings correctly" do
Commit_comment_tip

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.