diff --git a/lib/webrick/httputils.rb b/lib/webrick/httputils.rb index e2c2a40..1d9324f 100644 --- a/lib/webrick/httputils.rb +++ b/lib/webrick/httputils.rb @@ -471,14 +471,20 @@ def parse_form_data(io, boundary) def _make_regex(str) /([#{Regexp.escape(str)}])/n end def _make_regex!(str) /([^#{Regexp.escape(str)}])/n end + def _ensure_string(str) + unless str.is_a?(String) + raise TypeError, "no implicit conversion of #{str.class} into String" + end + str + end def _escape(str, regex) - str = str.b + str = _ensure_string(str).b str.gsub!(regex) {"%%%02X" % $1.ord} # %-escaped string should contain US-ASCII only str.force_encoding(Encoding::US_ASCII) end def _unescape(str, regex) - str = str.b + str = _ensure_string(str).b str.gsub!(regex) {$1.hex.chr} # encoding of %-unescaped string is unknown str @@ -519,7 +525,7 @@ def escape_form(str) # Unescapes form reserved characters in +str+ def unescape_form(str) - _unescape(str.gsub(/\+/, " "), ESCAPED) + _unescape(_ensure_string(str).gsub(/\+/, " "), ESCAPED) end ## diff --git a/test/webrick/test_httputils.rb b/test/webrick/test_httputils.rb index 00f297b..86d9a99 100644 --- a/test/webrick/test_httputils.rb +++ b/test/webrick/test_httputils.rb @@ -98,4 +98,14 @@ def test_escape_path assert_equal("/foo/bar/", escape_path("/foo/bar/")) assert_equal("/%25foo/bar/", escape_path("/%foo/bar/")) end + + def test_escape_with_nil_raises_clear_type_error + # [Bug: nil raised a confusing NoMethodError ("undefined method 'b' + # for nil:NilClass") instead of a clear, documented error - see + # https://github.com/ruby/webrick/issues/96 + [:escape, :unescape, :escape_form, :unescape_form].each do |meth| + err = assert_raise(TypeError) { send(meth, nil) } + assert_equal("no implicit conversion of NilClass into String", err.message) + end + end end