summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkevin brintnall <kbrint@rufus.net>2008-12-24 20:59:15 -0600
committerRafael Garcia-Suarez <rgarciasuarez@gmail.com>2008-12-26 23:43:35 +0100
commit2779b694b3fbb69a13c300a6e239e050151abf6d (patch)
treeb9afb365d2f161d679ce56d9d038425f340e230f
parentf08e0584288c021de71ecd212ba86a45c8f96a5b (diff)
downloadperl-2779b694b3fbb69a13c300a6e239e050151abf6d.tar.gz
sv_dup(): avoid cloning empty arrays
Testing the ARRAY pointer is insufficent. Arrays emptied by 'shift' or 'pop' may still have non-NULL 'ARRAY' pointers. Check more carefully to determine whether the array has anything worth duplicating. If not, reset the FILL and MAX offsets to -1 just as 'undef @ARRAY' would. This avoids potential corruption in the PL_ptr_table during perl_clone().
-rw-r--r--sv.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/sv.c b/sv.c
index 917c897eaa..a9d9b21f06 100644
--- a/sv.c
+++ b/sv.c
@@ -10826,7 +10826,8 @@ Perl_sv_dup(pTHX_ const SV *const sstr, CLONE_PARAMS *const param)
IoBOTTOM_NAME(dstr) = SAVEPV(IoBOTTOM_NAME(dstr));
break;
case SVt_PVAV:
- if (AvARRAY((const AV *)sstr)) {
+ /* avoid cloning an empty array */
+ if (AvARRAY((const AV *)sstr) && AvFILLp((const AV *)sstr) >= 0) {
SV **dst_ary, **src_ary;
SSize_t items = AvFILLp((const AV *)sstr) + 1;
@@ -10851,6 +10852,8 @@ Perl_sv_dup(pTHX_ const SV *const sstr, CLONE_PARAMS *const param)
else {
AvARRAY(MUTABLE_AV(dstr)) = NULL;
AvALLOC((const AV *)dstr) = (SV**)NULL;
+ AvMAX( (const AV *)dstr) = -1;
+ AvFILLp((const AV *)dstr) = -1;
}
break;
case SVt_PVHV: