diff options
author | Yves Orton <demerphq@gmail.com> | 2020-01-31 15:34:48 +0100 |
---|---|---|
committer | Yves Orton <demerphq@gmail.com> | 2020-01-31 15:37:45 +0100 |
commit | 2b301921ff7682e54ab74ad30dbf2ce1c9fc24b1 (patch) | |
tree | be847e310a47167a95628f59deaf59c0d27639e8 /av.c | |
parent | 3eb35b099f783db0ec40f0ca9f20fd1666c54cdb (diff) | |
download | perl-2b301921ff7682e54ab74ad30dbf2ce1c9fc24b1.tar.gz |
pp_sort.c: fix fencepost error in call to av_extend()
In [rt.cpan.org #39196] issue #17496 there is a report
that Tie::File produced spurious blank lines in the file
after
@tied= sort @tied;
it turns out that this is because Tie::File treats
EXTEND similarly to STORESIZE (which is arguably not
entirely correct, but also not that weird) coupled
with an off by one error in the calls to av_extend()
in pp_sort.
This patch fixes the fencepost error, adds some comments
to av_extend() to make it clear what it is doing, and
adds a test that EXTEND is called by this code with
correct argument.
Diffstat (limited to 'av.c')
-rw-r--r-- | av.c | 18 |
1 files changed, 16 insertions, 2 deletions
@@ -55,8 +55,13 @@ Perl_av_reify(pTHX_ AV *av) /* =for apidoc av_extend -Pre-extend an array. The C<key> is the index to which the array should be -extended. +Pre-extend an array so that it is capable of storing values at indexes +C<0..key>. Thus C<av_extend(av,99)> guarantees that the array can store 100 +elements, i.e. that C<av_store(av, 0, sv)> through C<av_store(av, 99, sv)> +on a plain array will work without any further memory allocation. + +If the av argument is a tied array then will call the C<EXTEND> tied +array method with an argument of C<(key+1)>. =cut */ @@ -72,6 +77,15 @@ Perl_av_extend(pTHX_ AV *av, SSize_t key) mg = SvTIED_mg((const SV *)av, PERL_MAGIC_tied); if (mg) { SV *arg1 = sv_newmortal(); + /* NOTE: the API for av_extend() is NOT the same as the tie method EXTEND. + * + * The C function takes an *index* (assumes 0 indexed arrays) and ensures + * that the array is at least as large as the index provided. + * + * The tied array method EXTEND takes a *count* and ensures that the array + * is at least that many elements large. Thus we have to +1 the key when + * we call the tied method. + */ sv_setiv(arg1, (IV)(key + 1)); Perl_magic_methcall(aTHX_ MUTABLE_SV(av), mg, SV_CONST(EXTEND), G_DISCARD, 1, arg1); |