Patch 8.0.0667
Problem:    Memory access error when command follows :endfunction. (Nikolai
            Pavlov)
Solution:   Make memory handling in :function straightforward. (closes #1793)
Files:      src/userfunc.c, src/testdir/test_vimscript.vim


*** ../vim-8.0.0666/src/userfunc.c      2017-06-23 20:52:21.575128772 +0200
--- src/userfunc.c      2017-06-24 14:47:44.523671380 +0200
***************
*** 1780,1785 ****
--- 1780,1786 ----
  ex_function(exarg_T *eap)
  {
      char_u    *theline;
+     char_u    *line_to_free = NULL;
      int               j;
      int               c;
      int               saved_did_emsg;
***************
*** 2093,2102 ****
                line_arg = p + 1;
            }
        }
-       else if (eap->getline == NULL)
-           theline = getcmdline(':', 0L, indent);
        else
!           theline = eap->getline(':', eap->cookie, indent);
        if (KeyTyped)
            lines_left = Rows - 1;
        if (theline == NULL)
--- 2094,2108 ----
                line_arg = p + 1;
            }
        }
        else
!       {
!           vim_free(line_to_free);
!           if (eap->getline == NULL)
!               theline = getcmdline(':', 0L, indent);
!           else
!               theline = eap->getline(':', eap->cookie, indent);
!           line_to_free = theline;
!       }
        if (KeyTyped)
            lines_left = Rows - 1;
        if (theline == NULL)
***************
*** 2130,2147 ****
            /* Check for "endfunction". */
            if (checkforcmd(&p, "endfunction", 4) && nesting-- == 0)
            {
                if (*p == '|')
!                   /* Another command follows. */
!                   eap->nextcmd = vim_strsave(p + 1);
                else if (line_arg != NULL && *skipwhite(line_arg) != NUL)
!                   /* Another command follows. */
!                   eap->nextcmd = line_arg;
                else if (*p != NUL && *p != '"' && p_verbose > 0)
                    give_warning2(
                         (char_u *)_("W22: Text found after :endfunction: %s"),
                         p, TRUE);
!               if (line_arg == NULL)
!                   vim_free(theline);
                break;
            }
  
--- 2136,2164 ----
            /* Check for "endfunction". */
            if (checkforcmd(&p, "endfunction", 4) && nesting-- == 0)
            {
+               char_u *nextcmd = NULL;
+ 
                if (*p == '|')
!                   nextcmd = p + 1;
                else if (line_arg != NULL && *skipwhite(line_arg) != NUL)
!                   nextcmd = line_arg;
                else if (*p != NUL && *p != '"' && p_verbose > 0)
                    give_warning2(
                         (char_u *)_("W22: Text found after :endfunction: %s"),
                         p, TRUE);
!               if (nextcmd != NULL)
!               {
!                   /* Another command follows. If the line came from "eap" we
!                    * can simply point into it, otherwise we need to change
!                    * "eap->cmdlinep". */
!                   eap->nextcmd = nextcmd;
!                   if (line_to_free != NULL)
!                   {
!                       vim_free(*eap->cmdlinep);
!                       *eap->cmdlinep = line_to_free;
!                       line_to_free = NULL;
!                   }
!               }
                break;
            }
  
***************
*** 2212,2235 ****
  
        /* Add the line to the function. */
        if (ga_grow(&newlines, 1 + sourcing_lnum_off) == FAIL)
-       {
-           if (line_arg == NULL)
-               vim_free(theline);
            goto erret;
-       }
  
        /* Copy the line to newly allocated memory.  get_one_sourceline()
         * allocates 250 bytes per line, this saves 80% on average.  The cost
         * is an extra alloc/free. */
        p = vim_strsave(theline);
!       if (p != NULL)
!       {
!           if (line_arg == NULL)
!               vim_free(theline);
!           theline = p;
!       }
! 
!       ((char_u **)(newlines.ga_data))[newlines.ga_len++] = theline;
  
        /* Add NULL lines for continuation lines, so that the line count is
         * equal to the index in the growarray.   */
--- 2229,2243 ----
  
        /* Add the line to the function. */
        if (ga_grow(&newlines, 1 + sourcing_lnum_off) == FAIL)
            goto erret;
  
        /* Copy the line to newly allocated memory.  get_one_sourceline()
         * allocates 250 bytes per line, this saves 80% on average.  The cost
         * is an extra alloc/free. */
        p = vim_strsave(theline);
!       if (p == NULL)
!           goto erret;
!       ((char_u **)(newlines.ga_data))[newlines.ga_len++] = p;
  
        /* Add NULL lines for continuation lines, so that the line count is
         * equal to the index in the growarray.   */
***************
*** 2428,2433 ****
--- 2436,2442 ----
      ga_clear_strings(&newlines);
  ret_free:
      vim_free(skip_until);
+     vim_free(line_to_free);
      vim_free(fudi.fd_newkey);
      vim_free(name);
      did_emsg |= saved_did_emsg;
*** ../vim-8.0.0666/src/testdir/test_vimscript.vim      2017-06-23 
20:52:21.575128772 +0200
--- src/testdir/test_vimscript.vim      2017-06-24 14:40:18.511173845 +0200
***************
*** 1379,1384 ****
--- 1379,1389 ----
      delfunc Xtest
      unlet done
  
+     " trailing line break
+     exe "func Xtest()\necho 'hello'\nendfunc\n"
+     call assert_true(exists('*Xtest'))
+     delfunc Xtest
+ 
      set verbose=1
      exe "func Xtest()\necho 'hello'\nendfunc \" garbage"
      call assert_notmatch('W22:', split(execute('1messages'), "\n")[0])
***************
*** 1390,1395 ****
--- 1395,1405 ----
      call assert_true(exists('*Xtest'))
      delfunc Xtest
      set verbose=0
+ 
+     function Foo()
+       echo 'hello'
+     endfunction | echo 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
+     delfunc Foo
  endfunc
  
  func Test_delfunction_force()
*** ../vim-8.0.0666/src/version.c       2017-06-23 23:00:03.933758799 +0200
--- src/version.c       2017-06-24 14:41:52.022439531 +0200
***************
*** 766,767 ****
--- 766,769 ----
  {   /* Add new patch number below this line */
+ /**/
+     667,
  /**/

-- 
If bankers can count, how come they have eight windows and
only four tellers?

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui