if (!(mg = mg_find_mglob(sv))) {
mg = sv_magicext_mglob(sv);
}
- mg->mg_len = m - orig;
+ assert(SvPOK(dstr));
+ MgBYTEPOS_set(mg, sv, SvPVX(dstr), m - orig);
}
if (old != rx)
(void)ReREFCNT_inc(rx);
itembytes = len;
send = chophere = s + itembytes;
while (s < send) {
- if (*s & ~31)
+ if (! isCNTRL(*s))
gotsome = TRUE;
else if (*s == '\n')
break;
itemsize = fieldsize;
send = chophere = s + itemsize;
while (s < send) {
- if (*s & ~31)
+ if (! isCNTRL(*s))
gotsome = TRUE;
else if (*s == '\n')
break;
chophere = s;
break;
}
- if (*s++ & ~31)
+ if (! isCNTRL(*s))
gotsome = TRUE;
+ s++;
}
}
else {
break;
}
else {
- if (*s & ~31)
+ if (! isCNTRL(*s))
gotsome = TRUE;
if (strchr(PL_chopset, *s))
chophere = s + 1;
chophere = s;
break;
}
- if (*s++ & ~31)
+ if (! isCNTRL(*s))
gotsome = TRUE;
+ s++;
}
}
else {
break;
}
else {
- if (*s & ~31)
+ if (! isCNTRL(*s))
gotsome = TRUE;
if (strchr(PL_chopset, *s))
chophere = s + 1;
U8 *send = s + to_copy;
while (s < send) {
const int ch = *s;
- if (trans == '~' ? (ch == '~') :
-#ifdef EBCDIC
- iscntrl(ch)
-#else
- (!(ch & ~31))
-#endif
- )
+ if (trans == '~' ? (ch == '~') : isCNTRL(ch))
*s = ' ';
s++;
}
if (RANGE_IS_NUMERIC(left,right)) {
IV i, j;
IV max;
- if ((SvOK(left) && SvNV_nomg(left) < IV_MIN) ||
- (SvOK(right) && SvNV_nomg(right) > IV_MAX))
+ if ((SvOK(left) && !SvIOK(left) && SvNV_nomg(left) < IV_MIN) ||
+ (SvOK(right) && (SvIOK(right)
+ ? SvIsUV(right) && SvUV(right) > IV_MAX
+ : SvNV_nomg(right) > IV_MAX)))
DIE(aTHX_ "Range iterator outside integer range");
i = SvIV_nomg(left);
max = SvIV_nomg(right);
if (max >= i) {
j = max - i + 1;
+ if (j > SSize_t_MAX)
+ Perl_croak(aTHX_ "Out of memory during list extend");
EXTEND_MORTAL(j);
EXTEND(SP, j);
}
const HEK *stash_hek;
I32 count = 0;
bool has_arg = MAXARG && TOPs;
+ const COP *lcop;
if (MAXARG) {
if (has_arg)
PUSHTARG;
}
mPUSHs(newSVpv(OutCopFILE(cx->blk_oldcop), 0));
- mPUSHi((I32)CopLINE(cx->blk_oldcop));
+ lcop = closest_cop(cx->blk_oldcop, cx->blk_oldcop->op_sibling,
+ cx->blk_sub.retop, TRUE);
+ if (!lcop)
+ lcop = cx->blk_oldcop;
+ mPUSHi((I32)CopLINE(lcop));
if (!has_arg)
RETURN;
if (CxTYPE(cx) == CXt_SUB || CxTYPE(cx) == CXt_FORMAT) {
&& CopSTASH_eq(PL_curcop, PL_debstash))
{
AV * const ary = cx->blk_sub.argarray;
- const int off = AvARRAY(ary) - AvALLOC(ary);
+ const SSize_t off = AvARRAY(ary) - AvALLOC(ary);
Perl_init_dbargs(aTHX);
}
break;
case CXt_FORMAT:
- POPFORMAT(cx);
retop = cx->blk_sub.retop;
+ POPFORMAT(cx);
break;
default:
DIE(aTHX_ "panic: return, type=%u", (unsigned) CxTYPE(cx));
S_return_lvalues(aTHX_ newsp, SP, newsp, gimme, cx, newpm);
LEAVE;
- cxstack_ix--;
POPSUB(cx,sv); /* Stack values are safe: release CV and @_ ... */
+ cxstack_ix--;
PL_curpm = newpm; /* ... and pop $1 et al */
LEAVESUB(sv);
return 0;
}
-PP(pp_goto)
+PP(pp_goto) /* also pp_dump */
{
dVAR; dSP;
OP *retop = NULL;
static const char* const must_have_label = "goto must have label";
if (PL_op->op_flags & OPf_STACKED) {
+ /* goto EXPR or goto &foo */
+
SV * const sv = POPs;
SvGETMAGIC(sv);
OP* const retop = cx->blk_sub.retop;
SV **newsp;
I32 gimme;
- const SSize_t items = AvFILLp(arg) + 1;
+ const SSize_t items = arg ? AvFILLp(arg) + 1 : 0;
SV** mark;
PERL_UNUSED_VAR(newsp);
PERL_UNUSED_VAR(gimme);
/* put GvAV(defgv) back onto stack */
- EXTEND(SP, items+1); /* @_ could have been extended. */
- Copy(AvARRAY(arg), SP + 1, items, SV*);
+ if (items) {
+ EXTEND(SP, items+1); /* @_ could have been extended. */
+ Copy(AvARRAY(arg), SP + 1, items, SV*);
+ }
mark = SP;
SP += items;
- if (AvREAL(arg)) {
- I32 index;
+ if (items && AvREAL(arg)) {
+ SSize_t index;
for (index=0; index<items; index++)
- SvREFCNT_inc_void(sv_2mortal(SP[-index]));
+ if (SP[-index])
+ SvREFCNT_inc_void_NN(sv_2mortal(SP[-index]));
+ else {
+ SP[-index] = sv_2mortal(newSVavdefelem(arg,
+ AvFILLp(arg) - index, 1));
+ }
}
SvREFCNT_dec(arg);
if (CxTYPE(cx) == CXt_SUB && CxHASARGS(cx)) {
}
}
else {
+ /* goto EXPR */
label = SvPV_nomg_const(sv, label_len);
label_flags = SvUTF8(sv);
}
}
else if (!(PL_op->op_flags & OPf_SPECIAL)) {
+ /* goto LABEL or dump LABEL */
label = cPVOP->op_pv;
label_flags = (cPVOP->op_private & OPpPV_IS_UTF8) ? SVf_UTF8 : 0;
label_len = strlen(label);
{
Stat_t st;
const char *p = SvPV_nolen_const(name);
- const int st_rc = PerlLIO_stat(p, &st);
+ int st_rc;
PERL_ARGS_ASSERT_CHECK_TYPE_AND_OPEN;
+ /* checking here captures a reasonable error message when
+ * PERL_DISABLE_PMC is true, but when PMC checks are enabled, the
+ * user gets a confusing message about looking for the .pmc file
+ * rather than for the .pm file.
+ * This check prevents a \0 in @INC causing problems.
+ */
+ if (!IS_SAFE_PATHNAME(name, "require"))
+ return NULL;
+
+ st_rc = PerlLIO_stat(p, &st);
+
if (st_rc < 0 || S_ISDIR(st.st_mode) || S_ISBLK(st.st_mode)) {
return NULL;
}
PERL_ARGS_ASSERT_DOOPEN_PM;
+ /* check the name before trying for the .pmc name to avoid the
+ * warning referring to the .pmc which the user probably doesn't
+ * know or care about
+ */
+ if (!IS_SAFE_PATHNAME(name, "require"))
+ return NULL;
+
if (namelen > 3 && memEQs(p + namelen - 3, 3, ".pm")) {
SV *const pmcsv = sv_newmortal();
Stat_t pmcstat;
name = SvPV_const(sv, len);
if (!(name && len > 0 && *name))
DIE(aTHX_ "Null filename used");
+ if (!IS_SAFE_PATHNAME(sv, "require")) {
+ DIE(aTHX_ "Can't locate %s: %s",
+ pv_escape(newSVpvs_flags("",SVs_TEMP),SvPVX(sv),SvCUR(sv),
+ SvCUR(sv)*2,NULL, SvUTF8(sv)?PERL_PV_ESCAPE_UNI:0),
+ Strerror(ENOENT));
+ }
TAINT_PROPER("require");
path_searchable = path_is_searchable(name);
}
if (!tryrsfp && !(errno == EACCES && !path_searchable)) {
AV * const ar = GvAVn(PL_incgv);
- I32 i;
+ SSize_t i;
#ifdef VMS
if (vms_unixname)
#endif
} else {
if (namesv) { /* did we lookup @INC? */
AV * const ar = GvAVn(PL_incgv);
- I32 i;
+ SSize_t i;
SV *const msg = newSVpvs_flags("", SVs_TEMP);
SV *const inc = newSVpvs_flags("", SVs_TEMP);
for (i = 0; i <= AvFILL(ar); i++) {
}
else if (SvROK(d) && SvTYPE(SvRV(d)) == SVt_PVAV) {
/* Test sub truth for each element */
- I32 i;
+ SSize_t i;
bool andedresults = TRUE;
AV *av = (AV*) SvRV(d);
const I32 len = av_len(av);
}
else if (SvROK(d) && SvTYPE(SvRV(d)) == SVt_PVAV) {
AV * const other_av = MUTABLE_AV(SvRV(d));
- const I32 other_len = av_len(other_av) + 1;
- I32 i;
+ const SSize_t other_len = av_len(other_av) + 1;
+ SSize_t i;
HV *hv = MUTABLE_HV(SvRV(e));
DEBUG_M(Perl_deb(aTHX_ " applying rule Array-Hash\n"));
}
else if (SvROK(d) && SvTYPE(SvRV(d)) == SVt_PVHV) {
AV * const other_av = MUTABLE_AV(SvRV(e));
- const I32 other_len = av_len(other_av) + 1;
- I32 i;
+ const SSize_t other_len = av_len(other_av) + 1;
+ SSize_t i;
DEBUG_M(Perl_deb(aTHX_ " applying rule Hash-Array\n"));
for (i = 0; i < other_len; ++i) {
if (av_len(MUTABLE_AV(SvRV(e))) != av_len(other_av))
RETPUSHNO;
else {
- I32 i;
- const I32 other_len = av_len(other_av);
+ SSize_t i;
+ const SSize_t other_len = av_len(other_av);
if (NULL == seen_this) {
seen_this = newHV();
sm_regex_array:
{
PMOP * const matcher = make_matcher((REGEXP*) SvRV(d));
- const I32 this_len = av_len(MUTABLE_AV(SvRV(e)));
- I32 i;
+ const SSize_t this_len = av_len(MUTABLE_AV(SvRV(e)));
+ SSize_t i;
for(i = 0; i <= this_len; ++i) {
SV * const * const svp = av_fetch(MUTABLE_AV(SvRV(e)), i, FALSE);
}
else if (!SvOK(d)) {
/* undef ~~ array */
- const I32 this_len = av_len(MUTABLE_AV(SvRV(e)));
- I32 i;
+ const SSize_t this_len = av_len(MUTABLE_AV(SvRV(e)));
+ SSize_t i;
DEBUG_M(Perl_deb(aTHX_ " applying rule Undef-Array\n"));
for (i = 0; i <= this_len; ++i) {
else {
sm_any_array:
{
- I32 i;
- const I32 this_len = av_len(MUTABLE_AV(SvRV(e)));
+ SSize_t i;
+ const SSize_t this_len = av_len(MUTABLE_AV(SvRV(e)));
DEBUG_M(Perl_deb(aTHX_ " applying rule Any-Array\n"));
for (i = 0; i <= this_len; ++i) {
if (count > 0) {
SV *out = POPs;
+ SvGETMAGIC(out);
if (SvOK(out)) {
status = SvIV(out);
}
LEAVE_with_name("call_filter_sub");
}
+ if (SvGMAGICAL(upstream)) {
+ mg_get(upstream);
+ if (upstream == buf_sv) mg_free(buf_sv);
+ }
if (SvIsCOW(upstream)) sv_force_normal(upstream);
if(!err && SvOK(upstream)) {
- got_p = SvPV(upstream, got_len);
+ got_p = SvPV_nomg(upstream, got_len);
if (umaxlen) {
if (got_len > umaxlen) {
prune_from = got_p + umaxlen;
if (SvUTF8(upstream)) {
SvUTF8_on(cache);
}
- SvCUR_set(upstream, got_len - cached_len);
+ if (SvPOK(upstream)) SvCUR_set(upstream, got_len - cached_len);
+ else
+ /* Cannot just use sv_setpvn, as that could free the buffer
+ before we have a chance to assign it. */
+ sv_usepvn(upstream, savepvn(got_p, got_len - cached_len),
+ got_len - cached_len);
*prune_from = 0;
/* Can't yet be EOF */
if (status == 0)
concatenate it then we get a warning about use of uninitialised value.
*/
if (!err && upstream != buf_sv &&
- (SvOK(upstream) || SvGMAGICAL(upstream))) {
- sv_catsv(buf_sv, upstream);
+ SvOK(upstream)) {
+ sv_catsv_nomg(buf_sv, upstream);
}
else if (SvOK(upstream)) (void)SvPV_force_nolen(buf_sv);