]> granicus.if.org Git - vim/commitdiff
patch 8.1.0234: incorrect reference counting in Perl interface v8.1.0234
authorBram Moolenaar <Bram@vim.org>
Thu, 2 Aug 2018 19:46:51 +0000 (21:46 +0200)
committerBram Moolenaar <Bram@vim.org>
Thu, 2 Aug 2018 19:46:51 +0000 (21:46 +0200)
Problem:    Incorrect reference counting in Perl interface.
Solution:   Call SvREFCNT_inc more often, add a test. (Damien)

src/if_perl.xs
src/testdir/test_perl.vim
src/version.c

index bc15efa944b6546b803b4ffd2622f703981b3112..9fd219691ef09b6025593f5743ab5f2e96aee5ba 100644 (file)
@@ -831,8 +831,7 @@ newWINrv(SV *rv, win_T *ptr)
        ptr->w_perl_private = newSV(0);
        sv_setiv(ptr->w_perl_private, PTR2IV(ptr));
     }
-    else
-       SvREFCNT_inc_void_NN(ptr->w_perl_private);
+    SvREFCNT_inc_void_NN(ptr->w_perl_private);
     SvRV(rv) = ptr->w_perl_private;
     SvROK_on(rv);
     return sv_bless(rv, gv_stashpv("VIWIN", TRUE));
@@ -847,8 +846,7 @@ newBUFrv(SV *rv, buf_T *ptr)
        ptr->b_perl_private = newSV(0);
        sv_setiv(ptr->b_perl_private, PTR2IV(ptr));
     }
-    else
-       SvREFCNT_inc_void_NN(ptr->b_perl_private);
+    SvREFCNT_inc_void_NN(ptr->b_perl_private);
     SvRV(rv) = ptr->b_perl_private;
     SvROK_on(rv);
     return sv_bless(rv, gv_stashpv("VIBUF", TRUE));
@@ -918,12 +916,13 @@ I32 cur_val(IV iv, SV *sv)
     else
        rv = newBUFrv(newSV(0), curbuf);
 
-    if (SvRV(sv) == SvRV(rv))
-       SvREFCNT_dec(SvRV(rv));
-    else // XXX: Not sure if the `else` condition are right
-        // Test_SvREFCNT() pass in all case.
+    if (SvRV(sv) != SvRV(rv))
+       // XXX: This magic variable is a bit confusing...
+       // Is curently refcounted ?
        sv_setsv(sv, rv);
 
+    SvREFCNT_dec(rv);
+
     return 0;
 }
 #endif /* !PROTO */
index 661c65cdc8f6f452e3a6b60b68bbc6a96eaee4bd..03c5fa0d108b1331e865583e507a775ff9f2dd19 100644 (file)
@@ -4,6 +4,9 @@ if !has('perl')
   finish
 end
 
+" FIXME: RunTest don't see any error when Perl abort...
+perl $SIG{__WARN__} = sub { die "Unexpected warnings from perl: @_" };
+
 func Test_change_buffer()
   call setline(line('$'), ['1 line 1'])
   perl VIM::DoCommand("normal /^1\n")
@@ -229,6 +232,15 @@ func Test_000_SvREFCNT()
 #line 5 "Test_000_SvREFCNT()"
   my ($b, $w);
 
+  my $num = 0;
+  for ( 0 .. 100 ) {
+      if ( ++$num >= 8 ) { $num = 0 }
+      VIM::DoCommand("buffer X$num");
+      $b = $curbuf;
+  }
+
+  VIM::DoCommand("buffer t");
+
   $b = $curbuf      for 0 .. 100;
   $w = $curwin      for 0 .. 100;
   () = VIM::Buffers for 0 .. 100;
@@ -240,12 +252,13 @@ func Test_000_SvREFCNT()
       my $cw = Internals::SvREFCNT($$w);
       VIM::Eval("assert_equal(2, $cb, 'T1')");
       VIM::Eval("assert_equal(2, $cw, 'T2')");
+      my $strongref;
       foreach ( VIM::Buffers, VIM::Windows ) {
+         VIM::DoCommand("%bw!");
          my $c = Internals::SvREFCNT($_);
          VIM::Eval("assert_equal(2, $c, 'T3')");
          $c = Internals::SvREFCNT($$_);
-         # Why only one ref?
-         # Look wrong but work.  Maybe not portable...
+         next if $c == 2 && !$strongref++;
          VIM::Eval("assert_equal(1, $c, 'T4')");
       }
       $cb = Internals::SvREFCNT($$curbuf);
index 6e6c3cdc76effb3c2ff31664a9c4b0a5074acaaf..482b38e38aab8fdf73c79236beb124f21fb23fbd 100644 (file)
@@ -794,6 +794,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    234,
 /**/
     233,
 /**/