Subject: | PATCH: Incorrectly multiple escaped data in list context |
Hi,
This patch fixes an issue causing data to be escaped multiple times
when providing HTML::FillInForm with an array to fill multiple text
fields with the same name.
So for example an array like this:
my @choices = (
{ value => '<1' },
{ value => '<2' },
{ value => '<3' },
);
Passing this to FillInForm, causes the actual values of those fields
named "choice" to be like:
1st. "<1" (OK)
2nd. "&lt;2" (wrong)
3rd. "&amp;lt;3" (wrong)
That problem is fixed in the patch included.
Lets hope that issue gets fixed soon in the upstream.
--
Regards,
Miika Pekkarinen <miika.pekkarinen NOSPAM_AT ihme.org>
Subject: | fillinform.diff |
--- FillInForm.pm.orig 2008-03-14 13:50:51.000000000 +0200
+++ FillInForm.pm 2008-03-14 14:11:38.000000000 +0200
@@ -225,7 +225,6 @@
# force hidden fields to have a value
$value = '' if exists($attr->{'type'}) && $attr->{'type'} eq 'hidden' && ! exists $attr->{'value'} && ! defined $value;
if (defined($value)){
- $value = $self->escapeHTMLStringOrList($value);
# check for input type, noting that default type is text
if (!exists $attr->{'type'} ||
$attr->{'type'} =~ /^(text|textfield|hidden|)$/i){
@@ -233,13 +232,13 @@
$value = shift @$value;
$value = '' unless defined $value;
}
- $attr->{'value'} = $value;
+ $attr->{'value'} = __escapeHTML($value);
} elsif (lc $attr->{'type'} eq 'password' && $self->{fill_password}) {
if ( ref($value) eq 'ARRAY' ) {
$value = shift @$value;
$value = '' unless defined $value;
}
- $attr->{'value'} = $value;
+ $attr->{'value'} = __escapeHTML($value);
} elsif (lc $attr->{'type'} eq 'radio'){
if ( ref($value) eq 'ARRAY' ) {
$value = $value->[0];
@@ -247,7 +246,7 @@
}
# value for radio boxes default to 'on', works with netscape
$attr->{'value'} = 'on' unless exists $attr->{'value'};
- if ($attr->{'value'} eq $value){
+ if ($attr->{'value'} eq __escapeHTML($value)){
$attr->{'checked'} = 'checked';
} else {
delete $attr->{'checked'};
@@ -259,7 +258,7 @@
delete $attr->{'checked'}; # Everything is unchecked to start
$value = [ $value ] unless ref($value) eq 'ARRAY';
foreach my $v ( @$value ) {
- if ( $attr->{'value'} eq $v ) {
+ if ( $attr->{'value'} eq __escapeHTML($v) ) {
$attr->{'checked'} = 'checked';
}
}
@@ -280,7 +279,6 @@
$value = [ $value ] unless ( ref($value) eq 'ARRAY' );
if ( defined $value->[0] ){
- $value = $self->escapeHTMLStringOrList($value);
delete $attr->{selected} if exists $attr->{selected};
if(defined($attr->{'value'})){
@@ -289,14 +287,14 @@
if ($self->{selectMultiple}){
# check if the option tag belongs to a multiple option select
foreach my $v ( grep { defined } @$value ) {
- if ( $attr->{'value'} eq $v ){
+ if ( $attr->{'value'} eq __escapeHTML($v) ){
$attr->{selected} = 'selected';
}
}
} else {
# if not every value of a fdat ARRAY belongs to a different select tag
if (not $self->{selectSelected}){
- if ( $attr->{'value'} eq $value->[0]){
+ if ( $attr->{'value'} eq __escapeHTML($value->[0])){
shift @$value if ref($value) eq 'ARRAY';
$attr->{selected} = 'selected';
$self->{selectSelected} = 1; # remeber that an option tag is selected for this select tag
@@ -306,7 +304,7 @@
} else {
# option tag has no value attr - <OPTION>bar</OPTION>
# save for processing under text handler
- $self->{option_no_value} = $value;
+ $self->{option_no_value} = __escapeHTML($value);
}
}
$self->{output} .= "<$tagname";
@@ -319,12 +317,11 @@
}
} elsif ($tagname eq 'textarea'){
if ($attr->{'name'} and defined (my $value = $self->_get_param($attr->{'name'}))){
- $value = $self->escapeHTMLStringOrList($value);
$value = (shift @$value || '') if ref($value) eq 'ARRAY';
# <textarea> foobar </textarea> -> <textarea> $value </textarea>
# we need to set outputText to 'no' so that 'foobar' won't be printed
$self->{outputText} = 'no';
- $self->{output} .= $origtext . $value;
+ $self->{output} .= $origtext . __escapeHTML($value);
} else {
$self->{output} .= $origtext;
}
@@ -406,21 +403,8 @@
$self->{output} .= $origtext;
}
-sub escapeHTMLStringOrList {
- my ($self, $toencode) = @_;
-
- if (ref($toencode) eq 'ARRAY') {
- foreach my $elem (@$toencode) {
- $elem = $self->escapeHTML($elem);
- }
- return $toencode;
- } else {
- return $self->escapeHTML($toencode);
- }
-}
-
-sub escapeHTML {
- my ($self, $toencode) = @_;
+sub __escapeHTML {
+ my ($toencode) = @_;
return undef unless defined($toencode);
$toencode =~ s/&/&/g;