Index: lib/uri/common.rb =================================================================== --- lib/uri/common.rb (revision 39770) +++ lib/uri/common.rb (working copy) @@ -971,12 +971,12 @@ # See URI.decode_www_form_component, URI.encode_www_form def self.decode_www_form(str, enc=Encoding::UTF_8) return [] if str.empty? - unless /\A#{WFKV_}=#{WFKV_}(?:[;&]#{WFKV_}=#{WFKV_})*\z/o =~ str + unless /\A#{WFKV_}(=#{WFKV_})?(?:[;&]#{WFKV_}(=#{WFKV_})?)*\z/o =~ str raise ArgumentError, "invalid data of application/x-www-form-urlencoded (#{str})" end ary = [] - $&.scan(/([^=;&]+)=([^;&]*)/) do - ary << [decode_www_form_component($1, enc), decode_www_form_component($2, enc)] + $&.scan(/([^=;&]+)(?:=([^;&]*))?/) do + ary << [decode_www_form_component($1, enc), (decode_www_form_component($2, enc) if $2)] end ary end Index: test/uri/test_common.rb =================================================================== --- test/uri/test_common.rb (revision 39770) +++ test/uri/test_common.rb (working copy) @@ -109,14 +109,14 @@ assert_equal([%w[a 1], ["\u3042", "\u6F22"]], URI.decode_www_form("a=1;%E3%81%82=%E6%BC%A2")) assert_equal([%w[?a 1], %w[a 2]], URI.decode_www_form("?a=1&a=2")) + assert_equal([['a', nil], ['b', nil]], URI.decode_www_form("a&b")) assert_equal([], URI.decode_www_form("")) assert_raise(ArgumentError){URI.decode_www_form("%=1")} assert_raise(ArgumentError){URI.decode_www_form("a=%")} assert_raise(ArgumentError){URI.decode_www_form("a=1&%=2")} assert_raise(ArgumentError){URI.decode_www_form("a=1&b=%")} - assert_raise(ArgumentError){URI.decode_www_form("a&b")} - bug4098 = '[ruby-core:33464]' - assert_raise(ArgumentError, bug4098){URI.decode_www_form("a=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA&b")} + # ruby-core:33464 regression test + assert_equal([["a", "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"], ["b", nil]], URI.decode_www_form("a=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA&b")) end end