summaryrefslogtreecommitdiff
path: root/pp.c
diff options
context:
space:
mode:
authorPerl 5 Porters <perl5-porters@africa.nicoh.com>1996-08-28 03:20:21 +0000
committerAndy Dougherty <doughera@lafcol.lafayette.edu>1996-08-28 03:20:21 +0000
commitdedeecdaea55ab4b3131dd2b0054ee46a1954f19 (patch)
treef13f2a975ae7cf4cf039bf13bc50bd25fde50c91 /pp.c
parent84287afe68eecc4342d7e27aac5d9df9d2412490 (diff)
downloadperl-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.c19
1 files changed, 14 insertions, 5 deletions
diff --git a/pp.c b/pp.c
index d75566fa3a..711ba29645 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);