Subject: | DFV::Constraints::Upload processes input data, not filtered data |
In Bug #22589 I added support for a new "get_filtered_data()" method,
which allowed for constraints that operated on multiple fields to be
able to access the -filtered- versions of other data fields.
I missed DFV::Constraints::Upload, though, and it was still processing
the original -input- data instead of the -filtered- data.
This causes problems if you have an upload field that is both
filtered+constrained, and for which the constraint expects that the
filter has already been applied. The use case that I've run into that
uncovered this was attempting to use
DFV::Filters::Image::image_filter() (to restrict the resolution of
uploaded images) and DFV::Constraints::Upload::file_max_bytes() (to
restrict uploaded file size) at the same time. What I was expecting
to see was that "image_filter" would filter and resize the image
first, and then the resulting image would then be checked for max
bytes using "file_max_bytes". However.... what I ended up with was
that "file_max_bytes" would constrain against the original uploaded
image, not the filtered/resized version (which may have been shrunk
down far enough to be of acceptable size).
I've attached a diff against DFV::Constraints::Upload from DFV v4.50,
which updates it to use "get_filtered_data()" wherever possible. Test
suites in DFV v4.50 all pass, although I will admit that I have -not-
checked this patch against uploads when using Apache::Request or
CGI::Simple.
Subject: | dfv-upload-filtered-data.patch |
Only in Data-FormValidator-4.50/: .Changes.swp
diff -ru Data-FormValidator-4.50.orig/lib/Data/FormValidator/Constraints/Upload.pm Data-FormValidator-4.50/lib/Data/FormValidator/Constraints/Upload.pm
--- Data-FormValidator-4.50.orig/lib/Data/FormValidator/Constraints/Upload.pm 2006-12-04 18:38:14.000000000 -0800
+++ Data-FormValidator-4.50/lib/Data/FormValidator/Constraints/Upload.pm 2007-01-31 12:58:13.741041627 -0800
@@ -79,10 +79,7 @@
# are no additional arguments";
# }
- my $q = $self->get_input_data;
-
- $q->can('param') ||
- die 'file_format: data object missing param() method';
+ my $q = $self->get_filtered_data;
my $field = $self->get_current_constraint_field;
my $fh = _get_upload_fh($self);
@@ -121,7 +118,7 @@
my @mt_exts = $t ? $t->extensions : ();
## setup filename to retrieve extension
- my $fn = $q->param($field);
+ my $fn = $q->{$field};
my ($uploaded_ext) = ($fn =~ m/\.([\w\d]*)?$/);
my $ext;
@@ -160,7 +157,7 @@
($max_width > 0) || die 'image_max_dimensions: maximum width must be > 0';
($max_height > 0) || die 'image_max_dimensions: maximum height must be > 0';
- my $q = $self->get_input_data;
+ my $q = $self->get_filtered_data;
my $field = $self->get_current_constraint_field;
my ($width,$height) = _get_img_size($self);
@@ -193,9 +190,7 @@
$max_bytes = 1024*1024; # default to 1 Meg
}
- my $q = $self->get_input_data;
- $q->can('param') ||
- die 'file_max_bytes: object missing param() method';
+ my $q = $self->get_filtered_data;
my $field = $self->get_current_constraint_field;
@@ -229,7 +224,7 @@
($min_width > 0) || die 'image_min_dimensions: minimum width must be > 0';
($min_height > 0) || die 'image_min_dimensions: minimum height must be > 0';
- my $q = $self->get_input_data;
+ my $q = $self->get_filtered_data;
my $field = $self->get_current_constraint_field;
my ($width, $height) = _get_img_size($self);
@@ -249,16 +244,13 @@
sub _get_img_size
{
my $self = shift;
- my $q = $self->get_input_data;
+ my $q = $self->get_filtered_data;
## setup caller to make can errors more useful
my $caller = (caller(1))[3];
my $pkg = __PACKAGE__ . "::";
$caller =~ s/$pkg//g;
- $q->can('param') || die "$caller: data object missing param() method";
- $q->can('upload') || die "$caller: data object missing upload() method";
-
my $field = $self->get_current_constraint_field;
## retrieve filehandle from query object.
@@ -286,9 +278,16 @@
sub _get_upload_fh
{
my $self = shift;
- my $q = $self->get_input_data;
+ my $q = $self->get_filtered_data;
my $field = $self->get_current_constraint_field;
+ ## Hash
+ if (ref($q) eq 'HASH') {
+ my $fh = $q->{$field};
+ ## convert into seekable handle
+ return IO::File->new_from_fd(fileno($fh), "r");
+ }
+
## CGI::Simple object processing (slightly different from others)
if ($q->isa('CGI::Simple')) {
## get filename
@@ -338,6 +337,8 @@
}
## returns mime type if included as part of the send
+##
+## NOTE: retrieves from original uploaded, -UNFILTERED- data
sub _get_upload_mime_type
{
my $self = shift;
@@ -436,6 +437,11 @@
give up. The extension we return is based on the MIME type we found, rather
than trusting the one that was uploaded.
+B<NOTE:> if we have to fall back to using the MIME type provided by the
+browser, we access it from the original I<input> data and not the
+I<filtered> data. This should only cause issue when you have used a filter
+to alter the type of file that was uploaded (e.g. image conversion).
+
=item file_max_bytes
This function checks the maximum size of an uploaded file. By default,