• ベストアンサー

CGIのファイルアップローダーでサイズ制限

ファイルアップローダーで下記のCGIを書きましたが、0バイトのファイルだけはどうしても通ってしまいます。どうすればいいでしょうか? ちなみに1バイトでもあればエラーを表示してくれます。 $file_size ++; if($file_size > 1000000){ exitError("ファイルサイズが大きすぎます。1MB以下 にしてください"); } $file_size ++; if($file_size < 500){ exitError("ファイルサイズが小さすぎます。500バイト以上にして下さい。"); } $file_size ++; if($file_size == 0){ exitError("0バイトのファイルです"); } } はじめは <500 だけでもいけると思ったんですが、ダメだったんで ==0 も加えたんですが、やはりダメでした。

質問者が選んだベストアンサー

  • ベストアンサー
noname#205944
noname#205944
回答No.6

訂正(スマソ) $file はファイルとして保存するためにあるのですね while($bytesread = read($filename, $buffer, $BUFSZ)){ $file .= $buffer; $file_size += length($buffer); } で一回やめて if ($file_size > 1000000){ exitError("1つめのError! Size : $file_size byte"); } elsif ($file_size < 500) { exitError("2つめのError! Size : $file_size byte"); } else { exitError("OK! Size : $file_size byte"); } では どうでしょ?

anzyaa
質問者

お礼

edamsさんの言うように、一度処理を止めてからファイル制限のプログラムを開始させたところ上手くいきました。 どうもありがとうございました。

その他の回答 (5)

noname#205944
noname#205944
回答No.5

while($bytesread = read($filename, $buffer, $BUFSZ)){ $file .= $buffer; $file_size; if ($file_size > 1000000){ exitError("1つめのError! Size : $file_size byte"); } elsif ($file_size < 500) { exitError("2つめのError! Size : $file_size byte"); } else { exitError("OK! Size : $file_size byte"); } たぶんこの他にいろいろ省いていると思うので、想像しながら追っていくと $file は何に使うのかわからないのですが・・・ $bytesreadは読み込んだバイト数です また最後に(End-Of-File)になると0を返します つまり、サイズを加算している? つもりなら $file += $buffer では? $BUFSZはたぶん1024ですよね $file_size は初期化したままなのでずっと0ですね $bufferはアップロードされたファイルの中身ですよね つまり $file_size = length($buffer) でアップロードされたファイルのサイズが出る これだけを見るのならwile文の外でサイズ判定したほうがいいのでは

noname#205944
noname#205944
回答No.4

つまり500以上1000000以下はOKということですよね 視点を変えてエラーメッセージを変えてみては? if($file_size > 500 && $file_size < 1000000) { exitError("ファイルは500バイト以上1メガバイト以下にしてください Size: $file_size"); } これでもダメなら $file_size を取得する部分も教えてくださいな

anzyaa
質問者

補足

>つまり500以上1000000以下はOKということですよね いえ。1.5KBのファイルで2つ目のエラーというのは明らかに上手くいっていないということになります。 一応、ファイル取得からサイズ制限までの部分を抜き出しときます。 $query = new CGI; $id = $query->param('id'); ##$data = $query->param('data'); ## ファイル種類 $filename = $query->param('filename'); # ファイル名の取得 $ostype = $query->param('ostype'); # OSの種類の取得 $ip = $ENV{'REMOTE_ADDR'}; if( $id eq "" || $filename eq "" ){ &exitError("入力された値が間違っているか、または入力されていない項目があります。"); } ## ## $filename からファイル名部分を抽出 ## Windowsに対応 @f = split(/\\/, $filename); $basename = $f[ $#f ]; if( $basename =~ /[\s|,]/ ){ &exitError("ファイル名に空白またはカンマが含まれています。"); } ## 処理ロック &lock; ## 転送先ディレクトリの決定 $dir = "$save_dir/$id"; ## 転送先ディレクトリがなければ作成する。 if( ! -d "$dir" ) { mkdir "$dir", 0777; } # MIMEタイプの取得 $type = $query->uploadInfo($filename)->{'Content-Type'}; while($bytesread = read($filename, $buffer, $BUFSZ)){ $file .= $buffer; $file_size; if ($file_size > 1000000){ exitError("1つめのError! Size : $file_size byte"); } elsif ($file_size < 500) { exitError("2つめのError! Size : $file_size byte"); } else { exitError("OK! Size : $file_size byte"); }

  • Kendai
  • ベストアンサー率45% (36/79)
回答No.3

 またまた#1です。  ちょっと質問を読み違えていたかも知れません。でも、今までの回答で大丈夫です。  エラー表示の時に $file_size の中身(数値)が表示されますので、アップロードしたファイルのサイズと極端に違う場合は、ファイルサイズの取得の仕方を間違ったか、変数をどこかで足したり、かけたりしているかが考えられます。  あと、どのような用途か分かりませんが、500バイト以下でも通してしまっていいような気がします。その代わりに、$file_size == 0 のときにエラーにしてしまっていいような…(^^;)> if ($file_size > 1000000){ exitError("1つめのError! Size : $file_size byte"); } elsif ($file_size < 500) { exitError("2つめのError! Size : $file_size byte"); } else { exitError("OK! Size : $file_size byte"); }

anzyaa
質問者

お礼

やはりこの部分以外に問題があるようですね。 0バイトのファイルは通ります 30バイトくらいのファイルは2つ目のエラー 1.5KBのファイルでも2つ目のエラー おっしゃるとおり、500バイトではなく、0バイトの時のみで問題ありません。知人に頼まれて500バイト以下にしてくれと言われましたが、結局は0バイトがブロックできればいいです。 アップローダーでファイルを参照した後にファイル名を変える人が多く、しかもなぜかアップロードできてしまうという現象が起きます。 でも実際はそんなファイルは存在しませんから、結局は空のファイルがアップロードされます。そのファイルサイズが0バイトなもんで、それをブロックしたいと。 なにせ、5000人規模が使用するアップローダーなもんで、結構、重要だったりするわけです。 そんな重要なCGIを詳しくない私に任されても。という感じなのですが(^^;; 話がそれましたが、ファイルの所得が間違ったりしている可能性があるということなので、それについて。 FORMでのアップローダーでCGIに処理を行わせるものです。 $filename = $query->param('filename'); # ファイル名の取得 これでファイルを所得しています。

  • Kendai
  • ベストアンサー率45% (36/79)
回答No.2

再び#1です。 これでもダメですかね…? if ($file_size > 1000000){ exitError("Error! Size : $file_size byte"); } elsif ($file_size < 500) { exitError("Error! Size : $file_size byte"); } else { exitError("OK! Size : $file_size byte"); }  全体の流れがよく分からないので、デバッグができるようにエラーメッセージを上のようにしてみました。どこがおかしいか分かりやすくなると思います。  ただし、正常な場合でもエラーメッセージが出るようにしています。意図したとおりに動くようになれば、else以降を消して下さい。

anzyaa
質問者

お礼

再びありがとうございます。 コピペしてみましたがダメでした。 0バイトのファイルは普通にアップロードされますし、そのほかのサイズだと全てErrorと表示されてしまいます。 これはやはりこの部分以外の問題なんでしょうか?

  • Kendai
  • ベストアンサー率45% (36/79)
回答No.1

 ご質問を見る限り、$file_size ++;を通るたびに$file_sizeの値が1ずつ増えているので、それをなくせばわざわざ==0をつけなくとも解決しそうです。  あと、ifやelseなどの分岐処理をうまく使いこなすことで、よりスマートに命令文を記述できます。  いろんなサイトで解説されていますので、がんばって探して下さい(^^)

anzyaa
質問者

お礼

返信とアドバイスありがとうございます。 ++を消しましたがダメでした。 あと、新たな問題を発見しまして、500バイト以上のファイルも通さないことに気づきました。 このCGIは書き方間違っているんでしょうか? ご教授お願いします。

関連するQ&A