Skip to content

Commit

Permalink
Make query parameters without = have empty string values
Browse files Browse the repository at this point in the history
This was reverted in 77cf057
so that Rails could have historical Rack behavior without the
complexity of splitting form/query parsing.

Now that splitting form/query parsing has been added back in
3855d1d, this changes the
behavior to what originally shipped in Rack 3.

This matches URL spec section 5.1.3.3.  Frameworks that want
Rack's historical behavior of using nil values instead of
empty string values can reparse QUERY_STRING and use
rack.request.form_pairs to get the behavior they want.
  • Loading branch information
jeremyevans committed Jul 19, 2023
1 parent 444dc8a commit d28fa2a
Show file tree
Hide file tree
Showing 4 changed files with 12 additions and 10 deletions.
2 changes: 2 additions & 0 deletions lib/rack/query_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,8 @@ def normalize_params(params, name, v, _depth=nil)

return if k.empty?

v ||= String.new

if after == ''
if k == '[]' && depth != 0
return [v]
Expand Down
2 changes: 1 addition & 1 deletion test/spec_query_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@
it "can normalize values with missing values" do
query_parser.parse_nested_query("a=a").must_equal({"a" => "a"})
query_parser.parse_nested_query("a=").must_equal({"a" => ""})
query_parser.parse_nested_query("a").must_equal({"a" => nil})
query_parser.parse_nested_query("a").must_equal({"a" => ""})
end
end
4 changes: 2 additions & 2 deletions test/spec_request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -583,9 +583,9 @@ def self.req(headers)
it "parse the query string" do
request = make_request(Rack::MockRequest.env_for("/?foo=bar&quux=bla&nothing&empty="))
request.query_string.must_equal "foo=bar&quux=bla&nothing&empty="
request.GET.must_equal "foo" => "bar", "quux" => "bla", "nothing" => nil, "empty" => ""
request.GET.must_equal "foo" => "bar", "quux" => "bla", "nothing" => "", "empty" => ""
request.POST.must_be :empty?
request.params.must_equal "foo" => "bar", "quux" => "bla", "nothing" => nil, "empty" => ""
request.params.must_equal "foo" => "bar", "quux" => "bla", "nothing" => "", "empty" => ""
end

it "handles invalid unicode in query string value" do
Expand Down
14 changes: 7 additions & 7 deletions test/spec_utils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ def assert_nested_query(exp, act)

it "parse nested query strings correctly" do
Rack::Utils.parse_nested_query("foo").
must_equal "foo" => nil
must_equal "foo" => ""
Rack::Utils.parse_nested_query("foo=").
must_equal "foo" => ""
Rack::Utils.parse_nested_query("foo=bar").
Expand All @@ -158,7 +158,7 @@ def assert_nested_query(exp, act)
Rack::Utils.parse_nested_query("&foo=1&&bar=2").
must_equal "foo" => "1", "bar" => "2"
Rack::Utils.parse_nested_query("foo&bar=").
must_equal "foo" => nil, "bar" => ""
must_equal "foo" => "", "bar" => ""
Rack::Utils.parse_nested_query("foo=bar&baz=").
must_equal "foo" => "bar", "baz" => ""
Rack::Utils.parse_nested_query("my+weird+field=q1%212%22%27w%245%267%2Fz8%29%3F").
Expand All @@ -168,19 +168,19 @@ def assert_nested_query(exp, act)
must_equal "pid=1234" => "1023", "a" => "b"

Rack::Utils.parse_nested_query("foo[]").
must_equal "foo" => [nil]
must_equal "foo" => [""]
Rack::Utils.parse_nested_query("foo[]=").
must_equal "foo" => [""]
Rack::Utils.parse_nested_query("foo[]=bar").
must_equal "foo" => ["bar"]
Rack::Utils.parse_nested_query("foo[]=bar&foo").
must_equal "foo" => nil
must_equal "foo" => ""
Rack::Utils.parse_nested_query("foo[]=bar&foo[").
must_equal "foo" => ["bar"], "foo[" => nil
must_equal "foo" => ["bar"], "foo[" => ""
Rack::Utils.parse_nested_query("foo[]=bar&foo[=baz").
must_equal "foo" => ["bar"], "foo[" => "baz"
Rack::Utils.parse_nested_query("foo[]=bar&foo[]").
must_equal "foo" => ["bar", nil]
must_equal "foo" => ["bar", ""]
Rack::Utils.parse_nested_query("foo[]=bar&foo[]=").
must_equal "foo" => ["bar", ""]

Expand All @@ -192,7 +192,7 @@ def assert_nested_query(exp, act)
must_equal "foo" => ["bar"], "baz" => ["1", "2", "3"]

Rack::Utils.parse_nested_query("x[y][z]").
must_equal "x" => { "y" => { "z" => nil } }
must_equal "x" => { "y" => { "z" => ""} }
Rack::Utils.parse_nested_query("x[y][z]=1").
must_equal "x" => { "y" => { "z" => "1" } }
Rack::Utils.parse_nested_query("x[y][z][]=1").
Expand Down

0 comments on commit d28fa2a

Please sign in to comment.