From: Nathan Torkington Date: Thu, 5 Aug 1999 23:01:51 +0000 (-0600) Subject: Protect against pack/unpack repeat count overflows, X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=0638735429cd9f405fe3527971d0275cbbe212d8;p=p5sagit%2Fp5-mst-13.2.git Protect against pack/unpack repeat count overflows, based on: To: Brian Keefer Cc: perl5-porters@perl.org Subject: Re: [ID 19990806.001] Core dump with obfuscated code Message-ID: <14250.27711.769942.100675@localhost.frii.com> p4raw-id: //depot/cfgperl@3928 --- diff --git a/pod/perldiag.pod b/pod/perldiag.pod index 8e686ba..a068427 100644 --- a/pod/perldiag.pod +++ b/pod/perldiag.pod @@ -87,6 +87,16 @@ See L. checksumming process loses information, and you can't go the other way. See L. +=item Repeat count in pack overflows + +(F) You can't specify a repeat count so large that it overflows +your signed integers. See L. + +=item Repeat count in unpack overflows + +(F) You can't specify a repeat count so large that it overflows +your signed integers. See L. + =item /%s/: Unrecognized escape \\%c passed through (W) You used a backslash-character combination which is not recognized diff --git a/pp.c b/pp.c index 8437e5b..a020f54 100644 --- a/pp.c +++ b/pp.c @@ -3350,8 +3350,11 @@ PP(pp_unpack) } else if (isDIGIT(*pat)) { len = *pat++ - '0'; - while (isDIGIT(*pat)) + while (isDIGIT(*pat)) { len = (len * 10) + (*pat++ - '0'); + if (len < 0) + Perl_croak(aTHX_ "Repeat count in unpack overflows"); + } } else len = (datumtype != '@'); @@ -4394,8 +4397,11 @@ PP(pp_pack) } else if (isDIGIT(*pat)) { len = *pat++ - '0'; - while (isDIGIT(*pat)) + while (isDIGIT(*pat)) { len = (len * 10) + (*pat++ - '0'); + if (len < 0) + Perl_croak(aTHX_ "Repeat count in pack overflows"); + } } else len = 1;