【问题标题】:How to verify form in perl CGI?如何在 perl CGI 中验证表单?
【发布时间】:2016-11-05 15:32:15
【问题描述】:

我正在创建一个 CGI perl 脚本,用户可以在其中输入名字、姓氏和电话号码。然后,我使用一些正则表达式检查他们输入的数据,以确保数据格式正确,例如:电话是数字而不是字母。

问题是当我从浏览器执行我的脚本时,我得到了表单,但是当我输入不正确的格式时,我没有得到错误。我已经尝试更改我的脚本,但我没有更正这个问题。 这是我的脚本:

    #!/usr/bin/perl -w

use strict; #options

my %errors;
my %form;

my %fields = (
                "lname" => "Last Name",
                "phone" => "Phone Number",
                "fname" => "First Name"
             );

my %patterns = (
        "fname" => '[A-Z][a-z]{2,50}',
        "phone" => '[\d{3}-\d{3}-\d{4}',
        "lname" => '[A-Z][A-Za-z]{2,60}'
                );


#sequence that form fields are printed/processed
my @formSequence = ("fname", "lname", "phone");

print "Content-Type: text/html;charset=ISO-8859-1\n\n";

&startxhtml;

if ($ENV{REQUEST_METHOD} eq "GET") {
        &printform;
        exit;
}
else {
        &readformdata;
    if (&checkrequiredfields) {
        print "Form Data validated successfully!";
        exit;   
    }
    else {
        &checkrequiredfields;
        &printform;
    }
}


=for
if($ENV{REQUEST_METHOD} eq "POST")
        {
        &readformdata();
    #&printformdata;
                if(&checkrequiredfields)
                {
                print "Form data validated successfully";
                }
        else
                {
                &printform();
                }
}
=cut
print qq~</body></html>\n~;


sub checkrequiredfields
{
        my $success = 1;
        foreach(keys (%fields))
        {
                if($form{$_} !~ $patterns{$_})
                {
                        $errors{$_} = "Error: $fields{$_} is missing or incorrect format\n";
                        $success = 0;
                }
        }
        return $success;
}

sub printform
{
    print qq~<html>
         <head>
         <title>Taint Checking</title>
         </head>
         <body>
         <form action="/new-cgi/file5.cgi" method="POST">
         <center>
         <h2>Student Survery</h2>
         Last Name:<input type=text name=lname value=$form{lname}>
         <br>
         $errors{lname}
         First Name:<input type=text name=fname value=$form{fname}>
                 <br>
         $errors{fname}
         Phone Number:<input type=text name=phone value=$form{phone}>
                 <br>
         $errors{phone}
         <input type=submit value="Insert" name=Insert>
         </form>
         </center>
         </body>
         </html>
         ~;


}

sub startxhtml
{
print qq~
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head><title>Taint checking</title>
<body>
~;
}

sub readformdata
{
        #Read and decode form data
        my $input = <>;
        my @pairs = split(/&/, $input);
        my ($name, $value);
        foreach(@pairs)
                {
                ($name, $value) = split(/=/, $_);
                $value =~ tr/+/ /;
                $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
                $form{$name} = $value;
                }
}

当我从浏览器访问此脚本时,我会收到表单,但如果我输入错误的格式,我不会收到警告。

有人可以建议我做错了什么。谢谢

【问题讨论】:

  • 您是否尝试在您的%pattens 声明中使用qr/.../ 包装您的正则表达式字符串?
  • 此外,不再需要在子例程调用前加上&amp;,即您可以只使用checkrequiredfields; 而不是&amp;checkrequiredfields;
  • 此代码looks rather familiar。在深入了解它之前,您可以查看some of the issues I pointed out with it yesterday
  • 至少,至少,use CGI。不要手动操作。

标签: perl cgi


【解决方案1】:

当我输入错误的格式时,我没有收到错误

您在哪里查找错误?您的代码中有错误,因此我认为您会在 Web 服务器错误日志中收到错误消息。错误出现在用于检查phone 参数有效性的正则表达式中:

my %patterns = (
        "fname" => '[A-Z][a-z]{2,50}',
        "phone" => '[\d{3}-\d{3}-\d{4}',
        "lname" => '[A-Z][A-Za-z]{2,60}'
                );

phone 正则表达式的开头有一个额外的[。如果您删除它,那么我认为您的代码将按预期工作。

但是,正如I said yesterday,这段代码展示了一些相当古老的编码实践。我不确定你从哪里得到这段代码,但我会敦促你研究一些更现代的 Perl 编码资源。我已经在下面稍微清理了您的代码,但还有很多可以改进的地方。

#!/usr/bin/perl

use strict;
# Use warnings rather than "-w" on the shebang
use warnings;

# Use the module that helps us write CGI programs
use CGI qw[:cgi];

my %errors;

my %fields = (
  # No need to quote the LHS of =>
  lname => 'Last Name',
  phone => 'Phone Number',
  fname => 'First Name',  # Perl tip: Always add optional comma at end of list
);

my %patterns = (
  fname => '[A-Z][a-z]{2,50}',
  phone => '\d{3}-\d{3}-\d{4}',
  lname => '[A-Z][A-Za-z]{2,60}',
);


#sequence that form fields are printed/processed
# Less punctuation using qw(...)
my @formSequence = qw(fname lname phone);

# Use the header function to print a header
print header(-charset => 'ISO-8859-1');

# No ampersands on function calls (but parenthesese look nice)
startxhtml();

if (request_method eq 'GET') {
  printform();
  exit;
}

# exit() above means we don't need the else block

# Declare variables where they are used.
my %form = readformdata();

# Inverted to logic here as checkrequiredfields() returns true (a hash of errors)
# for invalid fields
if (my %errors = checkrequiredfields(%form)) {
  # Slightly weird logic here. If checkrequiredfields() ... else checkrequiredfields() ?
  checkrequiredfields();
  printform(%errors);
} else {
  print "Form Data validated successfully!";
  exit;
}


# Don't use raw HTML. Use the Template Toolkit (or some other templating system)
print qq~</body></html>\n~;


sub checkrequiredfields {
  my %form = @_;

  my %errors;

  my $success = 1;
  foreach (keys %fields) {
    if($form{$_} !~ $patterns{$_}) {
      $errors{$_} = "Error: $fields{$_} is missing or incorrect format\n";
      $success = 0;
    }
  }
  return %errors;
}

# Please use a templating engine!
sub printform {
  # Get rid of "uninitialised value" warnings
  my %errors = (
    fname => '',
    lname => '',
    phone => '',
  );

  %errors = (%errors, @_) if @_;

  print qq~<html>
         <head>
         <title>Taint Checking</title>
         </head>
         <body>
         <form action="/new-cgi/file5.cgi" method="POST">
         <center>
         <h2>Student Survery</h2>
         Last Name:<input type=text name=lname value=$form{lname}>
         <br>
         $errors{lname}
         First Name:<input type=text name=fname value=$form{fname}>
                 <br>
         $errors{fname}
         Phone Number:<input type=text name=phone value=$form{phone}>
                 <br>
         $errors{phone}
         <input type=submit value="Insert" name=Insert>
         </form>
         </center>
         </body>
         </html>
         ~;
}

# Please use a templating system
sub startxhtml {
  print qq~
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head><title>Taint checking</title>
<body>
~;
}

# Using the param() function from CGI.pm makes this a lot easier.
sub readformdata {
  my %form;
  my @params = qw[fname lname phone];

  foreach (@params) {
    $form{$_} = param($_);
  }

  return %form;
}

【讨论】:

    猜你喜欢
    • 2013-03-25
    • 2012-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-26
    • 1970-01-01
    • 2013-09-13
    • 2015-01-03
    相关资源
    最近更新 更多