PERL_ARGS_ASSERT_MG_GET;
+ if (PL_localizing == 1 && sv == DEFSV) return 0;
+
save_magic(mgs_ix, sv);
/* We must call svt_get(sv, mg) for each valid entry in the linked
PERL_ARGS_ASSERT_MG_SET;
+ if (PL_localizing == 2 && sv == DEFSV) return 0;
+
save_magic(mgs_ix, sv);
for (mg = SvMAGIC(sv); mg; mg = nextmg) {
(SSPTR(mgs_ix, MGS*))->mgs_magical = 0;
}
if (PL_localizing == 2
- && (PERL_MAGIC_TYPE_IS_VALUE_MAGIC(mg->mg_type) || sv == DEFSV))
+ && PERL_MAGIC_TYPE_IS_VALUE_MAGIC(mg->mg_type))
continue;
if (vtbl && vtbl->svt_set)
vtbl->svt_set(aTHX_ sv, mg);
}
}
+#ifdef VMS
+#include <descrip.h>
+#include <starlet.h>
+#endif
+
int
Perl_magic_get(pTHX_ SV *sv, MAGIC *mg)
{
if (nextchar == '\0') {
#if defined(VMS)
{
-# include <descrip.h>
-# include <starlet.h>
char msg[255];
$DESCRIPTOR(msgdsc,msg);
sv_setnv(sv,(NV) vaxc$errno);
sv_setpvn(sv, WARN_NONEstring, WARNsize) ;
}
else if (PL_compiling.cop_warnings == pWARN_STD) {
- sv_setpvn(
- sv,
- (PL_dowarn & G_WARN_ON) ? WARN_ALLstring : WARN_NONEstring,
- WARNsize
- );
+ sv_setsv(sv, &PL_sv_undef);
+ break;
}
else if (PL_compiling.cop_warnings == pWARN_ALL) {
/* Get the bit mask for $warnings::Bits{all}, because
case '$': /* $$ */
{
IV const pid = (IV)PerlProc_getpid();
- if (isGV(mg->mg_obj) || SvIV(mg->mg_obj) != pid)
+ if (isGV(mg->mg_obj) || SvIV(mg->mg_obj) != pid) {
/* never set manually, or at least not since last fork */
sv_setiv(sv, pid);
+ /* never unsafe, even if reading in a tainted expression */
+ SvTAINTED_off(sv);
+ }
/* else a value has been assigned manually, so do nothing */
}
break;
SvNOK_on(sv); /* what a wonderful hack! */
break;
case '<':
- sv_setiv(sv, (IV)PL_uid);
+ sv_setiv(sv, (IV)PerlProc_getuid());
break;
case '>':
- sv_setiv(sv, (IV)PL_euid);
+ sv_setiv(sv, (IV)PerlProc_geteuid());
break;
case '(':
- sv_setiv(sv, (IV)PL_gid);
+ sv_setiv(sv, (IV)PerlProc_getgid());
goto add_groups;
case ')':
- sv_setiv(sv, (IV)PL_egid);
+ sv_setiv(sv, (IV)PerlProc_getegid());
add_groups:
#ifdef HAS_GETGROUPS
{
}
int
-Perl_magic_setamagic(pTHX_ SV *sv, MAGIC *mg)
-{
- dVAR;
- PERL_ARGS_ASSERT_MAGIC_SETAMAGIC;
- PERL_UNUSED_ARG(sv);
- PERL_UNUSED_ARG(mg);
- PL_amagic_generation++;
-
- return 0;
-}
-
-int
Perl_magic_getnkeys(pTHX_ SV *sv, MAGIC *mg)
{
HV * const hv = MUTABLE_HV(LvTARG(sv));
{
PERL_ARGS_ASSERT_MAGIC_CLEARPACK;
+ if (mg->mg_type == PERL_MAGIC_tiedscalar) return 0;
return magic_methpack(sv,mg,"DELETE");
}
}
int
+Perl_magic_cleararylen_p(pTHX_ SV *sv, MAGIC *mg)
+{
+ dVAR;
+
+ PERL_ARGS_ASSERT_MAGIC_CLEARARYLEN_P;
+ PERL_UNUSED_ARG(sv);
+
+ /* Reset the iterator when the array is cleared */
+#if IVSIZE == I32SIZE
+ *((IV *) &(mg->mg_len)) = 0;
+#else
+ if (mg->mg_ptr)
+ *((IV *) mg->mg_ptr) = 0;
+#endif
+
+ return 0;
+}
+
+int
Perl_magic_freearylen_p(pTHX_ SV *sv, MAGIC *mg)
{
dVAR;
const char * const tmps = SvPV_const(lsv,len);
STRLEN offs = LvTARGOFF(sv);
STRLEN rem = LvTARGLEN(sv);
+ const bool negoff = LvFLAGS(sv) & 1;
+ const bool negrem = LvFLAGS(sv) & 2;
PERL_ARGS_ASSERT_MAGIC_GETSUBSTR;
PERL_UNUSED_ARG(mg);
+ if (!translate_substr_offsets(
+ SvUTF8(lsv) ? sv_len_utf8(lsv) : len,
+ negoff ? -(IV)offs : (IV)offs, !negoff,
+ negrem ? -(IV)rem : (IV)rem, !negrem, &offs, &rem
+ )) {
+ Perl_ck_warner(aTHX_ packWARN(WARN_SUBSTR), "substr outside of string");
+ sv_setsv_nomg(sv, &PL_sv_undef);
+ return 0;
+ }
+
if (SvUTF8(lsv))
offs = sv_pos_u2b_flags(lsv, offs, &rem, SV_CONST_RETURN);
- if (offs > len)
- offs = len;
- if (rem > len - offs)
- rem = len - offs;
sv_setpvn(sv, tmps + offs, rem);
if (SvUTF8(lsv))
SvUTF8_on(sv);
Perl_magic_setsubstr(pTHX_ SV *sv, MAGIC *mg)
{
dVAR;
- STRLEN len;
+ STRLEN len, lsv_len, oldtarglen, newtarglen;
const char * const tmps = SvPV_const(sv, len);
SV * const lsv = LvTARG(sv);
STRLEN lvoff = LvTARGOFF(sv);
STRLEN lvlen = LvTARGLEN(sv);
+ const bool negoff = LvFLAGS(sv) & 1;
+ const bool neglen = LvFLAGS(sv) & 2;
PERL_ARGS_ASSERT_MAGIC_SETSUBSTR;
PERL_UNUSED_ARG(mg);
+ SvGETMAGIC(lsv);
+ if (SvROK(lsv))
+ Perl_ck_warner(aTHX_ packWARN(WARN_SUBSTR),
+ "Attempt to use reference as lvalue in substr"
+ );
+ if (SvUTF8(lsv)) lsv_len = sv_len_utf8(lsv);
+ else (void)SvPV_nomg(lsv,lsv_len);
+ if (!translate_substr_offsets(
+ lsv_len,
+ negoff ? -(IV)lvoff : (IV)lvoff, !negoff,
+ neglen ? -(IV)lvlen : (IV)lvlen, !neglen, &lvoff, &lvlen
+ ))
+ Perl_croak(aTHX_ "substr outside of string");
+ oldtarglen = lvlen;
if (DO_UTF8(sv)) {
sv_utf8_upgrade(lsv);
lvoff = sv_pos_u2b_flags(lsv, lvoff, &lvlen, SV_CONST_RETURN);
- sv_insert(lsv, lvoff, lvlen, tmps, len);
- LvTARGLEN(sv) = sv_len_utf8(sv);
+ sv_insert_flags(lsv, lvoff, lvlen, tmps, len, 0);
+ newtarglen = sv_len_utf8(sv);
SvUTF8_on(lsv);
}
else if (lsv && SvUTF8(lsv)) {
const char *utf8;
lvoff = sv_pos_u2b_flags(lsv, lvoff, &lvlen, SV_CONST_RETURN);
- LvTARGLEN(sv) = len;
+ newtarglen = len;
utf8 = (char*)bytes_to_utf8((U8*)tmps, &len);
- sv_insert(lsv, lvoff, lvlen, utf8, len);
+ sv_insert_flags(lsv, lvoff, lvlen, utf8, len, 0);
Safefree(utf8);
}
else {
- sv_insert(lsv, lvoff, lvlen, tmps, len);
- LvTARGLEN(sv) = len;
+ sv_insert_flags(lsv, lvoff, lvlen, tmps, len, 0);
+ newtarglen = len;
}
+ if (!neglen) LvTARGLEN(sv) = newtarglen;
+ if (negoff) LvTARGOFF(sv) += newtarglen - oldtarglen;
return 0;
}
}
int
+Perl_magic_setvstring(pTHX_ SV *sv, MAGIC *mg)
+{
+ PERL_ARGS_ASSERT_MAGIC_SETVSTRING;
+
+ if (SvPOKp(sv)) {
+ SV * const vecsv = sv_newmortal();
+ scan_vstring(mg->mg_ptr, mg->mg_ptr + mg->mg_len, vecsv);
+ if (sv_eq_flags(vecsv, sv, 0 /*nomg*/)) return 0;
+ }
+ return sv_unmagic(sv, mg->mg_type);
+}
+
+int
Perl_magic_getdefelem(pTHX_ SV *sv, MAGIC *mg)
{
dVAR;
} else if (type == PERL_MAGIC_bm) {
SvTAIL_off(sv);
SvVALID_off(sv);
- } else if (type == PERL_MAGIC_study) {
- if (!isGV_with_GP(sv))
- SvSCREAM_off(sv);
} else {
assert(type == PERL_MAGIC_fm);
}
paren = atoi(mg->mg_ptr);
setparen:
if (PL_curpm && (rx = PM_GETRE(PL_curpm))) {
+ setparen_got_rx:
CALLREG_NUMBUF_STORE((REGEXP * const)rx,paren,sv);
} else {
/* Croak with a READONLY error when a numbered match var is
* set without a previous pattern match. Unless it's C<local $1>
*/
+ croakparen:
if (!PL_localizing) {
Perl_croak_no_modify(aTHX);
}
Safefree(PL_inplace);
PL_inplace = SvOK(sv) ? savesvpv(sv) : NULL;
break;
+ case '\016': /* ^N */
+ if (PL_curpm && (rx = PM_GETRE(PL_curpm))
+ && (paren = RX_LASTCLOSEPAREN(rx))) goto setparen_got_rx;
+ goto croakparen;
case '\017': /* ^O */
if (*(mg->mg_ptr+1) == '\0') {
Safefree(PL_osname);
}
else if (strEQ(mg->mg_ptr+1, "ARNING_BITS")) {
if ( ! (PL_dowarn & G_WARN_ALL_MASK)) {
- if (!SvPOK(sv) && PL_localizing) {
- sv_setpvn(sv, WARN_NONEstring, WARNsize);
- PL_compiling.cop_warnings = pWARN_NONE;
+ if (!SvPOK(sv)) {
+ PL_compiling.cop_warnings = pWARN_STD;
break;
}
{
}
break;
case '<':
- PL_uid = SvIV(sv);
+ {
+ const IV new_uid = SvIV(sv);
+ PL_delaymagic_uid = new_uid;
if (PL_delaymagic) {
PL_delaymagic |= DM_RUID;
break; /* don't do magic till later */
}
#ifdef HAS_SETRUID
- (void)setruid((Uid_t)PL_uid);
+ (void)setruid((Uid_t)new_uid);
#else
#ifdef HAS_SETREUID
- (void)setreuid((Uid_t)PL_uid, (Uid_t)-1);
+ (void)setreuid((Uid_t)new_uid, (Uid_t)-1);
#else
#ifdef HAS_SETRESUID
- (void)setresuid((Uid_t)PL_uid, (Uid_t)-1, (Uid_t)-1);
+ (void)setresuid((Uid_t)new_uid, (Uid_t)-1, (Uid_t)-1);
#else
- if (PL_uid == PL_euid) { /* special case $< = $> */
+ if (new_uid == PerlProc_geteuid()) { /* special case $< = $> */
#ifdef PERL_DARWIN
/* workaround for Darwin's setuid peculiarity, cf [perl #24122] */
- if (PL_uid != 0 && PerlProc_getuid() == 0)
+ if (new_uid != 0 && PerlProc_getuid() == 0)
(void)PerlProc_setuid(0);
#endif
- (void)PerlProc_setuid(PL_uid);
+ (void)PerlProc_setuid(new_uid);
} else {
- PL_uid = PerlProc_getuid();
Perl_croak(aTHX_ "setruid() not implemented");
}
#endif
#endif
#endif
- PL_uid = PerlProc_getuid();
break;
+ }
case '>':
- PL_euid = SvIV(sv);
+ {
+ const UV new_euid = SvIV(sv);
+ PL_delaymagic_euid = new_euid;
if (PL_delaymagic) {
PL_delaymagic |= DM_EUID;
break; /* don't do magic till later */
}
#ifdef HAS_SETEUID
- (void)seteuid((Uid_t)PL_euid);
+ (void)seteuid((Uid_t)new_euid);
#else
#ifdef HAS_SETREUID
- (void)setreuid((Uid_t)-1, (Uid_t)PL_euid);
+ (void)setreuid((Uid_t)-1, (Uid_t)new_euid);
#else
#ifdef HAS_SETRESUID
- (void)setresuid((Uid_t)-1, (Uid_t)PL_euid, (Uid_t)-1);
+ (void)setresuid((Uid_t)-1, (Uid_t)new_euid, (Uid_t)-1);
#else
- if (PL_euid == PL_uid) /* special case $> = $< */
- PerlProc_setuid(PL_euid);
+ if (new_euid == PerlProc_getuid()) /* special case $> = $< */
+ PerlProc_setuid(new_euid);
else {
- PL_euid = PerlProc_geteuid();
Perl_croak(aTHX_ "seteuid() not implemented");
}
#endif
#endif
#endif
- PL_euid = PerlProc_geteuid();
break;
+ }
case '(':
- PL_gid = SvIV(sv);
+ {
+ const UV new_gid = SvIV(sv);
+ PL_delaymagic_gid = new_gid;
if (PL_delaymagic) {
PL_delaymagic |= DM_RGID;
break; /* don't do magic till later */
}
#ifdef HAS_SETRGID
- (void)setrgid((Gid_t)PL_gid);
+ (void)setrgid((Gid_t)new_gid);
#else
#ifdef HAS_SETREGID
- (void)setregid((Gid_t)PL_gid, (Gid_t)-1);
+ (void)setregid((Gid_t)new_gid, (Gid_t)-1);
#else
#ifdef HAS_SETRESGID
- (void)setresgid((Gid_t)PL_gid, (Gid_t)-1, (Gid_t) 1);
+ (void)setresgid((Gid_t)new_gid, (Gid_t)-1, (Gid_t) -1);
#else
- if (PL_gid == PL_egid) /* special case $( = $) */
- (void)PerlProc_setgid(PL_gid);
+ if (new_gid == PerlProc_getegid()) /* special case $( = $) */
+ (void)PerlProc_setgid(new_gid);
else {
- PL_gid = PerlProc_getgid();
Perl_croak(aTHX_ "setrgid() not implemented");
}
#endif
#endif
#endif
- PL_gid = PerlProc_getgid();
break;
+ }
case ')':
+ {
+ UV new_egid;
#ifdef HAS_SETGROUPS
{
const char *p = SvPV_const(sv, len);
while (isSPACE(*p))
++p;
- PL_egid = Atol(p);
+ new_egid = Atol(p);
for (i = 0; i < maxgrp; ++i) {
while (*p && !isSPACE(*p))
++p;
Safefree(gary);
}
#else /* HAS_SETGROUPS */
- PL_egid = SvIV(sv);
+ new_egid = SvIV(sv);
#endif /* HAS_SETGROUPS */
+ PL_delaymagic_egid = new_egid;
if (PL_delaymagic) {
PL_delaymagic |= DM_EGID;
break; /* don't do magic till later */
}
#ifdef HAS_SETEGID
- (void)setegid((Gid_t)PL_egid);
+ (void)setegid((Gid_t)new_egid);
#else
#ifdef HAS_SETREGID
- (void)setregid((Gid_t)-1, (Gid_t)PL_egid);
+ (void)setregid((Gid_t)-1, (Gid_t)new_egid);
#else
#ifdef HAS_SETRESGID
- (void)setresgid((Gid_t)-1, (Gid_t)PL_egid, (Gid_t)-1);
+ (void)setresgid((Gid_t)-1, (Gid_t)new_egid, (Gid_t)-1);
#else
- if (PL_egid == PL_gid) /* special case $) = $( */
- (void)PerlProc_setgid(PL_egid);
+ if (new_egid == PerlProc_getgid()) /* special case $) = $( */
+ (void)PerlProc_setgid(new_egid);
else {
- PL_egid = PerlProc_getegid();
Perl_croak(aTHX_ "setegid() not implemented");
}
#endif
#endif
#endif
- PL_egid = PerlProc_getegid();
break;
+ }
case ':':
PL_chopset = SvPV_force(sv,len);
break;
U32 flags = 0;
XPV * const tXpv = PL_Xpv;
I32 old_ss_ix = PL_savestack_ix;
+ SV *errsv_save = NULL;
if (!PL_psig_ptr[sig]) {
#endif
PUTBACK;
+ errsv_save = newSVsv(ERRSV);
+
call_sv(MUTABLE_SV(cv), G_DISCARD|G_EVAL);
POPSTACK;
if (SvTRUE(ERRSV)) {
+ SvREFCNT_dec(errsv_save);
#ifndef PERL_MICRO
/* Handler "died", for example to get out of a restart-able read().
* Before we re-do that on its behalf re-enable the signal which was
#endif /* !PERL_MICRO */
die_sv(ERRSV);
}
+ else {
+ sv_setsv(ERRSV, errsv_save);
+ SvREFCNT_dec(errsv_save);
+ }
+
cleanup:
/* pop any of SAVEFREESV, SAVEDESTRUCTOR_X and "save in progress" */
PL_savestack_ix = old_ss_ix;
PERL_ARGS_ASSERT_MAGIC_CLEARHINT;
PERL_UNUSED_ARG(sv);
- assert(mg->mg_len == HEf_SVKEY);
-
- PERL_UNUSED_ARG(sv);
-
PL_hints |= HINT_LOCALIZE_HH;
CopHINTHASH_set(&PL_compiling,
- cophh_delete_sv(CopHINTHASH_get(&PL_compiling),
- MUTABLE_SV(mg->mg_ptr), 0, 0));
+ mg->mg_len == HEf_SVKEY
+ ? cophh_delete_sv(CopHINTHASH_get(&PL_compiling),
+ MUTABLE_SV(mg->mg_ptr), 0, 0)
+ : cophh_delete_pvn(CopHINTHASH_get(&PL_compiling),
+ mg->mg_ptr, mg->mg_len, 0, 0));
return 0;
}
return 0;
}
+int
+Perl_magic_copycallchecker(pTHX_ SV *sv, MAGIC *mg, SV *nsv,
+ const char *name, I32 namlen)
+{
+ MAGIC *nmg;
+
+ PERL_ARGS_ASSERT_MAGIC_COPYCALLCHECKER;
+ PERL_UNUSED_ARG(name);
+ PERL_UNUSED_ARG(namlen);
+
+ sv_magic(nsv, &PL_sv_undef, mg->mg_type, NULL, 0);
+ nmg = mg_find(nsv, mg->mg_type);
+ if (nmg->mg_flags & MGf_REFCOUNTED) SvREFCNT_dec(nmg->mg_obj);
+ nmg->mg_ptr = mg->mg_ptr;
+ nmg->mg_obj = SvREFCNT_inc_simple(mg->mg_obj);
+ nmg->mg_flags |= MGf_REFCOUNTED;
+ return 1;
+}
+
/*
* Local variables:
* c-indentation-style: bsd
* c-basic-offset: 4
- * indent-tabs-mode: t
+ * indent-tabs-mode: nil
* End:
*
- * ex: set ts=8 sts=4 sw=4 noet:
+ * ex: set ts=8 sts=4 sw=4 et:
*/