summaryrefslogtreecommitdiff
path: root/universal.c
diff options
context:
space:
mode:
authorNicholas Clark <nick@ccl4.org>2010-10-13 14:12:27 +0100
committerNicholas Clark <nick@ccl4.org>2010-10-13 14:12:27 +0100
commit0cf05ef1177b39ff322b92e7bf0e21b642395f49 (patch)
tree822452c6085e2a4ef51958f845c68fe103ef5c3d /universal.c
parent05099f26a2ddd438807aa96853b7e317f8afc787 (diff)
downloadperl-0cf05ef1177b39ff322b92e7bf0e21b642395f49.tar.gz
In XS_Tie_Hash_NamedCapture_{CLEAR,STORE}, free any returned value.
The calling convention for CALLREG_NAMED_BUFF_*() is to return NULL, or a reference to a scalar. For CLEAR and STORE we return no values, so if we're erroneously passed a reference, we should free it to stop it being leaked.
Diffstat (limited to 'universal.c')
-rw-r--r--universal.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/universal.c b/universal.c
index f3fe05dc79..556a79661d 100644
--- a/universal.c
+++ b/universal.c
@@ -1296,6 +1296,7 @@ XS(XS_Tie_Hash_NamedCapture_STORE)
dXSARGS;
REGEXP * rx;
U32 flags;
+ SV *ret;
if (items != 3)
croak_xs_usage(cv, "$key, $value, $flags");
@@ -1310,10 +1311,15 @@ XS(XS_Tie_Hash_NamedCapture_STORE)
PUTBACK;
flags = (U32)SvUV(SvRV(MUTABLE_SV(ST(0))));
- CALLREG_NAMED_BUFF_STORE(rx,ST(1), ST(2), flags);
+ ret = CALLREG_NAMED_BUFF_STORE(rx,ST(1), ST(2), flags);
+
/* Perl_magic_setpack calls us with G_DISCARD, so our return stack state
is thrown away. */
+
+ /* If we were returned anything, free it immediately. */
+ SvREFCNT_dec(ret);
+ XSRETURN_EMPTY;
}
XS(XS_Tie_Hash_NamedCapture_DELETE)
@@ -1347,6 +1353,7 @@ XS(XS_Tie_Hash_NamedCapture_CLEAR)
dXSARGS;
REGEXP * rx;
U32 flags;
+ SV *ret;
if (items != 1)
croak_xs_usage(cv, "$flags");
@@ -1360,10 +1367,14 @@ XS(XS_Tie_Hash_NamedCapture_CLEAR)
PUTBACK;
flags = (U32)SvUV(SvRV(MUTABLE_SV(ST(0))));
- CALLREG_NAMED_BUFF_CLEAR(rx, flags);
+ ret = CALLREG_NAMED_BUFF_CLEAR(rx, flags);
/* Perl_magic_wipepack calls us with G_DISCARD, so our return stack state
is thrown away. */
+
+ /* If we were returned anything, free it immediately. */
+ SvREFCNT_dec(ret);
+ XSRETURN_EMPTY;
}
XS(XS_Tie_Hash_NamedCapture_EXISTS)