From 75bb5aa48dfcf930533cd069393fc8a45e4ece18 Mon Sep 17 00:00:00 2001 From: David Mitchell Date: Fri, 22 Mar 2019 12:31:57 +0000 Subject: [PATCH] fix leak in cloned regexes. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a regex is cloned for a new thread, the string buffer (which holds the text of the original pattern) wasn't being freed because SvLEN was being set to 0. For example: use threads; my $r = qr/abc/; threads->new( sub { 1; })->join; In the new thread, $r is cloned but when the thread exits, the string buffer holding "(?^:abc)" was leaking. This was broken by v5.27.2-30-gdf6b4bd565. The problem was that in the cloned SV, the buffer was copied, but the SvLEN(sv) was left set at zero, which along with the SVf_FAKE, mader it look like the buffer was alien and so not freed. SvLEN was 0 in the parent thread's $r, since $r and its compile-time prototype share the same string buffer (so only the original SV has SvLEN > 0 - all the copies - within the same thread - have mother_re pointing to the original). When REs are cloned into another thread, mother_re isn't preserved, so each RE has its own copy of the buffer. Signed-off-by: Petr Písař --- regcomp.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/regcomp.c b/regcomp.c index 547b9113e3..15783541a4 100644 --- a/regcomp.c +++ b/regcomp.c @@ -20956,6 +20956,11 @@ Perl_re_dup_guts(pTHX_ const REGEXP *sstr, REGEXP *dstr, CLONE_PARAMS *param) 2: something we no longer hold a reference on so we need to copy it locally. */ RX_WRAPPED(dstr) = SAVEPVN(RX_WRAPPED_const(sstr), SvCUR(sstr)+1); + /* set malloced length to a non-zero value so it will be freed + * (otherwise in combination with SVf_FAKE it looks like an alien + * buffer). It doesn't have to be the actual malloced size, since it + * should never be grown */ + SvLEN_set(dstr, SvCUR(sstr)+1); ret->mother_re = NULL; } #endif /* PERL_IN_XSUB_RE */ -- 2.20.1