From 647b6565b7d935eb9b92e057d0c7ae5fe54726e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= Date: Thu, 6 Oct 2011 16:35:49 +0200 Subject: [PATCH] Don't segfault given string repeat count larger than 2^31 E.g., this overflows INT_MAX and overruns heap memory: $ perl -le 'print "v"x(2**31+1)' [Exit 139 (SEGV)] (Perl_repeatcpy): Use the same type for "count" as our sole callers in pp.c: IV (long), not I32 (int). Otherwise, passing the wider value to a narrower "I32 count" http://thread.gmane.org/gmane.comp.lang.perl.perl5.porters/96812 https://rt.perl.org/rt3/Ticket/Display.html?id=94560 Original author: Jim Meyering Petr Pisar: Modify embed.fnc instead of generated proto.h --- embed.fnc | 2 +- util.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/embed.fnc b/embed.fnc index bce167e..8c86a3e 100644 --- a/embed.fnc +++ b/embed.fnc @@ -1032,7 +1032,7 @@ EXp |SV*|reg_qr_package|NN REGEXP * const rx : FIXME - why the E? Ep |void |regprop |NULLOK const regexp *prog|NN SV* sv|NN const regnode* o -Anp |void |repeatcpy |NN char* to|NN const char* from|I32 len|I32 count +Anp |void |repeatcpy |NN char* to|NN const char* from|I32 len|IV count AnpP |char* |rninstr |NN const char* big|NN const char* bigend \ |NN const char* little|NN const char* lend Ap |Sighandler_t|rsignal |int i|Sighandler_t t diff --git a/util.c b/util.c index 0ea39c6..3d4dcc7 100644 --- a/util.c +++ b/util.c @@ -3315,7 +3315,7 @@ Perl_my_pclose(pTHX_ PerlIO *ptr) #define PERL_REPEATCPY_LINEAR 4 void -Perl_repeatcpy(register char *to, register const char *from, I32 len, register I32 count) +Perl_repeatcpy(register char *to, register const char *from, I32 len, register IV count) { PERL_ARGS_ASSERT_REPEATCPY; @@ -3323,19 +3323,19 @@ Perl_repeatcpy(register char *to, register const char *from, I32 len, register I memset(to, *from, count); else if (count) { register char *p = to; - I32 items, linear, half; + IV items, linear, half; linear = count < PERL_REPEATCPY_LINEAR ? count : PERL_REPEATCPY_LINEAR; for (items = 0; items < linear; ++items) { register const char *q = from; - I32 todo; + IV todo; for (todo = len; todo > 0; todo--) *p++ = *q++; } half = count / 2; while (items <= half) { - I32 size = items * len; + IV size = items * len; memcpy(p, to, size); p += size; items *= 2; -- 1.7.6.4