summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Mitchell <davem@iabyn.com>2017-03-15 09:25:51 +0000
committerDavid Mitchell <davem@iabyn.com>2017-03-15 09:25:51 +0000
commit95d8e32b92e4e78f0c172dd82ff70a8a96bb1451 (patch)
tree29bcb3e79f81cb7fcb9bc02ff828c860f950eca7
parentc61597183215b0dad8f01e5b9d60419ce3768b41 (diff)
parenta7dd840b16566dcdb761159060e3f05d9ed57073 (diff)
downloadperl-95d8e32b92e4e78f0c172dd82ff70a8a96bb1451.tar.gz
[MERGE] fixes and tests for Renew (RT #130841)
-rw-r--r--perlio.c7
-rw-r--r--pp_hot.c2
-rw-r--r--pp_sort.c2
-rw-r--r--reentr.c37
-rw-r--r--regcomp.c10
-rw-r--r--regen/reentr.pl37
-rw-r--r--scope.c29
-rw-r--r--t/op/range.t33
-rw-r--r--util.c18
-rw-r--r--win32/win32.c2
-rw-r--r--win32/wince.c2
11 files changed, 111 insertions, 68 deletions
diff --git a/perlio.c b/perlio.c
index 3e936a26d0..e9d3700cfe 100644
--- a/perlio.c
+++ b/perlio.c
@@ -547,11 +547,12 @@ PerlIO_list_push(pTHX_ PerlIO_list_t *list, PerlIO_funcs *funcs, SV *arg)
PERL_UNUSED_CONTEXT;
if (list->cur >= list->len) {
- list->len += 8;
+ const IV new_len = list->len + 8;
if (list->array)
- Renew(list->array, list->len, PerlIO_pair_t);
+ Renew(list->array, new_len, PerlIO_pair_t);
else
- Newx(list->array, list->len, PerlIO_pair_t);
+ Newx(list->array, new_len, PerlIO_pair_t);
+ list->len = new_len;
}
p = &(list->array[list->cur++]);
p->funcs = funcs;
diff --git a/pp_hot.c b/pp_hot.c
index 58bbe2f1e9..4f0d094ce6 100644
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -4134,8 +4134,8 @@ PP(pp_entersub)
items = SP - MARK;
if (UNLIKELY(items - 1 > AvMAX(av))) {
SV **ary = AvALLOC(av);
- AvMAX(av) = items - 1;
Renew(ary, items, SV*);
+ AvMAX(av) = items - 1;
AvALLOC(av) = ary;
AvARRAY(av) = ary;
}
diff --git a/pp_sort.c b/pp_sort.c
index 21e4574c1f..a54768a022 100644
--- a/pp_sort.c
+++ b/pp_sort.c
@@ -1831,8 +1831,8 @@ S_sortcv_stacked(pTHX_ SV *const a, SV *const b)
AvARRAY(av) = ary;
}
if (AvMAX(av) < 1) {
- AvMAX(av) = 1;
Renew(ary,2,SV*);
+ AvMAX(av) = 1;
AvARRAY(av) = ary;
AvALLOC(av) = ary;
}
diff --git a/reentr.c b/reentr.c
index c464acc834..70b971b5a4 100644
--- a/reentr.c
+++ b/reentr.c
@@ -33,6 +33,13 @@
#include "perl.h"
#include "reentr.h"
+#define RenewDouble(data_pointer, size_pointer, type) \
+ STMT_START { \
+ const size_t size = *(size_pointer) * 2; \
+ Renew((data_pointer), (size), type); \
+ *(size_pointer) = size; \
+ } STMT_END
+
void
Perl_reentrant_size(pTHX) {
PERL_UNUSED_CONTEXT;
@@ -326,9 +333,8 @@ Perl_reentrant_retry(const char *f, ...)
PERL_REENTRANT_MAXSIZE / 2)
#endif
{
- PL_reentrant_buffer->_hostent_size *= 2;
- Renew(PL_reentrant_buffer->_hostent_buffer,
- PL_reentrant_buffer->_hostent_size, char);
+ RenewDouble(PL_reentrant_buffer->_hostent_buffer,
+ &PL_reentrant_buffer->_hostent_size, char);
switch (PL_op->op_type) {
case OP_GHBYADDR:
p0 = va_arg(ap, void *);
@@ -359,9 +365,8 @@ Perl_reentrant_retry(const char *f, ...)
#endif
{
Gid_t gid;
- PL_reentrant_buffer->_grent_size *= 2;
- Renew(PL_reentrant_buffer->_grent_buffer,
- PL_reentrant_buffer->_grent_size, char);
+ RenewDouble(PL_reentrant_buffer->_grent_buffer,
+ &PL_reentrant_buffer->_grent_size, char);
switch (PL_op->op_type) {
case OP_GGRNAM:
p0 = va_arg(ap, void *);
@@ -394,9 +399,8 @@ Perl_reentrant_retry(const char *f, ...)
#endif
{
Netdb_net_t net;
- PL_reentrant_buffer->_netent_size *= 2;
- Renew(PL_reentrant_buffer->_netent_buffer,
- PL_reentrant_buffer->_netent_size, char);
+ RenewDouble(PL_reentrant_buffer->_netent_buffer,
+ &PL_reentrant_buffer->_netent_size, char);
switch (PL_op->op_type) {
case OP_GNBYADDR:
net = va_arg(ap, Netdb_net_t);
@@ -426,9 +430,8 @@ Perl_reentrant_retry(const char *f, ...)
#endif
{
Uid_t uid;
- PL_reentrant_buffer->_pwent_size *= 2;
- Renew(PL_reentrant_buffer->_pwent_buffer,
- PL_reentrant_buffer->_pwent_size, char);
+ RenewDouble(PL_reentrant_buffer->_pwent_buffer,
+ &PL_reentrant_buffer->_pwent_size, char);
switch (PL_op->op_type) {
case OP_GPWNAM:
p0 = va_arg(ap, void *);
@@ -462,9 +465,8 @@ Perl_reentrant_retry(const char *f, ...)
PERL_REENTRANT_MAXSIZE / 2)
#endif
{
- PL_reentrant_buffer->_protoent_size *= 2;
- Renew(PL_reentrant_buffer->_protoent_buffer,
- PL_reentrant_buffer->_protoent_size, char);
+ RenewDouble(PL_reentrant_buffer->_protoent_buffer,
+ &PL_reentrant_buffer->_protoent_size, char);
switch (PL_op->op_type) {
case OP_GPBYNAME:
p0 = va_arg(ap, void *);
@@ -492,9 +494,8 @@ Perl_reentrant_retry(const char *f, ...)
PERL_REENTRANT_MAXSIZE / 2)
#endif
{
- PL_reentrant_buffer->_servent_size *= 2;
- Renew(PL_reentrant_buffer->_servent_buffer,
- PL_reentrant_buffer->_servent_size, char);
+ RenewDouble(PL_reentrant_buffer->_servent_buffer,
+ &PL_reentrant_buffer->_servent_size, char);
switch (PL_op->op_type) {
case OP_GSBYNAME:
p0 = va_arg(ap, void *);
diff --git a/regcomp.c b/regcomp.c
index 0a80cedec5..810c4573d1 100644
--- a/regcomp.c
+++ b/regcomp.c
@@ -2355,8 +2355,9 @@ is the recommended Unicode-aware way of saying
#define TRIE_LIST_PUSH(state,fid,ns) STMT_START { \
if ( TRIE_LIST_CUR( state ) >=TRIE_LIST_LEN( state ) ) { \
- U32 ging = TRIE_LIST_LEN( state ) *= 2; \
+ U32 ging = TRIE_LIST_LEN( state ) * 2; \
Renew( trie->states[ state ].trans.list, ging, reg_trie_trans_le ); \
+ TRIE_LIST_LEN( state ) = ging; \
} \
TRIE_LIST_ITEM( state, TRIE_LIST_CUR( state ) ).forid = fid; \
TRIE_LIST_ITEM( state, TRIE_LIST_CUR( state ) ).newstate = ns; \
@@ -6416,10 +6417,11 @@ S_concat_pat(pTHX_ RExC_state_t * const pRExC_state,
* different closure than last time */
*recompile_p = 1;
if (pRExC_state->code_blocks) {
- pRExC_state->code_blocks->count += ri->code_blocks->count;
+ int new_count = pRExC_state->code_blocks->count
+ + ri->code_blocks->count;
Renew(pRExC_state->code_blocks->cb,
- pRExC_state->code_blocks->count,
- struct reg_code_block);
+ new_count, struct reg_code_block);
+ pRExC_state->code_blocks->count = new_count;
}
else
pRExC_state->code_blocks = S_alloc_code_blocks(aTHX_
diff --git a/regen/reentr.pl b/regen/reentr.pl
index 802b8db90d..f8f78a5152 100644
--- a/regen/reentr.pl
+++ b/regen/reentr.pl
@@ -773,6 +773,13 @@ print $c <<"EOF";
#include "perl.h"
#include "reentr.h"
+#define RenewDouble(data_pointer, size_pointer, type) \\
+ STMT_START { \\
+ const size_t size = *(size_pointer) * 2; \\
+ Renew((data_pointer), (size), type); \\
+ *(size_pointer) = size; \\
+ } STMT_END
+
void
Perl_reentrant_size(pTHX) {
PERL_UNUSED_CONTEXT;
@@ -840,9 +847,8 @@ Perl_reentrant_retry(const char *f, ...)
PERL_REENTRANT_MAXSIZE / 2)
#endif
{
- PL_reentrant_buffer->_hostent_size *= 2;
- Renew(PL_reentrant_buffer->_hostent_buffer,
- PL_reentrant_buffer->_hostent_size, char);
+ RenewDouble(PL_reentrant_buffer->_hostent_buffer,
+ &PL_reentrant_buffer->_hostent_size, char);
switch (PL_op->op_type) {
case OP_GHBYADDR:
p0 = va_arg(ap, void *);
@@ -873,9 +879,8 @@ Perl_reentrant_retry(const char *f, ...)
#endif
{
Gid_t gid;
- PL_reentrant_buffer->_grent_size *= 2;
- Renew(PL_reentrant_buffer->_grent_buffer,
- PL_reentrant_buffer->_grent_size, char);
+ RenewDouble(PL_reentrant_buffer->_grent_buffer,
+ &PL_reentrant_buffer->_grent_size, char);
switch (PL_op->op_type) {
case OP_GGRNAM:
p0 = va_arg(ap, void *);
@@ -908,9 +913,8 @@ Perl_reentrant_retry(const char *f, ...)
#endif
{
Netdb_net_t net;
- PL_reentrant_buffer->_netent_size *= 2;
- Renew(PL_reentrant_buffer->_netent_buffer,
- PL_reentrant_buffer->_netent_size, char);
+ RenewDouble(PL_reentrant_buffer->_netent_buffer,
+ &PL_reentrant_buffer->_netent_size, char);
switch (PL_op->op_type) {
case OP_GNBYADDR:
net = va_arg(ap, Netdb_net_t);
@@ -940,9 +944,8 @@ Perl_reentrant_retry(const char *f, ...)
#endif
{
Uid_t uid;
- PL_reentrant_buffer->_pwent_size *= 2;
- Renew(PL_reentrant_buffer->_pwent_buffer,
- PL_reentrant_buffer->_pwent_size, char);
+ RenewDouble(PL_reentrant_buffer->_pwent_buffer,
+ &PL_reentrant_buffer->_pwent_size, char);
switch (PL_op->op_type) {
case OP_GPWNAM:
p0 = va_arg(ap, void *);
@@ -976,9 +979,8 @@ Perl_reentrant_retry(const char *f, ...)
PERL_REENTRANT_MAXSIZE / 2)
#endif
{
- PL_reentrant_buffer->_protoent_size *= 2;
- Renew(PL_reentrant_buffer->_protoent_buffer,
- PL_reentrant_buffer->_protoent_size, char);
+ RenewDouble(PL_reentrant_buffer->_protoent_buffer,
+ &PL_reentrant_buffer->_protoent_size, char);
switch (PL_op->op_type) {
case OP_GPBYNAME:
p0 = va_arg(ap, void *);
@@ -1006,9 +1008,8 @@ Perl_reentrant_retry(const char *f, ...)
PERL_REENTRANT_MAXSIZE / 2)
#endif
{
- PL_reentrant_buffer->_servent_size *= 2;
- Renew(PL_reentrant_buffer->_servent_buffer,
- PL_reentrant_buffer->_servent_size, char);
+ RenewDouble(PL_reentrant_buffer->_servent_buffer,
+ &PL_reentrant_buffer->_servent_size, char);
switch (PL_op->op_type) {
case OP_GSBYNAME:
p0 = va_arg(ap, void *);
diff --git a/scope.c b/scope.c
index 4b302e7665..c51a125dfa 100644
--- a/scope.c
+++ b/scope.c
@@ -90,11 +90,12 @@ I32
Perl_cxinc(pTHX)
{
const IV old_max = cxstack_max;
- cxstack_max = GROW(cxstack_max);
- Renew(cxstack, cxstack_max + 1, PERL_CONTEXT);
+ const IV new_max = GROW(cxstack_max);
+ Renew(cxstack, new_max + 1, PERL_CONTEXT);
+ cxstack_max = new_max;
/* Without any kind of initialising deep enough recursion
* will end up reading uninitialised PERL_CONTEXTs. */
- PoisonNew(cxstack + old_max + 1, cxstack_max - old_max, PERL_CONTEXT);
+ PoisonNew(cxstack + old_max + 1, new_max - old_max, PERL_CONTEXT);
return cxstack_ix + 1;
}
@@ -102,11 +103,12 @@ void
Perl_push_scope(pTHX)
{
if (UNLIKELY(PL_scopestack_ix == PL_scopestack_max)) {
- PL_scopestack_max = GROW(PL_scopestack_max);
- Renew(PL_scopestack, PL_scopestack_max, I32);
+ const IV new_max = GROW(PL_scopestack_max);
+ Renew(PL_scopestack, new_max, I32);
#ifdef DEBUGGING
- Renew(PL_scopestack_name, PL_scopestack_max, const char*);
+ Renew(PL_scopestack_name, new_max, const char*);
#endif
+ PL_scopestack_max = new_max;
}
#ifdef DEBUGGING
PL_scopestack_name[PL_scopestack_ix] = "unknown";
@@ -140,23 +142,26 @@ Perl_markstack_grow(pTHX)
void
Perl_savestack_grow(pTHX)
{
+ IV new_max;
#ifdef STRESS_REALLOC
- PL_savestack_max += SS_MAXPUSH;
+ new_max = PL_savestack_max + SS_MAXPUSH;
#else
- PL_savestack_max = GROW(PL_savestack_max);
+ new_max = GROW(PL_savestack_max);
#endif
/* Note that we allocate SS_MAXPUSH slots higher than ss_max
* so that SS_ADD_END(), SSGROW() etc can do a simper check */
- Renew(PL_savestack, PL_savestack_max + SS_MAXPUSH, ANY);
+ Renew(PL_savestack, new_max + SS_MAXPUSH, ANY);
+ PL_savestack_max = new_max;
}
void
Perl_savestack_grow_cnt(pTHX_ I32 need)
{
- PL_savestack_max = PL_savestack_ix + need;
+ const IV new_max = PL_savestack_ix + need;
/* Note that we allocate SS_MAXPUSH slots higher than ss_max
* so that SS_ADD_END(), SSGROW() etc can do a simper check */
- Renew(PL_savestack, PL_savestack_max + SS_MAXPUSH, ANY);
+ Renew(PL_savestack, new_max + SS_MAXPUSH, ANY);
+ PL_savestack_max = new_max;
}
#undef GROW
@@ -186,8 +191,8 @@ Perl_tmps_grow_p(pTHX_ SSize_t ix)
if (ix - PL_tmps_max < 128)
extend_to += (PL_tmps_max < 512) ? 128 : 512;
#endif
+ Renew(PL_tmps_stack, extend_to + 1, SV*);
PL_tmps_max = extend_to + 1;
- Renew(PL_tmps_stack, PL_tmps_max, SV*);
return ix;
}
diff --git a/t/op/range.t b/t/op/range.t
index e58a39c8e8..02a38e0497 100644
--- a/t/op/range.t
+++ b/t/op/range.t
@@ -9,7 +9,7 @@ BEGIN {
use Config;
-plan (145);
+plan (146);
is(join(':',1..5), '1:2:3:4:5');
@@ -417,4 +417,33 @@ is( ( join ' ', map { join '', map ++$_, 'a'..'d' } 1..2 ), 'bcde bcde',
$s = ''; for (1..2) { for ('a'..'d') { $s .= ++$_ } $s.=' ' if $_==1; }
is( $s, 'bcde bcde','modifiable alpha counting loop counter' );
-# EOF
+# RT #130841
+# generating an extreme range triggered a croak, which if caught,
+# left the temps stack small but with a very large PL_tmps_max
+
+fresh_perl_like(<<'EOF', qr/\Aok 1 ok 2\Z/, {}, "RT #130841");
+my $max_iv = (~0 >> 1);
+eval {
+ my @range = 1..($max_iv - 1);
+};
+if ($@ =~ /panic: memory wrap|Out of memory/) {
+ print "ok 1";
+}
+else {
+ print "unexpected err status: [$@]";
+}
+
+# create and push lots of temps
+my $max = 10_000;
+my @ints = map $_+1, 0..($max-1);
+my $sum = 0;
+$sum += $_ for @ints;
+my $exp = $max*($max+1)/2;
+if ($sum == $exp) {
+ print " ok 2";
+}
+else {
+ print " unexpected sum: [$sum]; expected: [$exp]";
+}
+EOF
+
diff --git a/util.c b/util.c
index bd568bc22a..b324af43ed 100644
--- a/util.c
+++ b/util.c
@@ -5352,9 +5352,11 @@ Perl_my_cxt_init(pTHX_ int *index, size_t size)
/* make sure the array is big enough */
if (PL_my_cxt_size <= *index) {
if (PL_my_cxt_size) {
- while (PL_my_cxt_size <= *index)
- PL_my_cxt_size *= 2;
- Renew(PL_my_cxt_list, PL_my_cxt_size, void *);
+ IV new_size = PL_my_cxt_size;
+ while (new_size <= *index)
+ new_size *= 2;
+ Renew(PL_my_cxt_list, new_size, void *);
+ PL_my_cxt_size = new_size;
}
else {
PL_my_cxt_size = 16;
@@ -5415,10 +5417,12 @@ Perl_my_cxt_init(pTHX_ const char *my_cxt_key, size_t size)
int old_size = PL_my_cxt_size;
int i;
if (PL_my_cxt_size) {
- while (PL_my_cxt_size <= index)
- PL_my_cxt_size *= 2;
- Renew(PL_my_cxt_list, PL_my_cxt_size, void *);
- Renew(PL_my_cxt_keys, PL_my_cxt_size, const char *);
+ IV new_size = PL_my_cxt_size;
+ while (new_size <= index)
+ new_size *= 2;
+ Renew(PL_my_cxt_list, new_size, void *);
+ Renew(PL_my_cxt_keys, new_size, const char *);
+ PL_my_cxt_size = new_size;
}
else {
PL_my_cxt_size = 16;
diff --git a/win32/win32.c b/win32/win32.c
index 39819212d2..2e82c53462 100644
--- a/win32/win32.c
+++ b/win32/win32.c
@@ -968,8 +968,8 @@ win32_readdir(DIR *dirp)
* new name and its null terminator */
while (newsize > dirp->size) {
long curpos = dirp->curr - dirp->start;
+ Renew(dirp->start, dirp->size * 2, char);
dirp->size *= 2;
- Renew(dirp->start, dirp->size, char);
dirp->curr = dirp->start + curpos;
}
strcpy(dirp->start + endpos, buffer);
diff --git a/win32/wince.c b/win32/wince.c
index 56a23b5e98..045853779a 100644
--- a/win32/wince.c
+++ b/win32/wince.c
@@ -765,8 +765,8 @@ win32_readdir(DIR *dirp)
* new name and its null terminator */
while (newsize > dirp->size) {
long curpos = dirp->curr - dirp->start;
+ Renew(dirp->start, dirp->size * 2, char);
dirp->size *= 2;
- Renew(dirp->start, dirp->size, char);
dirp->curr = dirp->start + curpos;
}
strcpy(dirp->start + endpos, ptr);