const bool was_tainted = TAINT_get;
if (pm->op_flags & OPf_STACKED)
lhs = args[-1];
- else if (pm->op_private & OPpTARGET_MY)
+ else if (pm->op_targ)
lhs = PAD_SV(pm->op_targ);
else lhs = DEFSV;
SvGETMAGIC(lhs);
rxres_restore(&cx->sb_rxres, rx);
if (cx->sb_iters++) {
- const I32 saviters = cx->sb_iters;
+ const SSize_t saviters = cx->sb_iters;
if (cx->sb_iters > cx->sb_maxiters)
DIE(aTHX_ "Substitution loop");
POPSUBST(cx);
PERL_ASYNC_CHECK();
RETURNOP(pm->op_next);
- assert(0); /* NOTREACHED */
+ NOT_REACHED; /* NOTREACHED */
}
cx->sb_iters = saviters;
}
break;
}
itembytes = s - item;
+ chophere = s;
break;
}
goto append;
case FF_CHOP: /* (for ^*) chop the current item */
- {
+ if (sv != &PL_sv_no) {
const char *s = chophere;
if (chopspace) {
while (isSPACE(*s))
const char *const send = s + len;
item_is_utf8 = DO_UTF8(sv);
+ chophere = s + len;
if (!len)
break;
trans = 0;
gotsome = TRUE;
- chophere = s + len;
source = (U8 *) s;
to_copy = len;
while (s < send) {
PP(pp_range)
{
- if (GIMME == G_ARRAY)
+ if (GIMME_V == G_ARRAY)
return NORMAL;
if (SvTRUEx(PAD_SV(PL_op->op_targ)))
return cLOGOP->op_other;
{
dSP;
- if (GIMME == G_ARRAY) {
+ if (GIMME_V == G_ARRAY) {
RETURNOP(((LOGOP*)cUNOP->op_first)->op_other);
}
else {
{
dSP;
- if (GIMME == G_ARRAY) {
+ if (GIMME_V == G_ARRAY) {
dPOPPOPssrl;
SvGETMAGIC(left);
else
n = 0;
while (n--) {
- SV * const sv = sv_2mortal(newSViv(i++));
+ SV * const sv = sv_2mortal(newSViv(i));
PUSHs(sv);
+ if (n) /* avoid incrementing above IV_MAX */
+ i++;
}
}
else {
PL_restartjmpenv = restartjmpenv;
PL_restartop = restartop;
JMPENV_JUMP(3);
- assert(0); /* NOTREACHED */
+ NOT_REACHED; /* NOTREACHED */
}
}
write_to_stderr(exceptsv);
my_failure_exit();
- assert(0); /* NOTREACHED */
+ NOT_REACHED; /* NOTREACHED */
}
PP(pp_xor)
dSP;
const PERL_CONTEXT *cx;
const PERL_CONTEXT *dbcx;
- I32 gimme;
+ I32 gimme = GIMME_V;
const HEK *stash_hek;
I32 count = 0;
bool has_arg = MAXARG && TOPs;
cx = caller_cx(count + !!(PL_op->op_private & OPpOFFBYONE), &dbcx);
if (!cx) {
- if (GIMME != G_ARRAY) {
+ if (gimme != G_ARRAY) {
EXTEND(SP, 1);
RETPUSHUNDEF;
}
stash_hek = SvTYPE(CopSTASH(cx->blk_oldcop)) == SVt_PVHV
? HvNAME_HEK((HV*)CopSTASH(cx->blk_oldcop))
: NULL;
- if (GIMME != G_ARRAY) {
+ if (gimme != G_ARRAY) {
EXTEND(SP, 1);
if (!stash_hek)
PUSHs(&PL_sv_undef);
PUSHTARG;
}
mPUSHs(newSVpv(OutCopFILE(cx->blk_oldcop), 0));
- lcop = closest_cop(cx->blk_oldcop, OP_SIBLING(cx->blk_oldcop),
+ lcop = closest_cop(cx->blk_oldcop, OpSIBLING(cx->blk_oldcop),
cx->blk_sub.retop, TRUE);
if (!lcop)
lcop = cx->blk_oldcop;
RETURN;
}
+static bool
+S_outside_integer(pTHX_ SV *sv)
+{
+ if (SvOK(sv)) {
+ const NV nv = SvNV_nomg(sv);
+ if (Perl_isinfnan(nv))
+ return TRUE;
+#ifdef NV_PRESERVES_UV
+ if (nv < (NV)IV_MIN || nv > (NV)IV_MAX)
+ return TRUE;
+#else
+ if (nv <= (NV)IV_MIN)
+ return TRUE;
+ if ((nv > 0) &&
+ ((nv > (NV)UV_MAX ||
+ SvUV_nomg(sv) > (UV)IV_MAX)))
+ return TRUE;
+#endif
+ }
+ return FALSE;
+}
+
PP(pp_enteriter)
{
dSP; dMARK;
SvGETMAGIC(sv);
SvGETMAGIC(right);
if (RANGE_IS_NUMERIC(sv,right)) {
- NV nv;
cx->cx_type &= ~CXTYPEMASK;
cx->cx_type |= CXt_LOOP_LAZYIV;
/* Make sure that no-one re-orders cop.h and breaks our
assumptions */
assert(CxTYPE(cx) == CXt_LOOP_LAZYIV);
-#ifdef NV_PRESERVES_UV
- if ((SvOK(sv) && (((nv = SvNV_nomg(sv)) < (NV)IV_MIN) ||
- (nv > (NV)IV_MAX)))
- ||
- (SvOK(right) && (((nv = SvNV_nomg(right)) > (NV)IV_MAX) ||
- (nv < (NV)IV_MIN))))
-#else
- if ((SvOK(sv) && (((nv = SvNV_nomg(sv)) <= (NV)IV_MIN)
- ||
- ((nv > 0) &&
- ((nv > (NV)UV_MAX) ||
- (SvUV_nomg(sv) > (UV)IV_MAX)))))
- ||
- (SvOK(right) && (((nv = SvNV_nomg(right)) <= (NV)IV_MIN)
- ||
- ((nv > 0) &&
- ((nv > (NV)UV_MAX) ||
- (SvUV_nomg(right) > (UV)IV_MAX))
- ))))
-#endif
+ if (S_outside_integer(aTHX_ sv) ||
+ S_outside_integer(aTHX_ right))
DIE(aTHX_ "Range iterator outside integer range");
cx->blk_loop.state_u.lazyiv.cur = SvIV_nomg(sv);
cx->blk_loop.state_u.lazyiv.end = SvIV_nomg(right);
if (o->op_flags & OPf_KIDS) {
OP *kid;
/* First try all the kids at this level, since that's likeliest. */
- for (kid = cUNOPo->op_first; kid; kid = OP_SIBLING(kid)) {
+ for (kid = cUNOPo->op_first; kid; kid = OpSIBLING(kid)) {
if (kid->op_type == OP_NEXTSTATE || kid->op_type == OP_DBSTATE) {
STRLEN kid_label_len;
U32 kid_label_flags;
return kid;
}
}
- for (kid = cUNOPo->op_first; kid; kid = OP_SIBLING(kid)) {
+ for (kid = cUNOPo->op_first; kid; kid = OpSIBLING(kid)) {
if (kid == PL_lastgotoprobe)
continue;
if (kid->op_type == OP_NEXTSTATE || kid->op_type == OP_DBSTATE) {
SAVETMPS;
SAVEFREESV(cv); /* later, undo the 'avoid premature free' hack */
if (CvISXSUB(cv)) {
- OP* const retop = cx->blk_sub.retop;
SV **newsp;
I32 gimme;
const SSize_t items = arg ? AvFILL(arg) + 1 : 0;
SvREFCNT_dec(arg);
}
+ retop = cx->blk_sub.retop;
/* XS subs don't have a CxSUB, so pop it */
POPBLOCK(cx, PL_curpm);
/* Push a mark for the start of arglist */
PUTBACK;
(void)(*CvXSUB(cv))(aTHX_ cv);
LEAVE;
- PERL_ASYNC_CHECK();
- return retop;
+ goto _return;
}
else {
PADLIST * const padlist = CvPADLIST(cv);
}
}
}
- PERL_ASYNC_CHECK();
- RETURNOP(CvSTART(cv));
+ retop = CvSTART(cv);
+ goto putback_return;
}
}
else {
case CXt_LOOP_PLAIN:
case CXt_GIVEN:
case CXt_WHEN:
- gotoprobe = OP_SIBLING(cx->blk_oldcop);
+ gotoprobe = OpSIBLING(cx->blk_oldcop);
break;
case CXt_SUBST:
continue;
case CXt_BLOCK:
if (ix) {
- gotoprobe = OP_SIBLING(cx->blk_oldcop);
+ gotoprobe = OpSIBLING(cx->blk_oldcop);
in_block = TRUE;
} else
gotoprobe = PL_main_root;
enterops, enterops + GOTO_DEPTH);
if (retop)
break;
- if ( (sibl1 = OP_SIBLING(gotoprobe)) &&
+ if ( (sibl1 = OpSIBLING(gotoprobe)) &&
sibl1->op_type == OP_UNSTACK &&
- (sibl2 = OP_SIBLING(sibl1)))
+ (sibl2 = OpSIBLING(sibl1)))
{
retop = dofindlabel(sibl2,
label, label_len, label_flags, enterops,
PL_do_undump = FALSE;
}
+ putback_return:
+ PL_stack_sp = sp;
+ _return:
PERL_ASYNC_CHECK();
- RETURNOP(retop);
+ return retop;
}
PP(pp_exit)
JMPENV_POP;
PL_op = oldop;
JMPENV_JUMP(ret);
- assert(0); /* NOTREACHED */
+ NOT_REACHED; /* NOTREACHED */
}
JMPENV_POP;
PL_op = oldop;
switch (cond) {
case FIND_RUNCV_padid_eq:
if (!CvPADLIST(cv)
- || PadlistNAMES(CvPADLIST(cv)) != INT2PTR(PADNAMELIST *, arg))
+ || CvPADLIST(cv)->xpadl_id != (U32)arg)
continue;
return cv;
case FIND_RUNCV_level_eq:
default:
JMPENV_POP;
JMPENV_JUMP(ret);
- assert(0); /* NOTREACHED */
+ NOT_REACHED; /* NOTREACHED */
}
JMPENV_POP;
return ret;
{
Stat_t st;
STRLEN len;
+ PerlIO * retio;
const char *p = SvPV_const(name, len);
int st_rc;
if (!IS_SAFE_PATHNAME(p, len, "require"))
return NULL;
+ /* on Win32 stat is expensive (it does an open() and close() twice and
+ a couple other IO calls), the open will fail with a dir on its own with
+ errno EACCES, so only do a stat to separate a dir from a real EACCES
+ caused by user perms */
+#ifndef WIN32
/* we use the value of errno later to see how stat() or open() failed.
* We don't want it set if the stat succeeded but we still failed,
* such as if the name exists, but is a directory */
if (st_rc < 0 || S_ISDIR(st.st_mode) || S_ISBLK(st.st_mode)) {
return NULL;
}
+#endif
#if !defined(PERLIO_IS_STDIO)
- return PerlIO_openn(aTHX_ ":", PERL_SCRIPT_MODE, -1, 0, 0, NULL, 1, &name);
+ retio = PerlIO_openn(aTHX_ ":", PERL_SCRIPT_MODE, -1, 0, 0, NULL, 1, &name);
#else
- return PerlIO_open(p, PERL_SCRIPT_MODE);
+ retio = PerlIO_open(p, PERL_SCRIPT_MODE);
+#endif
+#ifdef WIN32
+ /* EACCES stops the INC search early in pp_require to implement
+ feature RT #113422 */
+ if(!retio && errno == EACCES) { /* exists but probably a directory */
+ int eno;
+ st_rc = PerlLIO_stat(p, &st);
+ if (st_rc >= 0) {
+ if(S_ISDIR(st.st_mode) || S_ISBLK(st.st_mode))
+ eno = 0;
+ else
+ eno = EACCES;
+ errno = eno;
+ }
+ }
#endif
+ return retio;
}
#ifndef PERL_DISABLE_PMC
#endif /* !PERL_DISABLE_PMC */
/* require doesn't search for absolute names, or when the name is
- explicity relative the current directory */
+ explicitly relative the current directory */
PERL_STATIC_INLINE bool
S_path_is_searchable(const char *name)
{
SV *filter_state = NULL;
SV *filter_sub = NULL;
SV *hook_sv = NULL;
- SV *encoding;
OP *op;
int saved_errno;
bool path_searchable;
if (PL_op->op_type == OP_REQUIRE) {
if(saved_errno == EMFILE || saved_errno == EACCES) {
/* diag_listed_as: Can't locate %s */
- DIE(aTHX_ "Can't locate %s: %s", name, Strerror(saved_errno));
+ DIE(aTHX_ "Can't locate %s: %s: %s",
+ name, tryname, Strerror(saved_errno));
} else {
if (namesv) { /* did we lookup @INC? */
AV * const ar = GvAVn(PL_incgv);
PUTBACK;
- /* Store and reset encoding. */
- encoding = PL_encoding;
- PL_encoding = NULL;
-
if (doeval(gimme, NULL, PL_curcop->cop_seq, NULL))
op = DOCATCH(PL_eval_start);
else
op = PL_op->op_next;
- /* Restore encoding. */
- PL_encoding = encoding;
-
LOADED_FILE_PROBE(unixname);
return op;
umaxlen = maxlen;
/* I was having segfault trouble under Linux 2.2.5 after a
- parse error occured. (Had to hack around it with a test
+ parse error occurred. (Had to hack around it with a test
for PL_parser->error_count == 0.) Solaris doesn't segfault --
not sure where the trouble is yet. XXX */