2007年12月 7日

[ruby-list:44321] Re: multipartで送信した時のRails/cgi.rbの動作について

桑田です。

On Dec 6, 2007 5:36 PM, KOSEKI Kengo <kengo@xxxxx> wrote:
> 最初はStringIOに入れておいて、そのフィールドの入力が
> 一定サイズを超えたらTempfileに移行するといいのではと
> 思ったんですが、、。

Ruby1.9のcgi.rbはそのような動作になっているみたいです。

> > 試しにパッチを作成してみました。Ruby1.8.6のcgi.rbをもとにしています。
>
>ありがとうございます!
>試してみます。

新しいパッチを作ったので、こちらを試していただけますか。
multipartでない場合でも、REQUEST_METHODが "POST" なら CONTENT_LENGTH の
長さを調べ、長過ぎるようならエラーにしています。
multipartの場合とそうでない場合とで、制限値を変えています。

Index: lib/cgi.rb
===================================================================
--- /user/local/lib/ruby/1.8/cgi.rb 2007-05-23 06:58:09.000000000 +0900
+++ lib/cgi.rb 2007-12-07 01:00:37.000000000 +0900
@@ -907,6 +907,17 @@
params
end

+
+ # Maximum content length of post data
+ MAX_CONTENT_LENGTH = 2 * 1024 * 1024
+
+ # Maximum content length of multipart data
+ MAX_MULTIPART_LENGTH = 128 * 1024 * 1024
+
+ # Maximum number of parameters when multipart
+ MAX_MULTIPART_COUNT = 128
+
+
# Mixin module. It provides the follow functionality groups:
#
# 1. Access to CGI environment variables as methods. See
@@ -984,9 +995,14 @@
raise EOFError, "bad content body"
end

+ max_count = MAX_MULTIPART_COUNT
+ n = 0
+
loop do
+ raise StandardError.new("too many parameters.") if (n += 1) > max_count
+
head = nil
- if 10240 < content_length
+ if bufsize < content_length
require "tempfile"
body = Tempfile.new("CGI")
else
@@ -1106,7 +1122,11 @@
%r|\Amultipart/form-data.*boundary=\"?([^\";,]+)\"?|n.match(env_table['CONTENT_TYPE'])
boundary = $1.dup
@multipart = true
- @params = read_multipart(boundary,
Integer(env_table['CONTENT_LENGTH']))
+ content_length = Integer(env_table['CONTENT_LENGTH'])
+ if content_length > MAX_MULTIPART_LENGTH
+ raise StandardError.new("too large multipart data.")
+ end
+ @params = read_multipart(boundary, content_length)
else
@multipart = false
@params = CGI::parse(
@@ -1118,8 +1138,12 @@
env_table['QUERY_STRING'] or ""
end
when "POST"
+ content_length = Integer(env_table['CONTENT_LENGTH'])
+ if content_length > MAX_CONTENT_LENGTH
+ raise StandardError.new("too large post data.")
+ end
stdinput.binmode if defined? stdinput.binmode
- stdinput.read(Integer(env_table['CONTENT_LENGTH'])) or ''
+ stdinput.read(content_length) or ''
else
read_from_cmdline
end
===================================================================

これに関連する話ですが、以前質問したときに cgi.rb のテストスクリプトは
存在しないといわれたので、今 cgi.rb のテストスクリプトを書いています。
そのうち公開すると思います。

--
makoto kuwata

投稿者 xml-rpc : 2007年12月 7日 01:13
役に立ちました?:
過去のフィードバック 平均:(0) 総合:(0) 投票回数:(0)
本記事へのTrackback: http://hoop.euqset.org/blog/mt-tb2006.cgi/67317
トラックバック
コメント
コメントする




画像の中に見える文字を入力してください。