if (key <= newmax)
goto resized;
#endif
- newmax = key + *maxp / 5;
+ /* overflow-safe version of newmax = key + *maxp/5 */
+ newmax = *maxp / 5;
+ newmax = (key > SSize_t_MAX - newmax)
+ ? SSize_t_MAX : key + newmax;
resize:
{
#ifdef PERL_MALLOC_WRAP /* Duplicated in pp_hot.c */
static const char oom_array_extend[] =
"Out of memory during array extend";
#endif
- MEM_WRAP_CHECK_1(newmax+1, SV*, oom_array_extend);
+ /* it should really be newmax+1 here, but if newmax
+ * happens to equal SSize_t_MAX, then newmax+1 is
+ * undefined. This means technically we croak one
+ * index lower than we should in theory; in practice
+ * its unlikely the system has SSize_t_MAX/sizeof(SV*)
+ * bytes to spare! */
+ MEM_WRAP_CHECK_1(newmax, SV*, oom_array_extend);
}
#ifdef STRESS_REALLOC
{
static const char oom_array_extend[] =
"Out of memory during array extend";
#endif
- MEM_WRAP_CHECK_1(newmax+1, SV*, oom_array_extend);
+ /* see comment above about newmax+1*/
+ MEM_WRAP_CHECK_1(newmax, SV*, oom_array_extend);
}
Newx(*allocp, newmax+1, SV*);
ary = *allocp + 1;
(A slightly shorter form is C<av_tindex>.)
-=for apidoc av_tindex
-
-Same as L</av_top_index>.
-
=for apidoc av_len
Same as L</av_top_index>. Note that, unlike what the name implies, it returns
Set the highest index in the array to the given number, equivalent to
Perl's C<$#array = $fill;>.
-The number of elements in the an array will be C<fill + 1> after
+The number of elements in the array will be C<fill + 1> after
av_fill() returns. If the array was previously shorter, then the
additional elements appended are set to NULL. If the array
was longer, then the excess elements are freed. C<av_fill(av, -1)> is