Skip to content

Commit 26e1303

Browse files
meyeringFather Chrysostomos
authored andcommitted
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"
1 parent dd8fc02 commit 26e1303

File tree

3 files changed

+6
-6
lines changed

3 files changed

+6
-6
lines changed

embed.fnc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1066,7 +1066,7 @@ EXp |SV*|reg_qr_package|NN REGEXP * const rx
10661066

10671067
: FIXME - why the E?
10681068
Ep |void |regprop |NULLOK const regexp *prog|NN SV* sv|NN const regnode* o
1069-
Anp |void |repeatcpy |NN char* to|NN const char* from|I32 len|I32 count
1069+
Anp |void |repeatcpy |NN char* to|NN const char* from|I32 len|IV count
10701070
AnpP |char* |rninstr |NN const char* big|NN const char* bigend \
10711071
|NN const char* little|NN const char* lend
10721072
Ap |Sighandler_t|rsignal |int i|Sighandler_t t

proto.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3244,7 +3244,7 @@ PERL_CALLCONV void Perl_regprop(pTHX_ const regexp *prog, SV* sv, const regnode*
32443244
#define PERL_ARGS_ASSERT_REGPROP \
32453245
assert(sv); assert(o)
32463246

3247-
PERL_CALLCONV void Perl_repeatcpy(char* to, const char* from, I32 len, I32 count)
3247+
PERL_CALLCONV void Perl_repeatcpy(char* to, const char* from, I32 len, IV count)
32483248
__attribute__nonnull__(1)
32493249
__attribute__nonnull__(2);
32503250
#define PERL_ARGS_ASSERT_REPEATCPY \

util.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3404,27 +3404,27 @@ Perl_my_pclose(pTHX_ PerlIO *ptr)
34043404

34053405
#define PERL_REPEATCPY_LINEAR 4
34063406
void
3407-
Perl_repeatcpy(register char *to, register const char *from, I32 len, register I32 count)
3407+
Perl_repeatcpy(register char *to, register const char *from, I32 len, register IV count)
34083408
{
34093409
PERL_ARGS_ASSERT_REPEATCPY;
34103410

34113411
if (len == 1)
34123412
memset(to, *from, count);
34133413
else if (count) {
34143414
register char *p = to;
3415-
I32 items, linear, half;
3415+
IV items, linear, half;
34163416

34173417
linear = count < PERL_REPEATCPY_LINEAR ? count : PERL_REPEATCPY_LINEAR;
34183418
for (items = 0; items < linear; ++items) {
34193419
register const char *q = from;
3420-
I32 todo;
3420+
IV todo;
34213421
for (todo = len; todo > 0; todo--)
34223422
*p++ = *q++;
34233423
}
34243424

34253425
half = count / 2;
34263426
while (items <= half) {
3427-
I32 size = items * len;
3427+
IV size = items * len;
34283428
memcpy(p, to, size);
34293429
p += size;
34303430
items *= 2;

0 commit comments

Comments
 (0)