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