diff options
author | Jim Meyering <jim@meyering.net> | 2011-10-23 16:04:11 -0700 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2011-10-23 16:47:53 -0700 |
commit | 26e1303d691c34af15e9332d5ba72c53be9a4263 (patch) | |
tree | f9b7b6f5126aafffea8ce96c17cf5f7ac3938d6b | |
parent | dd8fc02804485f0ffdfd876c119b4f9500c7be86 (diff) | |
download | perl-26e1303d691c34af15e9332d5ba72c53be9a4263.tar.gz |
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"
-rw-r--r-- | embed.fnc | 2 | ||||
-rw-r--r-- | proto.h | 2 | ||||
-rw-r--r-- | util.c | 8 |
3 files changed, 6 insertions, 6 deletions
@@ -1066,7 +1066,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 @@ -3244,7 +3244,7 @@ PERL_CALLCONV void Perl_regprop(pTHX_ const regexp *prog, SV* sv, const regnode* #define PERL_ARGS_ASSERT_REGPROP \ assert(sv); assert(o) -PERL_CALLCONV void Perl_repeatcpy(char* to, const char* from, I32 len, I32 count) +PERL_CALLCONV void Perl_repeatcpy(char* to, const char* from, I32 len, IV count) __attribute__nonnull__(1) __attribute__nonnull__(2); #define PERL_ARGS_ASSERT_REPEATCPY \ @@ -3404,7 +3404,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; @@ -3412,19 +3412,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; |