diff --git a/Changes b/Changes index 1477a1a..c01c485 100644 --- a/Changes +++ b/Changes @@ -1,3 +1,8 @@ +4.52 2021-05-04 + + [ FIX ] + - sort hash keys for deterministic behaviour (GH #245, GH #246) + 4.51 2020-10-01 [ DOCUMENTATION ] diff --git a/lib/CGI.pm b/lib/CGI.pm index b4bd32d..11ace05 100644 --- a/lib/CGI.pm +++ b/lib/CGI.pm @@ -7,7 +7,7 @@ use strict; use warnings; #/; -$CGI::VERSION='4.51'; +$CGI::VERSION='4.52'; use CGI::Util qw(rearrange rearrange_header make_attributes unescape escape expires ebcdic2ascii ascii2ebcdic); @@ -286,7 +286,7 @@ sub import { # To allow overriding, search through the packages # Till we find one in which the correct subroutine is defined. my @packages = ($self,@{"$self\:\:ISA"}); - for $sym (keys %EXPORT) { + for $sym (sort keys %EXPORT) { my $pck; my $def = $DefaultClass; for $pck (@packages) { @@ -609,7 +609,7 @@ sub init { last METHOD; } if (ref($initializer) && ref($initializer) eq 'HASH') { - for (keys %$initializer) { + for (sort keys %$initializer) { $self->param('-name'=>$_,'-value'=>$initializer->{$_}); } last METHOD; @@ -1155,7 +1155,7 @@ sub import_names { die "Can't import names into \"main\"\n" if \%{"${namespace}::"} == \%::; if ($delete || $MOD_PERL || exists $ENV{'FCGI_ROLE'}) { # can anyone find an easier way to do this? - for (keys %{"${namespace}::"}) { + for (sort keys %{"${namespace}::"}) { local *symbol = "${namespace}::${_}"; undef $symbol; undef @symbol; @@ -1428,7 +1428,7 @@ sub save { if length($escaped_param) or length($value); } } - for (keys %{$self->{'.fieldnames'}}) { + for (sort keys %{$self->{'.fieldnames'}}) { print $filehandle ".cgifields=",escape("$_"),"\n"; } print $filehandle "=\n"; # end of record @@ -2456,7 +2456,7 @@ sub popup_menu { if (/{'.fieldnames'}}) { + for (sort keys %{$self->{'.fieldnames'}}) { push(@pairs,".cgifields=".escape("$_")); } return join($USE_PARAM_SEMICOLONS ? ';' : '&',@pairs); @@ -2991,7 +2991,7 @@ sub Accept { return $prefs{$search} if $prefs{$search}; # Didn't get it, so try pattern matching. - for (keys %prefs) { + for (sort keys %prefs) { next unless /\*/; # not a pattern match ($pat = $_) =~ s/([^\w*])/\\$1/g; # escape meta characters $pat =~ s/\*/.*/g; # turn it into a pattern @@ -3144,7 +3144,7 @@ sub http { } return $ENV{"HTTP_$parameter"}; } - return grep { /^HTTP(?:_|$)/ } keys %ENV; + return grep { /^HTTP(?:_|$)/ } sort keys %ENV; } #### Method: https @@ -3162,7 +3162,7 @@ sub https { return $ENV{"HTTPS_$parameter"}; } return wantarray - ? grep { /^HTTPS(?:_|$)/ } keys %ENV + ? grep { /^HTTPS(?:_|$)/ } sort keys %ENV : $ENV{'HTTPS'}; } @@ -3293,7 +3293,7 @@ sub register_parameter { sub get_fields { my($self) = @_; return $self->CGI::hidden('-name'=>'.cgifields', - '-values'=>[keys %{$self->{'.parametersToAdd'}}], + '-values'=>[sort keys %{$self->{'.parametersToAdd'}}], '-override'=>1); } @@ -3415,7 +3415,7 @@ sub read_multipart { # together with the body for later parsing with an external # MIME parser module if ( $multipart ) { - for ( keys %header ) { + for ( sort keys %header ) { print $filehandle "$_: $header{$_}${CRLF}"; } print $filehandle "${CRLF}"; @@ -3624,7 +3624,7 @@ sub _set_values_and_labels { $$l = $v if ref($v) eq 'HASH' && !ref($$l); return $self->param($n) if !defined($v); return $v if !ref($v); - return ref($v) eq 'HASH' ? keys %$v : @$v; + return ref($v) eq 'HASH' ? sort keys %$v : @$v; } # internal routine, don't use @@ -3633,7 +3633,7 @@ sub _set_attributes { my($element, $attributes) = @_; return '' unless defined($attributes->{$element}); $attribs = ' '; - for my $attrib (keys %{$attributes->{$element}}) { + for my $attrib (sort keys %{$attributes->{$element}}) { (my $clean_attrib = $attrib) =~ s/^-//; $attribs .= "@{[lc($clean_attrib)]}=\"$attributes->{$element}{$attrib}\" "; } diff --git a/lib/CGI/Carp.pm b/lib/CGI/Carp.pm index 66ed8c4..249f345 100644 --- a/lib/CGI/Carp.pm +++ b/lib/CGI/Carp.pm @@ -326,7 +326,7 @@ use File::Spec; $main::SIG{__WARN__}=\&CGI::Carp::warn; -$CGI::Carp::VERSION = '4.51'; +$CGI::Carp::VERSION = '4.52'; $CGI::Carp::CUSTOM_MSG = undef; $CGI::Carp::DIE_HANDLER = undef; $CGI::Carp::TO_BROWSER = 1; diff --git a/lib/CGI/Cookie.pm b/lib/CGI/Cookie.pm index 6c794cc..5ae12b2 100644 --- a/lib/CGI/Cookie.pm +++ b/lib/CGI/Cookie.pm @@ -3,7 +3,7 @@ package CGI::Cookie; use strict; use warnings; -our $VERSION='4.51'; +our $VERSION='4.52'; use CGI::Util qw(rearrange unescape escape); use overload '""' => \&as_string, 'cmp' => \&compare, 'fallback' => 1; diff --git a/lib/CGI/File/Temp.pm b/lib/CGI/File/Temp.pm index 4c24d79..218e260 100644 --- a/lib/CGI/File/Temp.pm +++ b/lib/CGI/File/Temp.pm @@ -3,7 +3,7 @@ # you use it directly and your code breaks horribly. package CGI::File::Temp; -$CGI::File::Temp::VERSION = '4.51'; +$CGI::File::Temp::VERSION = '4.52'; use parent File::Temp; use parent Fh; diff --git a/lib/CGI/Pretty.pm b/lib/CGI/Pretty.pm index 06b6b4c..9372f30 100644 --- a/lib/CGI/Pretty.pm +++ b/lib/CGI/Pretty.pm @@ -5,7 +5,7 @@ use warnings; use CGI (); -$CGI::Pretty::VERSION = '4.51'; +$CGI::Pretty::VERSION = '4.52'; $CGI::DefaultClass = __PACKAGE__; @CGI::Pretty::ISA = qw( CGI ); diff --git a/lib/CGI/Push.pm b/lib/CGI/Push.pm index 12d45c3..6297f55 100644 --- a/lib/CGI/Push.pm +++ b/lib/CGI/Push.pm @@ -5,7 +5,7 @@ use strict; use warnings; #/; -$CGI::Push::VERSION='4.51'; +$CGI::Push::VERSION='4.52'; use CGI; use CGI::Util 'rearrange'; @ISA = ('CGI'); diff --git a/lib/CGI/Util.pm b/lib/CGI/Util.pm index 7856555..d32595a 100644 --- a/lib/CGI/Util.pm +++ b/lib/CGI/Util.pm @@ -5,7 +5,7 @@ use strict; our @EXPORT_OK = qw(rearrange rearrange_header make_attributes unescape escape expires ebcdic2ascii ascii2ebcdic); -our $VERSION = '4.51'; +our $VERSION = '4.52'; our $_EBCDIC = "\t" ne "\011"; diff --git a/lib/Fh.pm b/lib/Fh.pm index 68d2bed..a7baab7 100644 --- a/lib/Fh.pm +++ b/lib/Fh.pm @@ -5,6 +5,6 @@ package Fh; use strict; use warnings; -$Fh::VERSION = '4.51'; +$Fh::VERSION = '4.52'; 1;