683572
From 28eabf1185634216ca335b3a24e1131b0f392ca1 Mon Sep 17 00:00:00 2001
683572
From: David Mitchell <davem@iabyn.com>
683572
Date: Wed, 10 Jul 2019 12:59:06 +0100
683572
Subject: [PATCH] avoid SEGV with uninit warning with multideref
683572
MIME-Version: 1.0
683572
Content-Type: text/plain; charset=UTF-8
683572
Content-Transfer-Encoding: 8bit
683572
683572
RT #134275
683572
683572
When the 'uninitialized warning' code in S_find_uninit_var() comes
683572
across an OP_MULTIDEREF node, it scans it to see if any part of that op
683572
(e.g. the indices or the returned value) could have been the source of
683572
the uninitialized value which triggered the warning.  Unfortunately when
683572
getting an AV or HV from a GV, it wasn't checking whether gp_av/gp_hv
683572
contained a NULL value. If so, it would SEGV.
683572
683572
The test code is a bit contrived; you have to "pull the rug" from under
683572
the GV at just the right moment with *foo = *bar, then trigger an uninit
683572
warning on an op whose subtree includes an OP_MULTIDEREF.
683572
683572
Signed-off-by: Petr Písař <ppisar@redhat.com>
683572
---
683572
 sv.c                   |  5 ++++-
683572
 t/lib/warnings/9uninit | 10 ++++++++++
683572
 2 files changed, 14 insertions(+), 1 deletion(-)
683572
683572
diff --git a/sv.c b/sv.c
683572
index 83de536ad7..4315fe9b64 100644
683572
--- a/sv.c
683572
+++ b/sv.c
683572
@@ -16662,8 +16662,11 @@ S_find_uninit_var(pTHX_ const OP *const obase, const SV *const uninit_sv,
683572
 
683572
         if (agg_targ)
683572
 	    sv = PAD_SV(agg_targ);
683572
-        else if (agg_gv)
683572
+        else if (agg_gv) {
683572
             sv = is_hv ? MUTABLE_SV(GvHV(agg_gv)) : MUTABLE_SV(GvAV(agg_gv));
683572
+            if (!sv)
683572
+                break;
683572
+            }
683572
         else
683572
             break;
683572
 
683572
diff --git a/t/lib/warnings/9uninit b/t/lib/warnings/9uninit
683572
index 774c6ee432..5c173fdb2a 100644
683572
--- a/t/lib/warnings/9uninit
683572
+++ b/t/lib/warnings/9uninit
683572
@@ -2206,3 +2206,13 @@ use warnings 'uninitialized';
683572
 undef $0;
683572
 EXPECT
683572
 Use of uninitialized value in undef operator at - line 5.
683572
+########
683572
+# RT #134275
683572
+# This was SEGVing due to the multideref code in S_find_uninit_var not
683572
+# handling a GV with a null gp_hv slot.
683572
+use warnings 'uninitialized';
683572
+"" =~ /$foo{a}${*foo=*bar}$x/;
683572
+EXPECT
683572
+Use of uninitialized value in regexp compilation at - line 5.
683572
+Use of uninitialized value in regexp compilation at - line 5.
683572
+Use of uninitialized value $x in regexp compilation at - line 5.
683572
-- 
683572
2.20.1
683572