summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGurusamy Sarathy <gsar@cpan.org>2000-02-13 19:02:07 +0000
committerGurusamy Sarathy <gsar@cpan.org>2000-02-13 19:02:07 +0000
commit0f79a09d62eb410185d697430134f937ab4e917d (patch)
tree79a361d65e09a6a28c1ab478935463a3d36adb2e
parent8ecf71871febb31312d723e89648aadebf858ae1 (diff)
downloadperl-0f79a09d62eb410185d697430134f937ab4e917d.tar.gz
more purification (pp_require() could access free memory; vdie()
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
-rw-r--r--cop.h13
-rw-r--r--op.c38
-rw-r--r--perl.c6
-rw-r--r--pp_ctl.c20
-rw-r--r--regcomp.c4
-rw-r--r--regexec.c2
-rw-r--r--scope.c5
-rw-r--r--sv.c2
-rw-r--r--util.c1
9 files changed, 56 insertions, 35 deletions
diff --git a/cop.h b/cop.h
index 734d2ea068..cfa6f4851c 100644
--- 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 8f3330cd25..e1d0dcdfd9 100644
--- 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 1da8b0ed43..189183647e 100644
--- 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);
}
diff --git a/pp_ctl.c b/pp_ctl.c
index 7b4cbfea49..030bcbd166 100644
--- 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 {
diff --git a/regcomp.c b/regcomp.c
index 57a3bad9b8..ca0b1d10d3 100644
--- 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;
diff --git a/regexec.c b/regexec.c
index 524313d570..cef98878f9 100644
--- 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 0f568543ba..e6c31259ec 100644
--- 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 8e8494641c..ac242996dc 100644
--- 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 031922a9f9..a63dd3ffe8 100644
--- 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,