/* mg.c
*
* Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- * 2000, 2001, 2002, 2003, by Larry Wall and others
+ * 2000, 2001, 2002, 2003, 2004, by Larry Wall and others
*
* You may distribute under the terms of either the GNU General Public
* License or the Artistic License, as specified in the README file.
int new = 0;
MAGIC *newmg, *head, *cur, *mg;
I32 mgs_ix = SSNEW(sizeof(MGS));
+ int was_temp = SvTEMP(sv);
+ /* guard against sv having being freed midway by holding a private
+ reference. */
+
+ /* sv_2mortal has this side effect of turning on the TEMP flag, which can
+ cause the SV's buffer to get stolen (and maybe other stuff).
+ So restore it.
+ */
+ sv_2mortal(SvREFCNT_inc(sv));
+ if (!was_temp) {
+ SvTEMP_off(sv);
+ }
save_magic(mgs_ix, sv);
if (!(mg->mg_flags & MGf_GSKIP) && vtbl && vtbl->svt_get) {
CALL_FPTR(vtbl->svt_get)(aTHX_ sv, mg);
- /* guard against sv having been freed */
- if (SvTYPE(sv) == SVTYPEMASK) {
- Perl_croak(aTHX_ "Tied variable freed while still in use");
- }
/* guard against magic having been deleted - eg FETCH calling
* untie */
if (!SvMAGIC(sv))
}
restore_magic(aTHX_ INT2PTR(void *, (IV)mgs_ix));
+
+ if (SvREFCNT(sv) == 1) {
+ /* We hold the last reference to this SV, which implies that the
+ SV was deleted as a side effect of the routines we called. */
+ SvOK_off(sv);
+ }
return 0;
}
}
else {
if (ckWARN(WARN_UNINITIALIZED))
- report_uninit();
+ report_uninit(sv);
}
}
else {
if (ckWARN(WARN_UNINITIALIZED))
- report_uninit();
+ report_uninit(sv);
}
return 0;
case '+':
case '\004': /* ^D */
sv_setiv(sv, (IV)(PL_debug & DEBUG_MASK));
-#if defined(YYDEBUG) && defined(DEBUGGING)
- PL_yydebug = DEBUG_p_TEST;
-#endif
break;
case '\005': /* ^E */
if (*(mg->mg_ptr+1) == '\0') {
sv_utf8_upgrade(lsv);
sv_pos_u2b(lsv, &lvoff, &lvlen);
sv_insert(lsv, lvoff, lvlen, tmps, len);
+ LvTARGLEN(sv) = sv_len_utf8(sv);
SvUTF8_on(lsv);
}
else if (lsv && SvUTF8(lsv)) {
sv_pos_u2b(lsv, &lvoff, &lvlen);
+ LvTARGLEN(sv) = len;
tmps = (char*)bytes_to_utf8((U8*)tmps, &len);
sv_insert(lsv, lvoff, lvlen, tmps, len);
Safefree(tmps);
}
- else
- sv_insert(lsv, lvoff, lvlen, tmps, len);
+ else {
+ sv_insert(lsv, lvoff, lvlen, tmps, len);
+ LvTARGLEN(sv) = len;
+ }
+
return 0;
}
break;
case '\017': /* ^O */
if (*(mg->mg_ptr+1) == '\0') {
- if (PL_osname)
+ if (PL_osname) {
Safefree(PL_osname);
+ PL_osname = Nullch;
+ }
if (SvOK(sv)) {
TAINT_PROPER("assigning to $^O");
PL_osname = savepv(SvPV(sv,len));
}
- else
- PL_osname = Nullch;
}
else if (strEQ(mg->mg_ptr, "\017PEN")) {
if (!PL_compiling.cop_io)