From dedeecdaea55ab4b3131dd2b0054ee46a1954f19 Mon Sep 17 00:00:00 2001 From: Perl 5 Porters Date: Wed, 28 Aug 1996 03:20:21 +0000 Subject: [PATCH] Patch for LONG_MAX & co. substr() in lvalue context interacts in buggy fashion with SVs that are !SvOK. This manifests itself with lexicals that have a REFCNT of 1, since these are merely "cleared in place" by setting SvOK_off. substr() coredumps with a target that is a ref, when it is used in an lvalue context. The patch below corrects the problem by stringifying the reference first (and emitting a warning when appropriate). --- pp.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/pp.c b/pp.c index d75566f..711ba29 100644 --- a/pp.c +++ b/pp.c @@ -576,7 +576,7 @@ PP(pp_predec) { dSP; if (SvIOK(TOPs)) { - if (SvIVX(TOPs) == PERL_LONG_MIN) { + if (SvIVX(TOPs) == IV_MIN) { sv_setnv(TOPs, (double)SvIVX(TOPs) - 1.0); } else { @@ -595,7 +595,7 @@ PP(pp_postinc) dSP; dTARGET; sv_setsv(TARG, TOPs); if (SvIOK(TOPs)) { - if (SvIVX(TOPs) == PERL_LONG_MAX) { + if (SvIVX(TOPs) == IV_MAX) { sv_setnv(TOPs, (double)SvIVX(TOPs) + 1.0); } else { @@ -617,7 +617,7 @@ PP(pp_postdec) dSP; dTARGET; sv_setsv(TARG, TOPs); if (SvIOK(TOPs)) { - if (SvIVX(TOPs) == PERL_LONG_MIN) { + if (SvIVX(TOPs) == IV_MIN) { sv_setnv(TOPs, (double)SvIVX(TOPs) - 1.0); } else { @@ -1446,8 +1446,17 @@ PP(pp_substr) rem = len; sv_setpvn(TARG, tmps, rem); if (lvalue) { /* it's an lvalue! */ - if (!SvGMAGICAL(sv)) - (void)SvPOK_only(sv); + if (!SvGMAGICAL(sv)) { + if (SvROK(sv)) { + SvPV_force(sv,na); + if (dowarn) + warn("Attempt to use reference as lvalue in substr"); + } + if (SvOK(sv)) /* is it defined ? */ + (void)SvPOK_only(sv); + else + sv_setpvn(sv,"",0); /* avoid lexical reincarnation */ + } if (SvTYPE(TARG) < SVt_PVLV) { sv_upgrade(TARG, SVt_PVLV); sv_magic(TARG, Nullsv, 'x', Nullch, 0); -- 2.7.4