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