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