diff options
author | kevin brintnall <kbrint@rufus.net> | 2008-12-24 20:59:15 -0600 |
---|---|---|
committer | Rafael Garcia-Suarez <rgarciasuarez@gmail.com> | 2008-12-26 23:43:35 +0100 |
commit | 2779b694b3fbb69a13c300a6e239e050151abf6d (patch) | |
tree | b9afb365d2f161d679ce56d9d038425f340e230f /sv.c | |
parent | f08e0584288c021de71ecd212ba86a45c8f96a5b (diff) | |
download | perl-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().
Diffstat (limited to 'sv.c')
-rw-r--r-- | sv.c | 5 |
1 files changed, 4 insertions, 1 deletions
@@ -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: |