diff options
author | Samuel Williams <samuel.williams@oriontransfer.co.nz> | 2023-03-13 17:50:30 +1300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-03-13 17:50:30 +1300 |
commit | 59d9ba903fdb50cf8db708c8263a7b2a79de83fb (patch) | |
tree | b652c0f40eaf3544268cc4e754ffe57c04332a47 | |
parent | eda1fb34d08134fea0cd7cf9eca6533deb41b734 (diff) | |
download | rack-59d9ba903fdb50cf8db708c8263a7b2a79de83fb.tar.gz |
Add `QueryParser#missing_value` for handling missing values + tests. (#2052)
-rw-r--r-- | lib/rack.rb | 1 | ||||
-rw-r--r-- | lib/rack/query_parser.rb | 15 | ||||
-rw-r--r-- | test/spec_query_parser.rb | 33 |
3 files changed, 46 insertions, 3 deletions
diff --git a/lib/rack.rb b/lib/rack.rb index 69780545..d00b9666 100644 --- a/lib/rack.rb +++ b/lib/rack.rb @@ -41,6 +41,7 @@ module Rack autoload :MethodOverride, "rack/method_override" autoload :Mime, "rack/mime" autoload :NullLogger, "rack/null_logger" + autoload :QueryParser, "rack/query_parser" autoload :Recursive, "rack/recursive" autoload :Reloader, "rack/reloader" autoload :RewindableInput, "rack/rewindable_input" diff --git a/lib/rack/query_parser.rb b/lib/rack/query_parser.rb index 1c05ae82..525900f7 100644 --- a/lib/rack/query_parser.rb +++ b/lib/rack/query_parser.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true require_relative 'bad_request' +require 'uri' module Rack class QueryParser @@ -111,6 +112,14 @@ module Rack _normalize_params(params, name, v, 0) end + # This value is used by default when a parameter is missing (nil). This + # usually happens when a parameter is specified without an `=value` part. + # The default value is an empty string, but this can be overridden by + # subclasses. + def missing_value + String.new + end + private def _normalize_params(params, name, v, depth) raise ParamsTooDeepError if depth >= param_depth_limit @@ -145,7 +154,7 @@ module Rack return if k.empty? - v ||= String.new + v ||= missing_value if after == '' if k == '[]' && depth != 0 @@ -207,8 +216,8 @@ module Rack true end - def unescape(s) - Utils.unescape(s) + def unescape(string, encoding = Encoding::UTF_8) + URI.decode_www_form_component(string, encoding) end class Params < Hash diff --git a/test/spec_query_parser.rb b/test/spec_query_parser.rb new file mode 100644 index 00000000..5f470818 --- /dev/null +++ b/test/spec_query_parser.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +require_relative 'helper' + +separate_testing do + require_relative '../lib/rack/query_parser' +end + +describe Rack::QueryParser do + def query_parser + @query_parser ||= Rack::QueryParser.new(Rack::QueryParser::Params, 8) + end + + it "has a default value" do + assert_equal "", query_parser.missing_value + end + + 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" => ""}) + end + + it "can override default missing value" do + def query_parser.missing_value + nil + end + + 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}) + end +end |