diff --git a/lib/cgi/core.rb b/lib/cgi/core.rb index b5c3a1e..69373cb 100644 --- a/lib/cgi/core.rb +++ b/lib/cgi/core.rb @@ -838,13 +838,16 @@ def read_from_cmdline # Handles multipart forms (in particular, forms that involve file uploads). # Reads query parameters in the @params field, and cookies into @cookies. def initialize_query() + content_length = env_table['CONTENT_LENGTH'] + content_length = nil if content_length == '' if ("POST" == env_table['REQUEST_METHOD']) and %r|\Amultipart/form-data.*boundary=\"?([^\";,]+)\"?| =~ env_table['CONTENT_TYPE'] current_max_multipart_length = @max_multipart_length.respond_to?(:call) ? @max_multipart_length.call : @max_multipart_length raise StandardError.new("too large multipart data.") if env_table['CONTENT_LENGTH'].to_i > current_max_multipart_length + raise StandardError.new("no content length for multipart data.") if content_length.nil? boundary = $1.dup @multipart = true - @params = read_multipart(boundary, Integer(env_table['CONTENT_LENGTH'])) + @params = read_multipart(boundary, Integer(content_length)) else @multipart = false @params = CGI.parse( @@ -857,7 +860,11 @@ def initialize_query() end when "POST" stdinput.binmode if defined? stdinput.binmode - stdinput.read(Integer(env_table['CONTENT_LENGTH'])) or '' + if content_length.nil? + stdinput.read or '' + else + stdinput.read(Integer(content_length)) or '' + end else read_from_cmdline end.dup.force_encoding(@accept_charset) diff --git a/test/cgi/test_cgi_core.rb b/test/cgi/test_cgi_core.rb index f7adb7e..b805c31 100644 --- a/test/cgi/test_cgi_core.rb +++ b/test/cgi/test_cgi_core.rb @@ -92,6 +92,33 @@ def test_cgi_core_params_POST $stdin = STDIN end + def test_cgi_core_params_POST_without_content_length + update_env( + 'REQUEST_METHOD' => 'POST', + 'CONTENT_TYPE' => 'application/x-www-form-urlencoded', + ) + $stdin = StringIO.new + cgi = nil + assert_nothing_raised { cgi = CGI.new } + assert_equal({}, cgi.params) + ensure + $stdin = STDIN + end + + def test_cgi_core_params_POST_empty_content_length + update_env( + 'REQUEST_METHOD' => 'POST', + 'CONTENT_TYPE' => 'application/x-www-form-urlencoded', + 'CONTENT_LENGTH' => '', + ) + $stdin = StringIO.new + cgi = nil + assert_nothing_raised { cgi = CGI.new } + assert_equal({}, cgi.params) + ensure + $stdin = STDIN + end + def test_cgi_core_params_encoding_check query_str = 'str=%BE%BE%B9%BE' update_env(