From 43cbd598f60a85afcfc3de71e89e8a48330158f5 Mon Sep 17 00:00:00 2001
From: Tony Cook <tony@develop-help.com>
Date: Wed, 22 Sep 2021 11:47:55 +1000
Subject: [PATCH] Don't try to Sv[PI]V() on an undef index SV in
 find_uninit_var()

When trying to evaluate:

  $x{$y}

or

  $x[$y]

where both the index and the hash or array entry was undefined,
when trying to report the entry as uninitialised, find_uninit_var()
would try to get the string or numeric value of the index,
recursively trying to produce a warning.

This would end up overflowing the stack, producing a segmentation fault.

Fixes #19147.

(cherry picked from commit 23cca2d1f4544cb47f1124d98c308ce1f31f09a6)
Conflict:NA
Reference:https://github.com/Perl/perl5/commit/43cbd598f60a85afcfc3de71e89e8a48330158f5
---
 sv.c              |  7 ++++---
 t/lib/warnings/sv | 13 +++++++++++++
 2 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/sv.c b/sv.c
index 27c425a54e6f..46bf9815cd15 100644
--- a/sv.c
+++ b/sv.c
@@ -16782,14 +16782,15 @@ S_find_uninit_var(pTHX_ const OP *const obase, const SV *const uninit_sv,
                 }
                 if (index_sv && !SvMAGICAL(index_sv) && !SvROK(index_sv)) {
                     if (is_hv) {
-                        HE *he = hv_fetch_ent(MUTABLE_HV(sv), index_sv, 0, 0);
+                        SV *report_index_sv = SvOK(index_sv) ? index_sv : &PL_sv_no;
+                        HE *he = hv_fetch_ent(MUTABLE_HV(sv), report_index_sv, 0, 0);
                         if (!he) {
                             return varname(agg_gv, '%', agg_targ,
-                                           index_sv, 0, FUV_SUBSCRIPT_HASH);
+                                           report_index_sv, 0, FUV_SUBSCRIPT_HASH);
                         }
                     }
                     else {
-                        SSize_t index = SvIV(index_sv);
+                        SSize_t index = SvOK(index_sv) ? SvIV(index_sv) : 0;
                         SV * const * const svp =
                             av_fetch(MUTABLE_AV(sv), index, FALSE);
                         if (!svp) {
diff --git a/t/lib/warnings/sv b/t/lib/warnings/sv
index be04b8457e3a..8524c2c25a1d 100644
--- a/t/lib/warnings/sv
+++ b/t/lib/warnings/sv
@@ -211,6 +211,19 @@ Use of uninitialized value $a in join or string at - line 4.
 Use of uninitialized value $a in concatenation (.) or string at - line 5.
 Use of uninitialized value $a in concatenation (.) or string at - line 6.
 ########
+# NAME https://github.com/Perl/perl5/issues/19147
+use warnings 'uninitialized';
+my %x;
+my @z;
+my $y;
+-$x{$y};
+-$z[$y];
+EXPECT
+Use of uninitialized value $y in hash element at - line 5.
+Use of uninitialized value $x{""} in negation (-) at - line 5.
+Use of uninitialized value $y in array element at - line 6.
+Use of uninitialized value $z[0] in negation (-) at - line 6.
+########
 # sv.c 
 use warnings 'numeric' ;
 sub TIESCALAR{bless[]} ; 
