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