(I am referring to what is usually known simply as The Stack.)
This partially fixes #119161.
By casting the argument to int, we can end up truncating/wrapping
it on 64-bit systems, so EXTEND(SP,
2147483648) translates into
EXTEND(SP, -1), which does not extend the stack at all. Then writing
to the stack in code like ()=1..
1000000000000 goes past the end of
allocated memory and crashes.
I can’t really write a test for this, since instead of crashing it
will use more memory than I have available (and then I’ll start for-
getting things).
*/
void
-Perl_av_extend(pTHX_ AV *av, I32 key)
+Perl_av_extend(pTHX_ AV *av, SSize_t key)
{
dVAR;
MAGIC *mg;
/* The guts of av_extend. *Not* for general use! */
void
-Perl_av_extend_guts(pTHX_ AV *av, I32 key, SSize_t *maxp, SV ***allocp,
+Perl_av_extend_guts(pTHX_ AV *av, SSize_t key, SSize_t *maxp, SV ***allocp,
SV ***arrayp)
{
dVAR;
if (key > *maxp) {
SV** ary;
- I32 tmp;
- I32 newmax;
+ SSize_t tmp;
+ SSize_t newmax;
if (av && *allocp != *arrayp) {
ary = *allocp + AvFILLp(av) + 1;
Apd |void |av_clear |NN AV *av
Apd |SV* |av_delete |NN AV *av|I32 key|I32 flags
ApdR |bool |av_exists |NN AV *av|I32 key
-Apd |void |av_extend |NN AV *av|I32 key
-p |void |av_extend_guts |NULLOK AV *av|I32 key|NN SSize_t *maxp \
+Apd |void |av_extend |NN AV *av|SSize_t key
+p |void |av_extend_guts |NULLOK AV *av|SSize_t key \
+ |NN SSize_t *maxp \
|NN SV ***allocp|NN SV ***arrayp
ApdR |SV** |av_fetch |NN AV *av|I32 key|I32 lval
Apd |void |av_fill |NN AV *av|I32 fill
np |Signal_t |sighandler |int sig
Anp |Signal_t |csighandler |int sig
#endif
-Ap |SV** |stack_grow |NN SV** sp|NN SV** p|int n
+Ap |SV** |stack_grow |NN SV** sp|NN SV** p|SSize_t n
Ap |I32 |start_subparse |I32 is_format|U32 flags
: Used in pp_ctl.c
p |void |sub_crush_depth|NN CV* cv
/* Go to some pains in the rare event that we must extend the stack. */
/*
-=for apidoc Am|void|EXTEND|SP|int nitems
+=for apidoc Am|void|EXTEND|SP|SSize_t nitems
Used to extend the argument stack for an XSUB's return values. Once
used, guarantees that there is room for at least C<nitems> to be pushed
onto the stack.
=cut
*/
-#define EXTEND(p,n) (void)(UNLIKELY(PL_stack_max - p < (int)(n)) && \
- (sp = stack_grow(sp,p, (int) (n))))
+#define EXTEND(p,n) (void)(UNLIKELY(PL_stack_max - p < (SSize_t)(n)) && \
+ (sp = stack_grow(sp,p, (SSize_t) (n))))
/* Same thing, but update mark register too. */
#define MEXTEND(p,n) STMT_START {if (UNLIKELY(PL_stack_max - p < (int)(n))) {\
const int markoff = mark - PL_stack_base; \
- sp = stack_grow(sp,p,(int) (n)); \
+ sp = stack_grow(sp,p,(SSize_t) (n)); \
mark = PL_stack_base + markoff; \
} } STMT_END
#define PERL_ARGS_ASSERT_AV_EXISTS \
assert(av)
-PERL_CALLCONV void Perl_av_extend(pTHX_ AV *av, I32 key)
+PERL_CALLCONV void Perl_av_extend(pTHX_ AV *av, SSize_t key)
__attribute__nonnull__(pTHX_1);
#define PERL_ARGS_ASSERT_AV_EXTEND \
assert(av)
-PERL_CALLCONV void Perl_av_extend_guts(pTHX_ AV *av, I32 key, SSize_t *maxp, SV ***allocp, SV ***arrayp)
+PERL_CALLCONV void Perl_av_extend_guts(pTHX_ AV *av, SSize_t key, SSize_t *maxp, SV ***allocp, SV ***arrayp)
__attribute__nonnull__(pTHX_3)
__attribute__nonnull__(pTHX_4)
__attribute__nonnull__(pTHX_5);
#define PERL_ARGS_ASSERT_SORTSV_FLAGS \
assert(cmp)
-PERL_CALLCONV SV** Perl_stack_grow(pTHX_ SV** sp, SV** p, int n)
+PERL_CALLCONV SV** Perl_stack_grow(pTHX_ SV** sp, SV** p, SSize_t n)
__attribute__nonnull__(pTHX_1)
__attribute__nonnull__(pTHX_2);
#define PERL_ARGS_ASSERT_STACK_GROW \
#include "perl.h"
SV**
-Perl_stack_grow(pTHX_ SV **sp, SV **p, int n)
+Perl_stack_grow(pTHX_ SV **sp, SV **p, SSize_t n)
{
dVAR;