Perl pack()和整数溢出

时间:2013-07-18 10:05:43

标签: perl overflow pack

我想用Perl(signed,unsigned,big-endian和little-endian)中的整数溢出检查来打包表达式的各种结果。 如果我尝试:

$ perl -e 'use warnings; print pack("c", 200)' | hexdump -C

我明白了:

Character in 'c' format wrapped in pack at -e line 1.
00000000  c8                                                |.|
00000001

有没有办法检查pack()函数中发生的整数溢出?或者可能强制函数在溢出时失败? 如果我在打包之前检查每种类型的范围(签名1,2,4,8字节,无符号1,2,4,8),代码似乎有点难看。

感谢。

2 个答案:

答案 0 :(得分:4)

您可以启用“打包”警告类别并使其致命。然后溢出会导致可能被捕获的异常。 E.g:

for my $val (127, 128) {
    print "$val -> ";
    if (eval {
        use warnings FATAL => qw(pack);
        pack("c", $val);
    }) {
        print "no overflow";
    } else {
        print "overflow ($@)";
    }
    print "\n";
}

另一种可能性是使用(最好是本地化的)$SIG{__WARN__}处理程序并检查处理程序是否发生了警告。

答案 1 :(得分:0)

致命警告是最简单的解决方案,但您可以编写自己的打包功能。

use Carp         qw( croak );
use Scalar::Util qw( looks_like_number );

sub pack_uint32_be {
   my ($n) = @_;
   croak "Not a number" unless looks_like_number($n);
   croak "Overflow"     unless 0 < $n && $n <= 2**32;
   return pack 'L>', $n;
}

$packed .= pack_uint32_be($x);
$packed .= pack_uint32_be($y);