mg.c: Fix misuse of AvARRAY in defelem_target
authorFather Chrysostomos <sprout@cpan.org>
Sun, 3 Nov 2013 12:23:43 +0000 (04:23 -0800)
committerFather Chrysostomos <sprout@cpan.org>
Mon, 4 Nov 2013 13:10:18 +0000 (05:10 -0800)
commitca58dfd9e0b19f1ae344f4aea62e3e4193f9c34f
treed5144a5a62e6b4593eacb65377b13c37af7f0d8e
parent5a34f1cdd2a19f0ff733c8488b899233b60188db
mg.c: Fix misuse of AvARRAY in defelem_target

defelem magic does not usually apply to tied arrays, but an array can
be tied after a defelem has been created and points to it.  The code
for handling deferred elements was never updated for tied arrays when
those were added, so it still does AvFILL and AvARRAY.

AvFILL works on tied arrays, and calls FETCHSIZE.  But AvARRAY
accesses the AV’s internal structure.  So AvFILL might suggest that
the index is within the array, whereas it is actually past the end
of AvARRAY.

By tying the array after a deferred element with a high index has been
created and then extending the tied array (so AvFILL returns a big
number), we can make AvARRAY[big number] crash.

This script:

use Tie::Array;
sub {
  tie @a, "Tie::StdArray";
  $#a = 20000;
  warn pre;
  "$_[0]";
  warn post
}->($a[10000]);

gives this output:

pre at -e line 5.
Segmentation fault: 11

For tied arrays, we need to use av_fetch, rather than AvARRAY.
mg.c
t/op/tie.t