b2938d
From 5f41fa466a67b5535aa8bcf4b814f242545ac7bd Mon Sep 17 00:00:00 2001
b2938d
From: Karl Williamson <khw@cpan.org>
b2938d
Date: Sat, 27 Feb 2021 11:43:41 -0700
b2938d
Subject: [PATCH] regcomp.c: Remove memory leak
b2938d
MIME-Version: 1.0
b2938d
Content-Type: text/plain; charset=UTF-8
b2938d
Content-Transfer-Encoding: 8bit
b2938d
b2938d
This fixes GH #18604.  There was a path through the code where a
b2938d
particular SV did not get its reference count decremented.
b2938d
b2938d
I did an audit of the function and came up with several other
b2938d
possiblities that are included in this commit.
b2938d
b2938d
Further, there would be leaks for some instances of finding syntax
b2938d
errors in the input pattern, or when warnings are fatalized.  Those
b2938d
would require mortalizing some SVs, but that is beyond the scope of this
b2938d
commit.
b2938d
b2938d
Signed-off-by: Petr Písař <ppisar@redhat.com>
b2938d
---
b2938d
 regcomp.c     | 7 +++++++
b2938d
 t/op/svleak.t | 3 ++-
b2938d
 2 files changed, 9 insertions(+), 1 deletion(-)
b2938d
b2938d
diff --git a/regcomp.c b/regcomp.c
b2938d
index e44c7a37e5..f5e5f581dc 100644
b2938d
--- a/regcomp.c
b2938d
+++ b/regcomp.c
b2938d
@@ -18765,6 +18765,12 @@ S_regclass(pTHX_ RExC_state_t *pRExC_state, I32 *flagp, U32 depth,
b2938d
 	RExC_end = save_end;
b2938d
 	RExC_in_multi_char_class = 0;
b2938d
         SvREFCNT_dec_NN(multi_char_matches);
b2938d
+        SvREFCNT_dec(properties);
b2938d
+        SvREFCNT_dec(cp_list);
b2938d
+        SvREFCNT_dec(simple_posixes);
b2938d
+        SvREFCNT_dec(posixes);
b2938d
+        SvREFCNT_dec(nposixes);
b2938d
+        SvREFCNT_dec(cp_foldable_list);
b2938d
         return ret;
b2938d
     }
b2938d
 
b2938d
@@ -20122,6 +20128,7 @@ S_regclass(pTHX_ RExC_state_t *pRExC_state, I32 *flagp, U32 depth,
b2938d
                                            RExC_parse - orig_parse);;
b2938d
     SvREFCNT_dec(cp_list);;
b2938d
     SvREFCNT_dec(only_utf8_locale_list);
b2938d
+    SvREFCNT_dec(upper_latin1_only_utf8_matches);
b2938d
     return ret;
b2938d
 }
b2938d
 
b2938d
diff --git a/t/op/svleak.t b/t/op/svleak.t
b2938d
index 6acc298c3d..3df4838be8 100644
b2938d
--- a/t/op/svleak.t
b2938d
+++ b/t/op/svleak.t
b2938d
@@ -15,7 +15,7 @@ BEGIN {
b2938d
 
b2938d
 use Config;
b2938d
 
b2938d
-plan tests => 150;
b2938d
+plan tests => 151;
b2938d
 
b2938d
 # run some code N times. If the number of SVs at the end of loop N is
b2938d
 # greater than (N-1)*delta at the end of loop 1, we've got a leak
b2938d
@@ -278,6 +278,7 @@ eleak(2,0,'/[[:ascii:]]/');
b2938d
 eleak(2,0,'/[[.zog.]]/');
b2938d
 eleak(2,0,'/[.zog.]/');
b2938d
 eleak(2,0,'/|\W/', '/|\W/ [perl #123198]');
b2938d
+eleak(2,0,'/a\sb/', '/a\sb/ [GH #18604]');
b2938d
 eleak(2,0,'no warnings; /(?[])/');
b2938d
 eleak(2,0,'no warnings; /(?[[a]+[b]])/');
b2938d
 eleak(2,0,'no warnings; /(?[[a]-[b]])/');
b2938d
-- 
b2938d
2.26.2
b2938d