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