summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Meyering <jim@meyering.net>2011-10-23 16:04:11 -0700
committerFather Chrysostomos <sprout@cpan.org>2011-10-23 16:47:53 -0700
commit26e1303d691c34af15e9332d5ba72c53be9a4263 (patch)
treef9b7b6f5126aafffea8ce96c17cf5f7ac3938d6b
parentdd8fc02804485f0ffdfd876c119b4f9500c7be86 (diff)
downloadperl-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.fnc2
-rw-r--r--proto.h2
-rw-r--r--util.c8
3 files changed, 6 insertions, 6 deletions
diff --git a/embed.fnc b/embed.fnc
index 43ad88b418..3a47a30447 100644
--- a/embed.fnc
+++ b/embed.fnc
@@ -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
diff --git a/proto.h b/proto.h
index 0eb5e7cf58..a70802bb17 100644
--- a/proto.h
+++ b/proto.h
@@ -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 \
diff --git a/util.c b/util.c
index 1df54538c9..164d9717b4 100644
--- a/util.c
+++ b/util.c
@@ -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;