1
votes

I am using the Perl CGI module. If I have HTML like this

<select multiple name="FILTER_SITE">
  <option>1</option>
  <option>2</option>
</select>

and submit my form I can get something like this in the URL: [..] FILTER_SITE=1&FILTER_SITE=2

Perl's my $FILTER_SITE = $cgi->param('FILTER_SITE'); wil capture only the first instance.

How can I make use of both (in this case)? Hack it and parse the referrer myself and add them to an array is my first idea but it'd be a bit messy, then again I'm hardly versed in CGI.pm or Perl.

With Data::Dumper, interestingly

print "<pre>".Dumper($cgi->param('FILTER_SITE')) . "</pre>";

$VAR1 = '1';
$VAR2 = '2';
3
Is optrion a typo? Try: use Data::Dumper; print Dumper $cgi->param('FILTER_SITE');TLP
This isn't something that's hidden in the docs.brian d foy
Indeed, the wonders of rapid development..Recct

3 Answers

7
votes

NOTE: Current documentation (as of 2020 May 29) says this method could cause a security vulnerability. Please check my answer below.

The param method supplies a single value in scalar context and (potentially) multiple values in list context. Read about it here.

So if you change your code to, for example

my @FILTER_SITE   = $cgi->param('FILTER_SITE');

then the array will contain all selected values of the option.

If it suits your code better, you can also write

for my $FILTER_SITE ($cgi->param('FILTER_SITE')) {
  :
}
2
votes

I know this is an old post, but looks like few things changed since this question was answered. I want to post the latest info on this, especially because the accepted answer is now considered a security vulnerability. CGI.pm documentation says

{Warning - calling param() in list context can lead to vulnerabilities if you do not sanitise user input as it is possible to inject other param keys and values into your code. This is why the multi_param() method exists, to make it clear that a list is being returned, note that param() can still be called in list context and will return a list for back compatibility.}

It is recommended to use $cgi->multi_param method instead.

0
votes

Example of parsing values

    #!/usr/bin/perl

    use Encode;

    print "Content-Type: text/html; charset=UTF-8\n\n";

    if($ENV{'REQUEST_METHOD'} eq "POST") {
      read(STDIN, $querystring, $ENV{'CONTENT_LENGTH'});
     print "<h1>POST</h1>";
    } else {
      print "<h1>GET</h1>";
      $type = "display_form";
      $querystring = $ENV{'QUERY_STRING'};
    }

    print "<p>$querystring</p>";

    if (length ($querystring) > 0){
      @pairs = split(/&/, $querystring);
      foreach $pair (@pairs){
           ($name, $value) = split(/=/, $pair);
           $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
           $name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
           if (exists $in{$name}) {
             $value = "$value,$in{$name}";
           }
           $in{$name} = $value;
      }
    }

   foreach my $val (sort keys %in) {
     print "<p>$val: $in{$val}</p>";
   }