Subject: | POST_MAX not obeyed for file uploads |
Hiya,
I've been using CGI::Simple, and have run into a critical problem -- it seems $CGI::Simple::POST_MAX is not being obeyed for form/multipart file uploads (I haven't tried regular POSTs, but at a glance, there may be some problems there too).
I've had a quick look under the hood, and it seems the culprit is _parse_multipart() -- it never checks $self->{'.globals'}->{'POST_MAX'}, but instead keeps on appending the read $buffer to $data.
The attached patch takes a stab at fixing this; while I wouldn't consider it a complete solution, at least it's a start.
-Steve
--- /usr/lib/perl5/site_perl/5.6.1/CGI/Simple.pm 2004-06-01 19:20:00.000000000 +0100
+++ /home/spurkis/perl5lib/CGI/Simple.pm 2004-11-16 18:02:15.000000000 +0000
@@ -227,6 +227,13 @@
return;
}
}
+
+ # TODO: this makes no sense --
+ # Shouldn't we really be doing this POST_MAX test above?
+ # Checking POST_MAX here actually means we'll read the whole POST,
+ # even if POST_MAX is set!
+ # -spurkis
+
# we do this test after the read so we strip the data from STDIN
if ( $self->{'.globals'}->{'POST_MAX'} != -1 and $length > $self->{'.globals'}->{'POST_MAX'} ) {
$self->cgi_error( "413 Request entity too large: $length bytes on STDIN exceeds \$POST_MAX!" );
@@ -313,11 +320,28 @@
my $data = '';
my $length = $ENV{'CONTENT_LENGTH'} || 0;
my $CRLF = $self->crlf;
+ my $post_max = $self->{'.globals'}->{POST_MAX};
+
+$post_max = 170;
READ:
while ( $got_data < $length ) {
- last READ unless sysread( STDIN, my $buffer, 4096 );
+ warn "got data: [$got_data]\n";
+ if ( $post_max != -1 and $got_data > $post_max ) {
+ warn( "413 Request entity too large: $length bytes on STDIN exceeds \$POST_MAX($post_max)!\n" );
+ $self->cgi_error( "413 Request entity too large: $length bytes on STDIN exceeds \$POST_MAX($post_max)!" );
+ my $discard_len = $length - $got_data;
+ # silently discard data
+ while ( $discard_len > 0 ) {
+ last unless sysread( STDIN, my $buffer, 4096 );
+ $discard_len -= length( $buffer );
+ }
+ return $got_data;
+ }
+
+ last READ unless sysread( STDIN, my $buffer, 128 );
+
$data .= $buffer;
$got_data += length $buffer;