我怎样才能在perl中使用unescape / urldecode查询URL查询变量?

时间:2013-02-05 04:43:08

标签: perl escaping cgi

我有一个处理URL的perl脚本 - 它在服务器升级之前工作正常。现在它似乎是对它返回的URL字符串进行双重编码。

以下是脚本用于返回的URL的示例:

https://processor.com/?&streetOne=johndoe%40test%2Ecom&key=1234

以下是现在返回的内容

https://processor.com/?&email=johndoe%2540test%252Ecom&key=1234

它们的主要区别在于,网址中的@过去被正确编码为%40,但现在百分号正在编码(双重编码),因此它是%2540如果您对@进行编码然后再对其进行编码会发生什么。

我不确定服务器上会发生什么变化导致此行为。我是一个PHP家伙,它让我想起了“魔术引号”,它会在脚本处理之前自动转义所有查询变量。

我没有对此服务器的root访问权限,因此如果无法使用.htaccess文件或某些本地配置选项(在perl脚本中?)进行更改,那么我可能需要更改这个函数发生了什么,它获取了所请求的每个URL值:

首先,脚本读取查询变量

(我认为这就是问题所在 - 我不理解正则表达式 - 关于在空格和$obj->{'key'};部分正在做什么之间寻找KEY的事情)

sub getValue
{
  my $obj = shift;
  my $name = shift;

  if ($name =~ /^\s*KEY\s*$/i)
    {
      return $obj->{'key'};
    }

  if (! $obj->isValid($name))
    {
      $obj->addError("Cannot obtain information for field '$name' since field is invalid");
      return 0;
    }

  if (! $obj->isAssigned($name))
    {
      $obj->addError("Cannot obtain value from field '$name' since field has not be assigned a value.");
      return 0;
    }

  return $obj->{'parameters'}->{ $name }->{ 'value'};
}

然后脚本将查询变量构建回URL以返回:

脚本的另一部分构建了它返回的URL - 但我不认为这是罪魁祸首。我尝试从CGI::escape部分删除CGI::escape($value)),但没有帮助。

sub create_results
{
  my $obj = shift;

  my ($seconds, $microseconds) = gettimeofday();
  my $timestamp = int($seconds*1000 + $microseconds/1000);

  $obj->assign('timestamp',$timestamp);

  # create query string and hash data

  my $hash_data = '';

  my @query_string = qw();

  foreach my $name (@{ $obj->{'parameter_order'} })
    {
      my $node = $obj->{'parameters'}->{ $name };

      if (defined($node->{'value'}))
        {
          my $value = $node->{'value'};
          $hash_data .= $value;

          # $query->param(-name=>"$name",   -value=>"$value");
          push(@query_string,$name . "=" . CGI::escape($value));
        }
    }

  # Hash
  $hash_data .= $obj->get('key');
  my $hash_digest = md5_hex( $hash_data );

  push(@query_string, "hash=$hash_digest");

  $obj->{'query_string'} = join("&",@query_string);
  $obj->{'hash_digest'} = $hash_digest; 
}

该脚本是我正在使用的perl包。我没有写。我在这里发布了完整的脚本:http://pastebin.com/eZr8rQ0t

1 个答案:

答案 0 :(得分:1)

使用CGI模块有点过时,CGI::escapeCGI::Util内部未记录的内部函数,仅适用于CGI内部 。有一个相应的unescape函数可用,但这不是正确的事情

为了缩短追逐时间,使用某处CGI::Util::unescape($dirty_value)应该可以正常工作,因为该模块应由CGI加载。也许是return来自getValue,但我很累,找到了正确的地方。这种双重编码看起来像是设计错误,或者假设您提供的示例网址已经被转义,并且脚本使用错误。

我打赌错误的设计;考虑到有人认为这很有趣

"foo" => { "parameterName" => "foo" },
... # snip like 50 other values
"quux" => { "parameterName" => "quux" },

以及map { $_ => {parameterName => $_} } qw/foo ... qux/可能只需输入一小部分的其他愚蠢......

提示https://metacpan.org/提供了所有(公共)Perl模块(包括源代码)的文档。