Stop uninit sort warnings from crashing
authorFather Chrysostomos <sprout@cpan.org>
Fri, 14 Oct 2011 03:25:39 +0000 (20:25 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Fri, 14 Oct 2011 03:26:49 +0000 (20:26 -0700)
Commit d4c6760a made the warning in cases like this mention the
sort operator:

$ ./miniperl -we '()=sort { undef } 1,2'
Use of uninitialized value [in sort] at -e line 1.

It did so by setting PL_op during the SvIV(retval of sort block).  But
sv.c:S_find_uninit_var, called by report_uninit, tries to access the
targets of some ops, which are in PL_curpad on threaded builds.  In
the case of a sort sub (rather than an inlined block), PL_curpad con-
tained whatever was left over from the sort block (I presume, but
have not confirmed; in any case what is in PL_curpad is bad), causing
find_uninit_var to crash.

This commit sets PL_curpad to null and puts a check for it in
report_uninit.

It did not crash in debugging threaded builds, but that was probably
luck (even though I don’t believe in it).

pp_sort.c
sv.c

index 0ee42dc..2257d2f 100644 (file)
--- a/pp_sort.c
+++ b/pp_sort.c
@@ -1765,6 +1765,7 @@ S_sortcv(pTHX_ SV *const a, SV *const b)
     I32 result;
     PMOP * const pm = PL_curpm;
     OP * const sortop = PL_op;
+    SV **pad;
  
     PERL_ARGS_ASSERT_SORTCV;
 
@@ -1776,7 +1777,9 @@ S_sortcv(pTHX_ SV *const a, SV *const b)
     if (PL_stack_sp != PL_stack_base + 1)
        Perl_croak(aTHX_ "Sort subroutine didn't return single value");
     PL_op = sortop;
+    pad = PL_curpad; PL_curpad = 0;
     result = SvIV(*PL_stack_sp);
+    PL_curpad = pad;
     while (PL_scopestack_ix > oldscopeix) {
        LEAVE;
     }
@@ -1795,6 +1798,7 @@ S_sortcv_stacked(pTHX_ SV *const a, SV *const b)
     AV * const av = GvAV(PL_defgv);
     PMOP * const pm = PL_curpm;
     OP * const sortop = PL_op;
+    SV **pad;
 
     PERL_ARGS_ASSERT_SORTCV_STACKED;
 
@@ -1826,7 +1830,9 @@ S_sortcv_stacked(pTHX_ SV *const a, SV *const b)
     if (PL_stack_sp != PL_stack_base + 1)
        Perl_croak(aTHX_ "Sort subroutine didn't return single value");
     PL_op = sortop;
+    pad = PL_curpad; PL_curpad = 0;
     result = SvIV(*PL_stack_sp);
+    PL_curpad = pad;
     while (PL_scopestack_ix > oldscopeix) {
        LEAVE;
     }
diff --git a/sv.c b/sv.c
index e0bcfdf..5ee4817 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -14314,7 +14314,7 @@ Perl_report_uninit(pTHX_ const SV *uninit_sv)
     dVAR;
     if (PL_op) {
        SV* varname = NULL;
-       if (uninit_sv) {
+       if (uninit_sv && PL_curpad) {
            varname = find_uninit_var(PL_op, uninit_sv,0);
            if (varname)
                sv_insert(varname, 0, 0, " ", 1);