summaryrefslogtreecommitdiff
path: root/regcomp.c
diff options
context:
space:
mode:
authorÆvar Arnfjörð Bjarmason <avar@cpan.org>2011-12-13 14:43:12 +0000
committerÆvar Arnfjörð Bjarmason <avar@cpan.org>2011-12-13 18:08:57 +0000
commit7402016d87474403eea5c52dc2c071f68cbbe25c (patch)
tree2753418938de6a46e30356ed966b7cfd7555ba5e /regcomp.c
parent8bb04350e086e681dbcecc759f9c887e24cbceef (diff)
downloadperl-7402016d87474403eea5c52dc2c071f68cbbe25c.tar.gz
[RT #78266] Don't leak memory when accessing named captures that didn't match
Since 5.10 (probably 44a2ac759e) named captures have been leaking memory when they're used, don't actually match, but are later accessed. E.g.: $ perl -wle 'for (1..10_000_000) { if ("foo" =~ /(foo|(?<capture>bar))?/) { my $capture = $+{capture} } } system "ps -o rss $$"' RSS 238524 Here we match the "foo" branch of our regex, but since we've used a name capture we'll end up running the code in Perl_reg_named_buff_fetch, which allocates a newSVsv(&PL_sv_undef) but never uses it unless it's trying to return an array. Just change that code not to allocate scalars we don't plan to return. With this fix we don't leak any memory since there's nothing to leak anymore. $ ./perl -Ilib -wle 'for (1..10_000_000) { if ("foo" =~ /(foo|(?<capture>bar))?/) { my $capture = $+{capture} } } system "ps -o rss $$"' RSS 3528 This reverts commit b28f4af8cf94eb18c0cfde71e9625081912499a8 ("Fix allocating something in the first place is a better solution than allocating it, not using it, and then freeing it.
Diffstat (limited to 'regcomp.c')
-rw-r--r--regcomp.c7
1 files changed, 2 insertions, 5 deletions
diff --git a/regcomp.c b/regcomp.c
index 9e9fac4388..56b2b9c8e7 100644
--- a/regcomp.c
+++ b/regcomp.c
@@ -5409,7 +5409,8 @@ Perl_reg_named_buff_fetch(pTHX_ REGEXP * const r, SV * const namesv,
if (!retarray)
return ret;
} else {
- ret = newSVsv(&PL_sv_undef);
+ if (retarray)
+ ret = newSVsv(&PL_sv_undef);
}
if (retarray)
av_push(retarray, ret);
@@ -5418,10 +5419,6 @@ Perl_reg_named_buff_fetch(pTHX_ REGEXP * const r, SV * const namesv,
return newRV_noinc(MUTABLE_SV(retarray));
}
}
-
- if (ret)
- SvREFCNT_dec(ret);
-
return NULL;
}