more purification (pp_require() could access free memory; vdie()
Gurusamy Sarathy [Sun, 13 Feb 2000 19:02:07 +0000 (19:02 +0000)]
could think message was random length when passed a null argument;
utilize() didn't set up the hash for the method name leading to
pp_method_named() accessing random state; PL_curpm wasn't zeroed
properly)

p4raw-id: //depot/perl@5072

cop.h
op.c
perl.c
pp_ctl.c
regcomp.c
regexec.c
scope.c
sv.c
util.c

diff --git a/cop.h b/cop.h
index 734d2ea..cfa6f48 100644 (file)
--- a/cop.h
+++ b/cop.h
@@ -149,23 +149,28 @@ struct block_sub {
 struct block_eval {
     I32                old_in_eval;
     I32                old_op_type;
-    char *     old_name;
+    SV *       old_namesv;
     OP *       old_eval_root;
     SV *       cur_text;
 };
 
 #define PUSHEVAL(cx,n,fgv)                                             \
+    STMT_START {                                                       \
        cx->blk_eval.old_in_eval = PL_in_eval;                          \
        cx->blk_eval.old_op_type = PL_op->op_type;                      \
-       cx->blk_eval.old_name = (n ? savepv(n) : Nullch);               \
+       cx->blk_eval.old_namesv = (n ? newSVpv(n,0) : Nullsv);          \
        cx->blk_eval.old_eval_root = PL_eval_root;                      \
-       cx->blk_eval.cur_text = PL_linestr;
+       cx->blk_eval.cur_text = PL_linestr;                             \
+    } STMT_END
 
 #define POPEVAL(cx)                                                    \
+    STMT_START {                                                       \
        PL_in_eval = cx->blk_eval.old_in_eval;                          \
        optype = cx->blk_eval.old_op_type;                              \
        PL_eval_root = cx->blk_eval.old_eval_root;                      \
-       Safefree(cx->blk_eval.old_name);
+       if (cx->blk_eval.old_namesv)                                    \
+           sv_2mortal(cx->blk_eval.old_namesv);                        \
+    } STMT_END
 
 /* loop context */
 struct block_loop {
diff --git a/op.c b/op.c
index 8f3330c..e1d0dcd 100644 (file)
--- a/op.c
+++ b/op.c
@@ -3105,7 +3105,7 @@ Perl_utilize(pTHX_ int aver, I32 floor, OP *version, OP *id, OP *arg)
 
     veop = Nullop;
 
-    if(version != Nullop) {
+    if (version != Nullop) {
        SV *vesv = ((SVOP*)version)->op_sv;
 
        if (arg == Nullop && !SvNIOK(vesv)) {
@@ -3113,6 +3113,7 @@ Perl_utilize(pTHX_ int aver, I32 floor, OP *version, OP *id, OP *arg)
        }
        else {
            OP *pack;
+           SV *meth;
 
            if (version->op_type != OP_CONST || !SvNIOK(vesv))
                Perl_croak(aTHX_ "Version number must be constant number");
@@ -3121,29 +3122,38 @@ Perl_utilize(pTHX_ int aver, I32 floor, OP *version, OP *id, OP *arg)
            pack = newSVOP(OP_CONST, 0, newSVsv(((SVOP*)id)->op_sv));
 
            /* Fake up a method call to VERSION */
+           meth = newSVpvn("VERSION",7);
+           sv_upgrade(meth, SVt_PVIV);
+           SvIOK_on(meth);
+           PERL_HASH(SvUVX(meth), SvPVX(meth), SvCUR(meth));
            veop = convert(OP_ENTERSUB, OPf_STACKED|OPf_SPECIAL,
                            append_elem(OP_LIST,
-                           prepend_elem(OP_LIST, pack, list(version)),
-                           newSVOP(OP_METHOD_NAMED, 0,
-                                   newSVpvn("VERSION", 7))));
+                                       prepend_elem(OP_LIST, pack, list(version)),
+                                       newSVOP(OP_METHOD_NAMED, 0, meth)));
        }
     }
 
     /* Fake up an import/unimport */
     if (arg && arg->op_type == OP_STUB)
        imop = arg;             /* no import on explicit () */
-    else if(SvNIOK(((SVOP*)id)->op_sv)) {
+    else if (SvNIOK(((SVOP*)id)->op_sv)) {
        imop = Nullop;          /* use 5.0; */
     }
     else {
+       SV *meth;
+
        /* Make copy of id so we don't free it twice */
        pack = newSVOP(OP_CONST, 0, newSVsv(((SVOP*)id)->op_sv));
+
+       /* Fake up a method call to import/unimport */
+       meth = aver ? newSVpvn("import",6) : newSVpvn("unimport", 8);;
+       sv_upgrade(meth, SVt_PVIV);
+       SvIOK_on(meth);
+       PERL_HASH(SvUVX(meth), SvPVX(meth), SvCUR(meth));
        imop = convert(OP_ENTERSUB, OPf_STACKED|OPf_SPECIAL,
-                   append_elem(OP_LIST,
-                       prepend_elem(OP_LIST, pack, list(arg)),
-                       newSVOP(OP_METHOD_NAMED, 0,
-                               aver ? newSVpvn("import", 6)
-                                    : newSVpvn("unimport", 8))));
+                      append_elem(OP_LIST,
+                                  prepend_elem(OP_LIST, pack, list(arg)),
+                                  newSVOP(OP_METHOD_NAMED, 0, meth)));
     }
 
     /* Fake up a require, handle override, if any */
@@ -4247,10 +4257,10 @@ Perl_op_const_sv(pTHX_ OP *o, CV *cv)
 {
     SV *sv = Nullsv;
 
-    if(!o)
+    if (!o)
        return Nullsv;
  
-    if(o->op_type == OP_LINESEQ && cLISTOPo->op_first) 
+    if (o->op_type == OP_LINESEQ && cLISTOPo->op_first) 
        o = cLISTOPo->op_first->op_sibling;
 
     for (; o; o = o->op_next) {
@@ -4370,7 +4380,7 @@ Perl_newATTRSUB(pTHX_ I32 floor, OP *o, OP *proto, OP *attrs, OP *block)
                Perl_croak(aTHX_ "Can't redefine active sort subroutine %s", name);
            if (!block)
                goto withattrs;
-           if(const_sv = cv_const_sv(cv))
+           if (const_sv = cv_const_sv(cv))
                const_changed = sv_cmp(const_sv, op_const_sv(block, Nullcv));
            if ((const_sv && const_changed) || ckWARN(WARN_REDEFINE) 
                                        && !(CvGV(cv) && GvSTASH(CvGV(cv))
@@ -5956,7 +5966,7 @@ S_simplify_sort(pTHX_ OP *o)
        return;
     if (strEQ(GvNAME(gv), "a"))
        reversed = 0;
-    else if(strEQ(GvNAME(gv), "b"))
+    else if (strEQ(GvNAME(gv), "b"))
        reversed = 1;
     else
        return;
diff --git a/perl.c b/perl.c
index 1da8b0e..1891836 100644 (file)
--- a/perl.c
+++ b/perl.c
@@ -1452,13 +1452,13 @@ Perl_call_method(pTHX_ const char *methname, I32 flags)
 {
     dSP;
     OP myop;
-    if (!PL_op)
+    if (!PL_op) {
+       myop.op_next = Nullop;
        PL_op = &myop;
+    }
     XPUSHs(sv_2mortal(newSVpv(methname,0)));
     PUTBACK;
     pp_method();
-       if(PL_op == &myop)
-               PL_op = Nullop;
     return call_sv(*PL_stack_sp--, flags);
 }
 
index 7b4cbfe..030bcbd 100644 (file)
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -1526,10 +1526,10 @@ PP(pp_caller)
        if (cx->blk_eval.old_op_type == OP_ENTEREVAL) {
            PUSHs(cx->blk_eval.cur_text);
            PUSHs(&PL_sv_no);
-       } 
-       else if (cx->blk_eval.old_name) { /* Try blocks have old_name == 0. */
-           /* Require, put the name. */
-           PUSHs(sv_2mortal(newSVpv(cx->blk_eval.old_name, 0)));
+       }
+       /* try blocks have old_namesv == 0 */
+       else if (cx->blk_eval.old_namesv) {
+           PUSHs(sv_2mortal(newSVsv(cx->blk_eval.old_namesv)));
            PUSHs(&PL_sv_yes);
        }
     }
@@ -1813,9 +1813,9 @@ PP(pp_return)
            (MARK == SP || (gimme == G_SCALAR && !SvTRUE(*SP))) )
        {
            /* Unassume the success we assumed earlier. */
-           char *name = cx->blk_eval.old_name;
-           (void)hv_delete(GvHVn(PL_incgv), name, strlen(name), G_DISCARD);
-           DIE(aTHX_ "%s did not return a true value", name);
+           SV *nsv = cx->blk_eval.old_namesv;
+           (void)hv_delete(GvHVn(PL_incgv), SvPVX(nsv), SvCUR(nsv), G_DISCARD);
+           DIE(aTHX_ "%s did not return a true value", SvPVX(nsv));
        }
        break;
     case CXt_FORMAT:
@@ -3294,9 +3294,9 @@ PP(pp_leaveeval)
        !(gimme == G_SCALAR ? SvTRUE(*SP) : SP > newsp))
     {
        /* Unassume the success we assumed earlier. */
-       char *name = cx->blk_eval.old_name;
-       (void)hv_delete(GvHVn(PL_incgv), name, strlen(name), G_DISCARD);
-       retop = Perl_die(aTHX_ "%s did not return a true value", name);
+       SV *nsv = cx->blk_eval.old_namesv;
+       (void)hv_delete(GvHVn(PL_incgv), SvPVX(nsv), SvCUR(nsv), G_DISCARD);
+       retop = Perl_die(aTHX_ "%s did not return a true value", SvPVX(nsv));
        /* die_where() did LEAVE, or we won't be here */
     }
     else {
index 57a3bad..ca0b1d1 100644 (file)
--- a/regcomp.c
+++ b/regcomp.c
@@ -1388,6 +1388,10 @@ Perl_pregcomp(pTHX_ char *exp, char *xend, PMOP *pm)
         char, regexp);
     if (r == NULL)
        FAIL("regexp out of space");
+#ifdef DEBUGGING
+    /* avoid reading uninitialized memory in DEBUGGING code in study_chunk() */
+    Zero(r, sizeof(regexp) + (unsigned)PL_regsize * sizeof(regnode), char);
+#endif
     r->refcnt = 1;
     r->prelen = xend - exp;
     r->precomp = PL_regprecomp;
index 524313d..cef9887 100644 (file)
--- a/regexec.c
+++ b/regexec.c
@@ -1670,7 +1670,7 @@ S_regtry(pTHX_ regexp *prog, char *startpos)
            SAVEDESTRUCTOR_X(restore_pos, 0);
         }
        if (!PL_reg_curpm)
-           New(22,PL_reg_curpm, 1, PMOP);
+           Newz(22,PL_reg_curpm, 1, PMOP);
        PL_reg_curpm->op_pmregexp = prog;
        PL_reg_oldcurpm = PL_curpm;
        PL_curpm = PL_reg_curpm;
diff --git a/scope.c b/scope.c
index 0f56854..e6c3125 100644 (file)
--- a/scope.c
+++ b/scope.c
@@ -994,8 +994,9 @@ Perl_cx_dump(pTHX_ PERL_CONTEXT *cx)
        PerlIO_printf(Perl_debug_log, "BLK_EVAL.OLD_OP_TYPE = %s (%s)\n",
                PL_op_name[cx->blk_eval.old_op_type],
                PL_op_desc[cx->blk_eval.old_op_type]);
-       PerlIO_printf(Perl_debug_log, "BLK_EVAL.OLD_NAME = %s\n",
-               cx->blk_eval.old_name);
+       if (cx->blk_eval.old_namesv)
+           PerlIO_printf(Perl_debug_log, "BLK_EVAL.OLD_NAME = %s\n",
+                         SvPVX(cx->blk_eval.old_namesv));
        PerlIO_printf(Perl_debug_log, "BLK_EVAL.OLD_EVAL_ROOT = 0x%"UVxf"\n",
                PTR2UV(cx->blk_eval.old_eval_root));
        break;
diff --git a/sv.c b/sv.c
index 8e84946..ac24299 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -6884,7 +6884,7 @@ Perl_cx_dup(pTHX_ PERL_CONTEXT *cxs, I32 ix, I32 max)
            case CXt_EVAL:
                ncx->blk_eval.old_in_eval = cx->blk_eval.old_in_eval;
                ncx->blk_eval.old_op_type = cx->blk_eval.old_op_type;
-               ncx->blk_eval.old_name  = SAVEPV(cx->blk_eval.old_name);
+               ncx->blk_eval.old_namesv = sv_dup_inc(cx->blk_eval.old_namesv);
                ncx->blk_eval.old_eval_root = cx->blk_eval.old_eval_root;
                ncx->blk_eval.cur_text  = sv_dup(cx->blk_eval.cur_text);
                break;
diff --git a/util.c b/util.c
index 031922a..a63dd3f 100644 (file)
--- a/util.c
+++ b/util.c
@@ -1504,6 +1504,7 @@ Perl_vdie(pTHX_ const char* pat, va_list *args)
     }
     else {
        message = Nullch;
+       msglen = 0;
     }
 
     DEBUG_S(PerlIO_printf(Perl_debug_log,