From 43cbd598f60a85afcfc3de71e89e8a48330158f5 Mon Sep 17 00:00:00 2001 From: Tony Cook 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[]} ;