Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

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.
Showing with 59 additions and 17 deletions.
  1. +15 −6 lib/rack/utils.rb
  2. +44 −11 test/spec_utils.rb
21 lib/rack/utils.rb
View
@@ -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
55 test/spec_utils.rb
View
@@ -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.