Skip to content

Loading…

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

Closed
wants to merge 1 commit into from

2 participants

@mcspring

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.

@raggi raggi closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Showing with 59 additions and 17 deletions.
  1. +15 −6 lib/rack/utils.rb
  2. +44 −11 test/spec_utils.rb
View
21 lib/rack/utils.rb
@@ -110,21 +110,30 @@ def normalize_params(params, name, v = nil)
if after == ""
params[k] = v
elsif after == "[]"
- params[k] ||= []
- raise TypeError, "expected Array (got #{params[k].class.name}) for param `#{k}'" unless params[k].is_a?(Array)
+ # Overlap un-compatibility previous
+ if params[k].nil? || !params[k].is_a?(Array)
+ params[k] = []
+ end
+
params[k] << v
elsif after =~ %r(^\[\]\[([^\[\]]+)\]$) || after =~ %r(^\[\](.+)$)
+ # Overlap un-compatibility previous
+ if params[k].nil? || !params[k].is_a?(Array)
+ params[k] = []
+ end
+
child_key = $1
- params[k] ||= []
- raise TypeError, "expected Array (got #{params[k].class.name}) for param `#{k}'" unless params[k].is_a?(Array)
if params_hash_type?(params[k].last) && !params[k].last.key?(child_key)
normalize_params(params[k].last, child_key, v)
else
params[k] << normalize_params(params.class.new, child_key, v)
end
else
- params[k] ||= params.class.new
- raise TypeError, "expected Hash (got #{params[k].class.name}) for param `#{k}'" unless params_hash_type?(params[k])
+ # Overlap un-compatibility previous
+ if params[k].nil? || !params_hash_type?(params[k])
+ params[k] = KeySpaceConstrainedParams.new
+ end
+
params[k] = normalize_params(params[k], after, v)
end
View
55 test/spec_utils.rb
@@ -6,7 +6,7 @@
describe Rack::Utils do
# A helper method which checks
- # if certain query parameters
+ # if certain query parameters
# are equal.
def equal_query_to(query)
parts = query.split('&')
@@ -78,7 +78,7 @@ def kcodeu
Rack::Utils.escape("ø".encode("ISO-8859-1")).should.equal "%F8"
end
end
-
+
should "not hang on escaping long strings that end in % (http://redmine.ruby-lang.org/issues/5149)" do
lambda {
timeout(1) do
@@ -191,17 +191,50 @@ def kcodeu
Rack::Utils.parse_nested_query("x[y][][z]=1&x[y][][w]=a&x[y][][z]=2&x[y][][w]=3").
should.equal "x" => {"y" => [{"z" => "1", "w" => "a"}, {"z" => "2", "w" => "3"}]}
- lambda { Rack::Utils.parse_nested_query("x[y]=1&x[y]z=2") }.
- should.raise(TypeError).
- message.should.equal "expected Hash (got String) for param `y'"
+ # Test Hash overlap
+ Rack::Utils.parse_nested_query("x=1&x[y]=2").
+ should.equal "x" => {"y" => "2"}
+
+ Rack::Utils.parse_nested_query("x[]=1&x=2").
+ should.equal "x" => "2"
+
+ Rack::Utils.parse_nested_query("x[]=1&x[y]=2").
+ should.equal "x" => {"y" => "2"}
+
+ Rack::Utils.parse_nested_query("x[y]=1&x[y][z]=2").
+ should.equal "x" => {"y" => {"z" => "2"}}
+
+ Rack::Utils.parse_nested_query("x[y][]=1&x[y]=2").
+ should.equal "x" => {"y" => "2"}
+
+ Rack::Utils.parse_nested_query("x[y][]=1&x[y][z]=2").
+ should.equal "x" => {"y" => {"z" => "2"}}
+
+ # Test Array overlap
+ Rack::Utils.parse_nested_query("x=1&x[]=2").
+ should.equal "x" => ["2"]
+
+ Rack::Utils.parse_nested_query("x[y]=1&x[]=2").
+ should.equal "x" => ["2"]
+
+ Rack::Utils.parse_nested_query("x=1&x[][y]=2").
+ should.equal "x" => [{"y" => "2"}]
+
+ Rack::Utils.parse_nested_query("x[y]=1&x[][y]=2").
+ should.equal "x" => [{"y" => "2"}]
+
+ Rack::Utils.parse_nested_query("x[y][z]=1&x[y][]=2").
+ should.equal "x" => {"y" => ["2"]}
+
+ # Test Hash & Array mix overlap
+ Rack::Utils.parse_nested_query("x[y]=1&x[y][]=2").
+ should.equal "x" => {"y" => ["2"]}
- lambda { Rack::Utils.parse_nested_query("x[y]=1&x[]=1") }.
- should.raise(TypeError).
- message.should.match(/expected Array \(got [^)]*\) for param `x'/)
+ Rack::Utils.parse_nested_query("x[y]=1&x[y][][z]=2").
+ should.equal "x" => {"y" => [{"z" => "2"}]}
- lambda { Rack::Utils.parse_nested_query("x[y]=1&x[y][][w]=2") }.
- should.raise(TypeError).
- message.should.equal "expected Array (got String) for param `y'"
+ Rack::Utils.parse_nested_query("x[y]=1&x[y][]=2&x[y][][z]=3").
+ should.equal "x" => {"y" => ["2", {"z" => "3"}]}
end
should "build query strings correctly" do
Something went wrong with that request. Please try again.