diff options
author | Perl 5 Porters <perl5-porters@africa.nicoh.com> | 1996-08-28 03:20:21 +0000 |
---|---|---|
committer | Andy Dougherty <doughera@lafcol.lafayette.edu> | 1996-08-28 03:20:21 +0000 |
commit | dedeecdaea55ab4b3131dd2b0054ee46a1954f19 (patch) | |
tree | f13f2a975ae7cf4cf039bf13bc50bd25fde50c91 /pp.c | |
parent | 84287afe68eecc4342d7e27aac5d9df9d2412490 (diff) | |
download | perl-dedeecdaea55ab4b3131dd2b0054ee46a1954f19.tar.gz |
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).
Diffstat (limited to 'pp.c')
-rw-r--r-- | pp.c | 19 |
1 files changed, 14 insertions, 5 deletions
@@ -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); |