summaryrefslogtreecommitdiff
path: root/sv.h
diff options
context:
space:
mode:
authorDavid Mitchell <davem@iabyn.com>2017-03-31 13:44:58 +0100
committerDavid Mitchell <davem@iabyn.com>2017-03-31 14:13:24 +0100
commit1b92e6949b737e92f61827f9c92afce9218e30ba (patch)
treedc6337456cd4e6bd0fe98c168602bcad4a2bedb1 /sv.h
parent1190bf17f4131bb86c6cd460c77e9d02894ca2ec (diff)
downloadperl-1b92e6949b737e92f61827f9c92afce9218e30ba.tar.gz
vec(): defer lvalue out-of-range croaking
RT #131083 Recent commits v5.25.10-81-gd69c430 and v5.25.10-82-g67dd6f3 added out-of-range/overflow checks for the offset arg of vec(). However in lvalue context, these croaks now happen before the SVt_PVLV was created, rather than when its set magic was called. This means that something like sub f { $x = $_[0] } f(vec($s, -1, 8)) now croaks even though the out-of-range value never ended up getting used in lvalue context. This commit fixes things by, in pp_vec(), rather than croaking, just set flag bits in LvFLAGS() to indicate that the offset is -Ve / out-of-range. Then in Perl_magic_getvec(), return 0 if these flags are set, and in Perl_magic_setvec() croak with a suitable error.
Diffstat (limited to 'sv.h')
-rw-r--r--sv.h3
1 files changed, 2 insertions, 1 deletions
diff --git a/sv.h b/sv.h
index 82130b7fc0..5e9c5b6881 100644
--- a/sv.h
+++ b/sv.h
@@ -541,7 +541,8 @@ struct xpvlv {
SV* xlv_targ;
char xlv_type; /* k=keys .=pos x=substr v=vec /=join/re
* y=alem/helem/iter t=tie T=tied HE */
- char xlv_flags; /* 1 = negative offset 2 = negative len */
+ char xlv_flags; /* 1 = negative offset 2 = negative len
+ 4 = out of range (vec) */
};
#define xlv_targoff xlv_targoff_u.xlvu_targoff