键的 arg 1 类型必须是散列错误显示在 Perl 5.10 但不是 Perl 5.16

Type of arg 1 to keys must be hash error shows on Perl 5.10 but not Perl 5.16

我不断收到以下错误:

键的 arg 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。我如何让它在两个版本中工作?

您无法传递对 keys 的引用,直到 Perl 5.14, but became an "experimental" warning in 5.20

您可以通过取消引用 hashref 来解决这个问题:

keys %{ $jparams{params} }
keys $jparams{params}

应该是

keys %{ $jparams{params} }

您的代码存在代码注入错误。

如果命令传递给 system(或 exec),请使用其 multi-argument 形式。

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 );