sub NEGATIVE_INDICES; + $tied[-1] = crash
authorFather Chrysostomos <sprout@cpan.org>
Sun, 3 Nov 2013 12:47:17 +0000 (04:47 -0800)
committerFather Chrysostomos <sprout@cpan.org>
Mon, 4 Nov 2013 13:10:18 +0000 (05:10 -0800)
This code in av.c, when trying to find $NEGATIVE_INDICES, was doing a
direct stash element lookup--instead of going through the normal GV
functions--and then expecting the returned value to be a GV.

‘sub NEGATIVE_INDICES’ creates a stash element that is a PV, not a GV,
so it’s easy to make things crash.

av.c
t/op/tie.t

diff --git a/av.c b/av.c
index 3473d08..2a8ccf0 100644 (file)
--- a/av.c
+++ b/av.c
@@ -201,7 +201,8 @@ S_adjust_index(pTHX_ AV *av, const MAGIC *mg, SSize_t *keyp)
            SV * const * const negative_indices_glob =
                hv_fetchs(SvSTASH(SvRV(ref)), NEGATIVE_INDICES_VAR, 0);
 
-           if (negative_indices_glob && SvTRUE(GvSV(*negative_indices_glob)))
+           if (negative_indices_glob && isGV(*negative_indices_glob)
+            && SvTRUE(GvSV(*negative_indices_glob)))
                adjust_index = 0;
        }
     }
index d6e641e..e0b2499 100644 (file)
@@ -1341,6 +1341,16 @@ Can't call method "FETCHSIZE" on an undefined value at - line 7.
 Can't call method "FETCHSIZE" on an undefined value at - line 8.
 ########
 
+# Crash when reading negative index when NEGATIVE_INDICES stub exists
+sub NEGATIVE_INDICES;
+sub TIEARRAY{bless[]};
+sub FETCHSIZE{}
+tie @a, "";
+print "ok\n" if ! defined $a[-1];
+EXPECT
+ok
+########
+
 # Assigning vstrings to tied scalars
 sub TIESCALAR{bless[]};
 sub STORE { print ref \$_[1], "\n" }