]> git.vpit.fr Git - perl/modules/autovivification.git/commitdiff
Make sure a_defined() calls get magic before testing for definedness rt56870
authorVincent Pit <vince@profvince.com>
Fri, 23 Apr 2010 23:23:20 +0000 (01:23 +0200)
committerVincent Pit <vince@profvince.com>
Fri, 23 Apr 2010 23:23:20 +0000 (01:23 +0200)
Before this lvalues never appeared as defined, which caused bugs with multiple
nested tied arrays and hashes.

This fixes RT #56870.

MANIFEST
autovivification.xs
t/23-hash-tied.t [new file with mode: 0644]
t/33-array-tied.t [new file with mode: 0644]

index 988f9cb72a15926300602f3b224982dd8a08ab2a..8d9162219392f3b7d3c0be7c0b69c40d3cfeb757 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -10,9 +10,11 @@ samples/hash2array.pl
 t/00-load.t
 t/20-hash.t
 t/22-hash-kv.t
+t/23-hash-tied.t
 t/30-array.t
 t/31-array-fast.t
 t/32-array-kv.t
+t/33-array-tied.t
 t/40-scope.t
 t/41-padsv.t
 t/42-deparse.t
index a8367a0a961e07b2f0b8665f4dec351e0c92e12d..7e7c1f34cd32fbb5a684c6d21695537bdd327fa1 100644 (file)
@@ -378,7 +378,9 @@ STATIC bool a_defined(pTHX_ SV *sv) {
     defined = TRUE;
    break;
   default:
-   defined = SvOK(sv);
+   SvGETMAGIC(sv);
+   if (SvOK(sv))
+    defined = TRUE;
  }
 
  return defined;
@@ -403,7 +405,7 @@ STATIC OP *a_pp_rv2av(pTHX) {
  flags = oi.flags;
 
  if (flags & A_HINT_DEREF) {
-  if (!SvOK(TOPs)) {
+  if (!a_defined(TOPs)) {
    /* We always need to push an empty array to fool the pp_aelem() that comes
     * later. */
    SV *av;
@@ -430,7 +432,7 @@ STATIC OP *a_pp_rv2hv_simple(pTHX) {
  flags = oi.flags;
 
  if (flags & A_HINT_DEREF) {
-  if (!SvOK(TOPs))
+  if (!a_defined(TOPs))
    RETURN;
  } else {
   PL_op->op_ppaddr = oi.old_pp;
@@ -448,7 +450,7 @@ STATIC OP *a_pp_rv2hv(pTHX) {
  flags = oi.flags;
 
  if (flags & A_HINT_DEREF) {
-  if (!SvOK(TOPs)) {
+  if (!a_defined(TOPs)) {
    SV *hv;
    POPs;
    hv = sv_2mortal((SV *) newHV());
@@ -484,7 +486,7 @@ deref:
 
   if (flags & (A_HINT_NOTIFY|A_HINT_STORE)) {
    SPAGAIN;
-   if (!SvOK(TOPs)) {
+   if (!a_defined(TOPs)) {
     if (flags & A_HINT_STRICT)
      croak("Reference vivification forbidden");
     else if (flags & A_HINT_WARN)
diff --git a/t/23-hash-tied.t b/t/23-hash-tied.t
new file mode 100644 (file)
index 0000000..7fd0fc3
--- /dev/null
@@ -0,0 +1,27 @@
+#!perl -T
+
+use strict;
+use warnings;
+
+use Test::More;
+
+BEGIN {
+ eval 'use Tie::Hash; scalar keys %Tie::StdHash::'
+                or plan skip_all => 'Tie::StdHash required to test tied hashes';
+ defined and diag "Using Tie::StdHash $_" for $Tie::Hash::VERSION;
+ plan tests => 1;
+}
+
+{
+ tie my %x, 'Tie::StdHash';
+ tie my %y, 'Tie::StdHash';
+
+ $x{key} = 'hlagh';
+ $y{x}   = \%x;
+
+ my $res = do {
+  no autovivification;
+  $y{x}{key};
+ };
+ is $res, 'hlagh', 'nested tied hashes';
+}
diff --git a/t/33-array-tied.t b/t/33-array-tied.t
new file mode 100644 (file)
index 0000000..93ab369
--- /dev/null
@@ -0,0 +1,27 @@
+#!perl -T
+
+use strict;
+use warnings;
+
+use Test::More;
+
+BEGIN {
+ eval 'use Tie::Array; scalar keys %Tie::StdArray::'
+               or plan skip_all => 'Tie::StdArray required to test tied arrays';
+ defined and diag "Using Tie::StdArray $_" for $Tie::Array::VERSION;
+ plan tests => 1;
+}
+
+{
+ tie my @a, 'Tie::StdArray';
+ tie my @b, 'Tie::StdArray';
+
+ $a[1] = 'hlagh';
+ $b[0] = \@a;
+
+ my $res = do {
+  no autovivification;
+  $b[0][1];
+ };
+ is $res, 'hlagh', 'nested tied arrays';
+}