summary refs log tree commit
diff options
context:
space:
mode:
authorMatthew Draper <matthew@trebex.net>2016-03-12 09:30:52 +1030
committerMatthew Draper <matthew@trebex.net>2016-03-12 09:30:52 +1030
commit09084fd2db976d74bfbcb5779a7c131d1943f3e2 (patch)
tree006b93ff7772f49f308136185ed4cdb0dafdb648
parent05bdc51dd7d39f6cea66481cd89143da0df1b41c (diff)
parenta8a908f1ab62f279eb18d3869c3433eb67037e0a (diff)
downloadrack-09084fd2db976d74bfbcb5779a7c131d1943f3e2.tar.gz
Merge pull request #1029 from rthbound/fixes-951-fixes-1015
Fixes 951 fixes 1015
-rw-r--r--lib/rack/query_parser.rb11
-rw-r--r--test/spec_utils.rb15
2 files changed, 22 insertions, 4 deletions
diff --git a/lib/rack/query_parser.rb b/lib/rack/query_parser.rb
index 72a521f3..17b77128 100644
--- a/lib/rack/query_parser.rb
+++ b/lib/rack/query_parser.rb
@@ -82,7 +82,13 @@ module Rack
       k = $1 || ''.freeze
       after = $' || ''.freeze
 
-      return if k.empty?
+      if k.empty?
+        if !v.nil? && name == "[]".freeze
+          return Array(v)
+        else
+          return
+        end
+      end
 
       if after == ''.freeze
         params[k] = v
@@ -96,7 +102,8 @@ module Rack
         child_key = $1
         params[k] ||= []
         raise ParameterTypeError, "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)
+        first_key = child_key.gsub(/[\[\]]/, ' ').split.first
+        if params_hash_type?(params[k].last) && !params[k].last.key?(first_key)
           normalize_params(params[k].last, child_key, v, depth - 1)
         else
           params[k] << normalize_params(make_params, child_key, v, depth - 1)
diff --git a/test/spec_utils.rb b/test/spec_utils.rb
index 17a12115..b24762c9 100644
--- a/test/spec_utils.rb
+++ b/test/spec_utils.rb
@@ -206,6 +206,14 @@ describe Rack::Utils do
     Rack::Utils.parse_nested_query("x[y][][z]=1&x[y][][w]=a&x[y][][z]=2&x[y][][w]=3").
       must_equal "x" => {"y" => [{"z" => "1", "w" => "a"}, {"z" => "2", "w" => "3"}]}
 
+    Rack::Utils.parse_nested_query("x[][y]=1&x[][z][w]=a&x[][y]=2&x[][z][w]=b").
+      must_equal "x" => [{"y" => "1", "z" => {"w" => "a"}}, {"y" => "2", "z" => {"w" => "b"}}]
+    Rack::Utils.parse_nested_query("x[][z][w]=a&x[][y]=1&x[][z][w]=b&x[][y]=2").
+      must_equal "x" => [{"y" => "1", "z" => {"w" => "a"}}, {"y" => "2", "z" => {"w" => "b"}}]
+
+    Rack::Utils.parse_nested_query("data[books][][data][page]=1&data[books][][data][page]=2").
+      must_equal "data" => { "books" => [{ "data" => { "page" => "1"}}, { "data" => { "page" => "2"}}] }
+
     lambda { Rack::Utils.parse_nested_query("x[y]=1&x[y]z=2") }.
       must_raise(Rack::Utils::ParameterTypeError).
       message.must_equal "expected Hash (got String) for param `y'"
@@ -300,13 +308,15 @@ describe Rack::Utils do
       must_equal 'x[y][][z]=1&x[y][][z]=2'
     Rack::Utils.build_nested_query('x' => { 'y' => [{ 'z' => '1', 'w' => 'a' }, { 'z' => '2', 'w' => '3' }] }).
       must_equal 'x[y][][z]=1&x[y][][w]=a&x[y][][z]=2&x[y][][w]=3'
+    Rack::Utils.build_nested_query({"foo" => ["1", ["2"]]}).
+      must_equal 'foo[]=1&foo[][]=2'
 
     lambda { Rack::Utils.build_nested_query("foo=bar") }.
       must_raise(ArgumentError).
       message.must_equal "value must be a Hash"
   end
 
-  should 'perform the inverse function of #parse_nested_query' do
+  it 'performs the inverse function of #parse_nested_query' do
     [{"foo" => nil, "bar" => ""},
       {"foo" => "bar", "baz" => ""},
       {"foo" => ["1", "2"]},
@@ -323,7 +333,8 @@ describe Rack::Utils do
       {"x" => {"y" => [{"v" => {"w" => "1"}}]}},
       {"x" => {"y" => [{"z" => "1", "v" => {"w" => "2"}}]}},
       {"x" => {"y" => [{"z" => "1"}, {"z" => "2"}]}},
-      {"x" => {"y" => [{"z" => "1", "w" => "a"}, {"z" => "2", "w" => "3"}]}}
+      {"x" => {"y" => [{"z" => "1", "w" => "a"}, {"z" => "2", "w" => "3"}]}},
+      {"foo" => ["1", ["2"]]},
     ].each { |params|
       qs = Rack::Utils.build_nested_query(params)
       Rack::Utils.parse_nested_query(qs).must_equal params