关键字的参数1的类型必须为散列错误在Perl 5.10上显示,但在Perl 5.16上未显示

izkcnapc  于 2022-11-15  发布在  Perl
关注(0)|答案(2)|浏览(140)

我不断收到以下错误:

关键字的参数1的类型必须是散列(不是散列元素)

在这一行:

my $command = join(" ", @{$jparams{args}})
  . " -cp " . $jparams{cp}
  . " "     . $jparams{class}
  . " "     . join(" ",
     map {
       ${_} . "=" . qq|"$jparams{params}{$_}"|
     } keys $jparams{params}
  );

该错误在Perl 5.10上显示,但在Perl 5.16上没有显示。如何使它在两个版本上都能工作?

tpgth1q7

tpgth1q71#

keys $jparams{params}

应该是

keys %{ $jparams{params} }

您的代码存在代码注入错误。
如果将命令传递给system(或exec),请使用其多参数形式。

my @command = (
   @{ $jparams{ args } },
   -cp => $jparams{ cp },
   $jparams{ class },
   map { "$_=$jparams{ params }{ $_ }" }
      keys %{ $jparams{ params } },
);

system { $command[0] } @command;

这不仅可以解决问题,还可以避免不必要地生成shell。
但是如果出于某种原因确实需要shell命令,那么可以使用String::ShellQuoteshell_quote来解决代码注入错误。

my @command = (
   @{ $jparams{ args } },
   -cp => $jparams{ cp },
   $jparams{ class },
   map { "$_=$jparams{ params }{ $_ }" }
      keys %{ $jparams{ params } },
);

my $command = shell_quote( @command );
9njqaruj

9njqaruj2#

在Perl 5.14之前,您不能传递对keys的引用,但在5.20中成为一个“实验性”警告。
您可以通过取消引用hashref来解决此问题:

keys %{ $jparams{params} }

相关问题