为什么CGI.pm仍然使用“\ 0”作为空字符,当它被视为Perl中的普通字符时?

时间:2011-09-06 11:09:56

标签: perl

引自in the CGI.pm docs

  

使用它时,你必须注意的是多值CGI   参数。因为哈希不能区分标量和列表   上下文,多值参数将作为打包字符串返回,   由“\ 0”(null)字符分隔。

然而,事实证明,\0在Perl中并不特别:

print length("test\0hi");

输出结果为:

7

而在C中它应该是4

为什么CGI.pm仍然使用\0作为空字符,当它在Perl中被视为普通字符(不再是字符串结尾的标记)时?

2 个答案:

答案 0 :(得分:7)

这是一个设计错误。我认为我们同意它根本不应该将哈希值强制转换为字符串,但它可能在当时看起来是一个好主意,而\0仅仅是由于各种不太重要的原因而最不好的选择。

编辑:人们通常会避免将NUL精确地放入他们的数据中,因为它往往会导致C程序中断,所以这使得这个角色稍微更有利于分隔符。

编辑2 hobbs comments它会回到Perl 4,所以错误不是在原始设计中,而是在执行它然后没有努力去弃用它特征

嗯,后见之明总是很完美。 Hash::MultiValue是您正在考虑的更智能的数据结构。

答案 1 :(得分:2)

这是一项安全功能。

->Vars的用户期望键值的哈希值,其中值是字符串。如果其中一个值恰好是对数组的引用,则会破坏该期望,并且可能导致程序行为异常。

如果要支持具有多个值的参数,请在列表上下文中使用->param。如果需要,您可以使用它来构建自己的哈希值。

my %hash;
for ($cgi->params) {
   $hash{$_} = [ $cgi->param($_) ];
}

我强烈反对这是一个设计错误。我认为这是处理不良数据的非常聪明的方法(参数的多个实例,其中最多只有一个参数)。