diff options
author | David Mitchell <davem@iabyn.com> | 2017-03-15 09:25:51 +0000 |
---|---|---|
committer | David Mitchell <davem@iabyn.com> | 2017-03-15 09:25:51 +0000 |
commit | 95d8e32b92e4e78f0c172dd82ff70a8a96bb1451 (patch) | |
tree | 29bcb3e79f81cb7fcb9bc02ff828c860f950eca7 | |
parent | c61597183215b0dad8f01e5b9d60419ce3768b41 (diff) | |
parent | a7dd840b16566dcdb761159060e3f05d9ed57073 (diff) | |
download | perl-95d8e32b92e4e78f0c172dd82ff70a8a96bb1451.tar.gz |
[MERGE] fixes and tests for Renew (RT #130841)
-rw-r--r-- | perlio.c | 7 | ||||
-rw-r--r-- | pp_hot.c | 2 | ||||
-rw-r--r-- | pp_sort.c | 2 | ||||
-rw-r--r-- | reentr.c | 37 | ||||
-rw-r--r-- | regcomp.c | 10 | ||||
-rw-r--r-- | regen/reentr.pl | 37 | ||||
-rw-r--r-- | scope.c | 29 | ||||
-rw-r--r-- | t/op/range.t | 33 | ||||
-rw-r--r-- | util.c | 18 | ||||
-rw-r--r-- | win32/win32.c | 2 | ||||
-rw-r--r-- | win32/wince.c | 2 |
11 files changed, 111 insertions, 68 deletions
@@ -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; @@ -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; } @@ -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; } @@ -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 *); @@ -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 *); @@ -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 + @@ -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); |