Patch 8.1.0470
Problem:    Pointer ownership around fname_expand() is unclear.
Solution:   Allow b_ffname and b_sfname to point to the same allocated memory,
            only free one.  Update comments.
Files:      src/buffer.c, src/structs.h, src/fileio.c, src/ex_cmds.c


*** ../vim-8.1.0469/src/buffer.c        2018-09-30 21:43:17.175693433 +0200
--- src/buffer.c        2018-10-11 19:00:11.004662173 +0200
***************
*** 663,670 ****
            workshop_file_closed_lineno((char *)buf->b_ffname,
                        (int)buf->b_last_cursor.lnum);
  #endif
!       vim_free(buf->b_ffname);
!       vim_free(buf->b_sfname);
        if (buf->b_prev == NULL)
            firstbuf = buf->b_next;
        else
--- 663,673 ----
            workshop_file_closed_lineno((char *)buf->b_ffname,
                        (int)buf->b_last_cursor.lnum);
  #endif
!       if (buf->b_sfname != buf->b_ffname)
!           VIM_CLEAR(buf->b_sfname);
!       else
!           buf->b_sfname = NULL;
!       VIM_CLEAR(buf->b_ffname);
        if (buf->b_prev == NULL)
            firstbuf = buf->b_next;
        else
***************
*** 1877,1887 ****
   */
      buf_T *
  buflist_new(
!     char_u    *ffname,        /* full path of fname or relative */
!     char_u    *sfname,        /* short fname or NULL */
!     linenr_T  lnum,           /* preferred cursor line */
!     int               flags)          /* BLN_ defines */
  {
      buf_T     *buf;
  #ifdef UNIX
      stat_T    st;
--- 1880,1892 ----
   */
      buf_T *
  buflist_new(
!     char_u    *ffname_arg,    // full path of fname or relative
!     char_u    *sfname_arg,    // short fname or NULL
!     linenr_T  lnum,           // preferred cursor line
!     int               flags)          // BLN_ defines
  {
+     char_u    *ffname = ffname_arg;
+     char_u    *sfname = sfname_arg;
      buf_T     *buf;
  #ifdef UNIX
      stat_T    st;
***************
*** 1890,1896 ****
      if (top_file_num == 1)
        hash_init(&buf_hashtab);
  
!     fname_expand(curbuf, &ffname, &sfname);   /* will allocate ffname */
  
      /*
       * If file name already exists in the list, update the entry.
--- 1895,1901 ----
      if (top_file_num == 1)
        hash_init(&buf_hashtab);
  
!     fname_expand(curbuf, &ffname, &sfname);   // will allocate ffname
  
      /*
       * If file name already exists in the list, update the entry.
***************
*** 1997,2004 ****
      if ((ffname != NULL && (buf->b_ffname == NULL || buf->b_sfname == NULL))
            || buf->b_wininfo == NULL)
      {
        VIM_CLEAR(buf->b_ffname);
-       VIM_CLEAR(buf->b_sfname);
        if (buf != curbuf)
            free_buffer(buf);
        return NULL;
--- 2002,2012 ----
      if ((ffname != NULL && (buf->b_ffname == NULL || buf->b_sfname == NULL))
            || buf->b_wininfo == NULL)
      {
+       if (buf->b_sfname != buf->b_ffname)
+           VIM_CLEAR(buf->b_sfname);
+       else
+           buf->b_sfname = NULL;
        VIM_CLEAR(buf->b_ffname);
        if (buf != curbuf)
            free_buffer(buf);
        return NULL;
***************
*** 3103,3109 ****
  }
  
  /*
!  * Set the file name for "buf"' to 'ffname', short file name to 'sfname'.
   * The file name with the full path is also remembered, for when :cd is used.
   * Returns FAIL for failure (file name already in use by other buffer)
   *    OK otherwise.
--- 3111,3118 ----
  }
  
  /*
!  * Set the file name for "buf"' to "ffname_arg", short file name to
!  * "sfname_arg".
   * The file name with the full path is also remembered, for when :cd is used.
   * Returns FAIL for failure (file name already in use by other buffer)
   *    OK otherwise.
***************
*** 3111,3120 ****
      int
  setfname(
      buf_T     *buf,
!     char_u    *ffname,
!     char_u    *sfname,
      int               message)        /* give message when buffer already 
exists */
  {
      buf_T     *obuf = NULL;
  #ifdef UNIX
      stat_T    st;
--- 3120,3131 ----
      int
  setfname(
      buf_T     *buf,
!     char_u    *ffname_arg,
!     char_u    *sfname_arg,
      int               message)        /* give message when buffer already 
exists */
  {
+     char_u    *ffname = ffname_arg;
+     char_u    *sfname = sfname_arg;
      buf_T     *obuf = NULL;
  #ifdef UNIX
      stat_T    st;
***************
*** 3123,3130 ****
      if (ffname == NULL || *ffname == NUL)
      {
        /* Removing the name. */
        VIM_CLEAR(buf->b_ffname);
-       VIM_CLEAR(buf->b_sfname);
  #ifdef UNIX
        st.st_dev = (dev_T)-1;
  #endif
--- 3134,3144 ----
      if (ffname == NULL || *ffname == NUL)
      {
        /* Removing the name. */
+       if (buf->b_sfname != buf->b_ffname)
+           VIM_CLEAR(buf->b_sfname);
+       else
+           buf->b_sfname = NULL;
        VIM_CLEAR(buf->b_ffname);
  #ifdef UNIX
        st.st_dev = (dev_T)-1;
  #endif
***************
*** 3175,3182 ****
  # endif
            fname_case(sfname, 0);    /* set correct case for short file name */
  #endif
        vim_free(buf->b_ffname);
-       vim_free(buf->b_sfname);
        buf->b_ffname = ffname;
        buf->b_sfname = sfname;
      }
--- 3189,3197 ----
  # endif
            fname_case(sfname, 0);    /* set correct case for short file name */
  #endif
+       if (buf->b_sfname != buf->b_ffname)
+           vim_free(buf->b_sfname);
        vim_free(buf->b_ffname);
        buf->b_ffname = ffname;
        buf->b_sfname = sfname;
      }
***************
*** 3210,3216 ****
      buf = buflist_findnr(fnum);
      if (buf != NULL)
      {
!       vim_free(buf->b_sfname);
        vim_free(buf->b_ffname);
        buf->b_ffname = vim_strsave(name);
        buf->b_sfname = NULL;
--- 3225,3232 ----
      buf = buflist_findnr(fnum);
      if (buf != NULL)
      {
!       if (buf->b_sfname != buf->b_ffname)
!           vim_free(buf->b_sfname);
        vim_free(buf->b_ffname);
        buf->b_ffname = vim_strsave(name);
        buf->b_sfname = NULL;
***************
*** 4820,4827 ****
  }
  
  /*
!  * Make "ffname" a full file name, set "sfname" to "ffname" if not NULL.
!  * "ffname" becomes a pointer to allocated memory (or NULL).
   */
      void
  fname_expand(
--- 4836,4847 ----
  }
  
  /*
!  * Make "*ffname" a full file name, set "*sfname" to "*ffname" if not NULL.
!  * "*ffname" becomes a pointer to allocated memory (or NULL).
!  * When resolving a link both "*sfname" and "*ffname" will point to the same
!  * allocated memory.
!  * The "*ffname" and "*sfname" pointer values on call will not be freed.
!  * Note that the resulting "*ffname" pointer should be considered not 
allocaed.
   */
      void
  fname_expand(
***************
*** 4829,4846 ****
      char_u    **ffname,
      char_u    **sfname)
  {
!     if (*ffname == NULL)      /* if no file name given, nothing to do */
        return;
!     if (*sfname == NULL)      /* if no short file name given, use ffname */
        *sfname = *ffname;
!     *ffname = fix_fname(*ffname);   /* expand to full path */
  
  #ifdef FEAT_SHORTCUT
      if (!buf->b_p_bin)
      {
        char_u  *rfname;
  
!       /* If the file name is a shortcut file, use the file it links to. */
        rfname = mch_resolve_shortcut(*ffname);
        if (rfname != NULL)
        {
--- 4849,4866 ----
      char_u    **ffname,
      char_u    **sfname)
  {
!     if (*ffname == NULL)          // no file name given, nothing to do
        return;
!     if (*sfname == NULL)          // no short file name given, use ffname
        *sfname = *ffname;
!     *ffname = fix_fname(*ffname);   // expand to full path
  
  #ifdef FEAT_SHORTCUT
      if (!buf->b_p_bin)
      {
        char_u  *rfname;
  
!       // If the file name is a shortcut file, use the file it links to.
        rfname = mch_resolve_shortcut(*ffname);
        if (rfname != NULL)
        {
*** ../vim-8.1.0469/src/structs.h       2018-10-02 18:25:41.420867587 +0200
--- src/structs.h       2018-10-11 17:45:36.197140877 +0200
***************
*** 1972,1980 ****
       * b_fname is the same as b_sfname, unless ":cd" has been done,
       *                then it is the same as b_ffname (NULL for no name).
       */
!     char_u    *b_ffname;      /* full path file name */
!     char_u    *b_sfname;      /* short file name */
!     char_u    *b_fname;       /* current file name */
  
  #ifdef UNIX
      int               b_dev_valid;    /* TRUE when b_dev has a valid number */
--- 1972,1982 ----
       * b_fname is the same as b_sfname, unless ":cd" has been done,
       *                then it is the same as b_ffname (NULL for no name).
       */
!     char_u    *b_ffname;      // full path file name, allocated
!     char_u    *b_sfname;      // short file name, allocated, may be equal to
!                               // b_ffname
!     char_u    *b_fname;       // current file name, points to b_ffname or
!                               // b_sfname
  
  #ifdef UNIX
      int               b_dev_valid;    /* TRUE when b_dev has a valid number */
*** ../vim-8.1.0469/src/fileio.c        2018-09-30 21:43:17.187693348 +0200
--- src/fileio.c        2018-10-11 18:50:41.084975167 +0200
***************
*** 6187,6193 ****
                || buf->b_sfname == NULL
                || mch_isFullName(buf->b_sfname)))
      {
!       VIM_CLEAR(buf->b_sfname);
        p = shorten_fname(buf->b_ffname, dirname);
        if (p != NULL)
        {
--- 6187,6194 ----
                || buf->b_sfname == NULL
                || mch_isFullName(buf->b_sfname)))
      {
!       if (buf->b_sfname != buf->b_ffname)
!           VIM_CLEAR(buf->b_sfname);
        p = shorten_fname(buf->b_ffname, dirname);
        if (p != NULL)
        {
*** ../vim-8.1.0469/src/ex_cmds.c       2018-10-09 21:49:30.447622031 +0200
--- src/ex_cmds.c       2018-10-11 19:01:12.524192986 +0200
***************
*** 3648,3655 ****
  }
  
  /*
!  * Try to abandon current file and edit a new or existing file.
!  * "fnum" is the number of the file, if zero use ffname/sfname.
   * "lnum" is the line number for the cursor in the new file (if non-zero).
   *
   * Return:
--- 3648,3655 ----
  }
  
  /*
!  * Try to abandon the current file and edit a new or existing file.
!  * "fnum" is the number of the file, if zero use "ffname_arg"/"sfname_arg".
   * "lnum" is the line number for the cursor in the new file (if non-zero).
   *
   * Return:
***************
*** 3661,3672 ****
      int
  getfile(
      int               fnum,
!     char_u    *ffname,
!     char_u    *sfname,
      int               setpm,
      linenr_T  lnum,
      int               forceit)
  {
      int               other;
      int               retval;
      char_u    *free_me = NULL;
--- 3661,3674 ----
      int
  getfile(
      int               fnum,
!     char_u    *ffname_arg,
!     char_u    *sfname_arg,
      int               setpm,
      linenr_T  lnum,
      int               forceit)
  {
+     char_u    *ffname = ffname_arg;
+     char_u    *sfname = sfname_arg;
      int               other;
      int               retval;
      char_u    *free_me = NULL;
*** ../vim-8.1.0469/src/version.c       2018-10-11 17:39:09.173107491 +0200
--- src/version.c       2018-10-11 18:57:27.585905972 +0200
***************
*** 794,795 ****
--- 794,797 ----
  {   /* Add new patch number below this line */
+ /**/
+     470,
  /**/

-- 
hundred-and-one symptoms of being an internet addict:
189. You put your e-mail address in the upper left-hand corner of envelopes.

 /// 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