summaryrefslogtreecommitdiff
path: root/pp_sys.c
diff options
context:
space:
mode:
authorDavid Mitchell <davem@iabyn.com>2015-09-21 14:49:22 +0100
committerDavid Mitchell <davem@iabyn.com>2015-10-02 11:29:35 +0100
commit052a7c766b9640ee847979cb9d2351a63e23a378 (patch)
tree1a796b916aa4702854196a5c6ef9767b4d6b98e8 /pp_sys.c
parent6768377c79109b7124f0c8a4e3677982689d9f49 (diff)
downloadperl-052a7c766b9640ee847979cb9d2351a63e23a378.tar.gz
fix up EXTEND() callers
The previous commit made it clear that the N argument to EXTEND() is supposed to be signed, in particular SSize_t, and now typically triggers compiler warnings where this isn't the case. This commit fixes the various places in core that passed the wrong sort of N to EXTEND(). The fixes are in three broad categories. First, where sensible, I've changed the relevant var to be SSize_t. Second, where its expected that N could never be large enough to wrap, I've just added an assert and a cast. Finally, I've added extra code to detect whether the cast could wrap/truncate, and if so set N to -1, which will trigger a panic in stack_grow(). This also fixes [perl #125937] 'x' operator on list causes segfault with possible stack corruption
Diffstat (limited to 'pp_sys.c')
-rw-r--r--pp_sys.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/pp_sys.c b/pp_sys.c
index f1e290240b..f9579afa86 100644
--- a/pp_sys.c
+++ b/pp_sys.c
@@ -533,6 +533,7 @@ Perl_tied_method(pTHX_ SV *methname, SV **sp, SV *const sv,
{
SV **orig_sp = sp;
I32 ret_args;
+ SSize_t extend_size;
PERL_ARGS_ASSERT_TIED_METHOD;
@@ -543,7 +544,12 @@ Perl_tied_method(pTHX_ SV *methname, SV **sp, SV *const sv,
PUTBACK; /* sp is at *foot* of args, so this pops args from old stack */
PUSHSTACKi(PERLSI_MAGIC);
- EXTEND(SP, argc+1); /* object + args */
+ /* extend for object + args. If argc might wrap/truncate when cast
+ * to SSize_t, set to -1 which will trigger a panic in EXTEND() */
+ extend_size =
+ sizeof(argc) >= sizeof(SSize_t) && argc > SSize_t_MAX - 1
+ ? -1 : (SSize_t)argc + 1;
+ EXTEND(SP, extend_size);
PUSHMARK(sp);
PUSHs(SvTIED_obj(sv, mg));
if (flags & TIED_METHOD_ARGUMENTS_ON_STACK) {