comparison src/buffer.c @ 14917:6f2ce3b311de v8.1.0470

patch 8.1.0470: pointer ownership around fname_expand() is unclear commit https://github.com/vim/vim/commit/3d6014f0336d9a64c01a7518fe45fde0a925fa20 Author: Bram Moolenaar <Bram@vim.org> Date: Thu Oct 11 19:27:47 2018 +0200 patch 8.1.0470: pointer ownership around fname_expand() is unclear 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.
author Bram Moolenaar <Bram@vim.org>
date Thu, 11 Oct 2018 19:30:05 +0200
parents 27b9a84395b5
children 67e3103d6e18
comparison
equal deleted inserted replaced
14916:11372e362ffc 14917:6f2ce3b311de
661 #ifdef FEAT_SUN_WORKSHOP 661 #ifdef FEAT_SUN_WORKSHOP
662 if (usingSunWorkShop) 662 if (usingSunWorkShop)
663 workshop_file_closed_lineno((char *)buf->b_ffname, 663 workshop_file_closed_lineno((char *)buf->b_ffname,
664 (int)buf->b_last_cursor.lnum); 664 (int)buf->b_last_cursor.lnum);
665 #endif 665 #endif
666 vim_free(buf->b_ffname); 666 if (buf->b_sfname != buf->b_ffname)
667 vim_free(buf->b_sfname); 667 VIM_CLEAR(buf->b_sfname);
668 else
669 buf->b_sfname = NULL;
670 VIM_CLEAR(buf->b_ffname);
668 if (buf->b_prev == NULL) 671 if (buf->b_prev == NULL)
669 firstbuf = buf->b_next; 672 firstbuf = buf->b_next;
670 else 673 else
671 buf->b_prev->b_next = buf->b_next; 674 buf->b_prev->b_next = buf->b_next;
672 if (buf->b_next == NULL) 675 if (buf->b_next == NULL)
1875 * if the buffer already exists. 1878 * if the buffer already exists.
1876 * This is the ONLY way to create a new buffer. 1879 * This is the ONLY way to create a new buffer.
1877 */ 1880 */
1878 buf_T * 1881 buf_T *
1879 buflist_new( 1882 buflist_new(
1880 char_u *ffname, /* full path of fname or relative */ 1883 char_u *ffname_arg, // full path of fname or relative
1881 char_u *sfname, /* short fname or NULL */ 1884 char_u *sfname_arg, // short fname or NULL
1882 linenr_T lnum, /* preferred cursor line */ 1885 linenr_T lnum, // preferred cursor line
1883 int flags) /* BLN_ defines */ 1886 int flags) // BLN_ defines
1884 { 1887 {
1888 char_u *ffname = ffname_arg;
1889 char_u *sfname = sfname_arg;
1885 buf_T *buf; 1890 buf_T *buf;
1886 #ifdef UNIX 1891 #ifdef UNIX
1887 stat_T st; 1892 stat_T st;
1888 #endif 1893 #endif
1889 1894
1890 if (top_file_num == 1) 1895 if (top_file_num == 1)
1891 hash_init(&buf_hashtab); 1896 hash_init(&buf_hashtab);
1892 1897
1893 fname_expand(curbuf, &ffname, &sfname); /* will allocate ffname */ 1898 fname_expand(curbuf, &ffname, &sfname); // will allocate ffname
1894 1899
1895 /* 1900 /*
1896 * If file name already exists in the list, update the entry. 1901 * If file name already exists in the list, update the entry.
1897 */ 1902 */
1898 #ifdef UNIX 1903 #ifdef UNIX
1995 buf->b_wininfo = (wininfo_T *)alloc_clear((unsigned)sizeof(wininfo_T)); 2000 buf->b_wininfo = (wininfo_T *)alloc_clear((unsigned)sizeof(wininfo_T));
1996 2001
1997 if ((ffname != NULL && (buf->b_ffname == NULL || buf->b_sfname == NULL)) 2002 if ((ffname != NULL && (buf->b_ffname == NULL || buf->b_sfname == NULL))
1998 || buf->b_wininfo == NULL) 2003 || buf->b_wininfo == NULL)
1999 { 2004 {
2005 if (buf->b_sfname != buf->b_ffname)
2006 VIM_CLEAR(buf->b_sfname);
2007 else
2008 buf->b_sfname = NULL;
2000 VIM_CLEAR(buf->b_ffname); 2009 VIM_CLEAR(buf->b_ffname);
2001 VIM_CLEAR(buf->b_sfname);
2002 if (buf != curbuf) 2010 if (buf != curbuf)
2003 free_buffer(buf); 2011 free_buffer(buf);
2004 return NULL; 2012 return NULL;
2005 } 2013 }
2006 2014
3101 3109
3102 return OK; 3110 return OK;
3103 } 3111 }
3104 3112
3105 /* 3113 /*
3106 * Set the file name for "buf"' to 'ffname', short file name to 'sfname'. 3114 * Set the file name for "buf"' to "ffname_arg", short file name to
3115 * "sfname_arg".
3107 * The file name with the full path is also remembered, for when :cd is used. 3116 * The file name with the full path is also remembered, for when :cd is used.
3108 * Returns FAIL for failure (file name already in use by other buffer) 3117 * Returns FAIL for failure (file name already in use by other buffer)
3109 * OK otherwise. 3118 * OK otherwise.
3110 */ 3119 */
3111 int 3120 int
3112 setfname( 3121 setfname(
3113 buf_T *buf, 3122 buf_T *buf,
3114 char_u *ffname, 3123 char_u *ffname_arg,
3115 char_u *sfname, 3124 char_u *sfname_arg,
3116 int message) /* give message when buffer already exists */ 3125 int message) /* give message when buffer already exists */
3117 { 3126 {
3127 char_u *ffname = ffname_arg;
3128 char_u *sfname = sfname_arg;
3118 buf_T *obuf = NULL; 3129 buf_T *obuf = NULL;
3119 #ifdef UNIX 3130 #ifdef UNIX
3120 stat_T st; 3131 stat_T st;
3121 #endif 3132 #endif
3122 3133
3123 if (ffname == NULL || *ffname == NUL) 3134 if (ffname == NULL || *ffname == NUL)
3124 { 3135 {
3125 /* Removing the name. */ 3136 /* Removing the name. */
3137 if (buf->b_sfname != buf->b_ffname)
3138 VIM_CLEAR(buf->b_sfname);
3139 else
3140 buf->b_sfname = NULL;
3126 VIM_CLEAR(buf->b_ffname); 3141 VIM_CLEAR(buf->b_ffname);
3127 VIM_CLEAR(buf->b_sfname);
3128 #ifdef UNIX 3142 #ifdef UNIX
3129 st.st_dev = (dev_T)-1; 3143 st.st_dev = (dev_T)-1;
3130 #endif 3144 #endif
3131 } 3145 }
3132 else 3146 else
3173 # ifdef USE_LONG_FNAME 3187 # ifdef USE_LONG_FNAME
3174 if (USE_LONG_FNAME) 3188 if (USE_LONG_FNAME)
3175 # endif 3189 # endif
3176 fname_case(sfname, 0); /* set correct case for short file name */ 3190 fname_case(sfname, 0); /* set correct case for short file name */
3177 #endif 3191 #endif
3192 if (buf->b_sfname != buf->b_ffname)
3193 vim_free(buf->b_sfname);
3178 vim_free(buf->b_ffname); 3194 vim_free(buf->b_ffname);
3179 vim_free(buf->b_sfname);
3180 buf->b_ffname = ffname; 3195 buf->b_ffname = ffname;
3181 buf->b_sfname = sfname; 3196 buf->b_sfname = sfname;
3182 } 3197 }
3183 buf->b_fname = buf->b_sfname; 3198 buf->b_fname = buf->b_sfname;
3184 #ifdef UNIX 3199 #ifdef UNIX
3208 buf_T *buf; 3223 buf_T *buf;
3209 3224
3210 buf = buflist_findnr(fnum); 3225 buf = buflist_findnr(fnum);
3211 if (buf != NULL) 3226 if (buf != NULL)
3212 { 3227 {
3213 vim_free(buf->b_sfname); 3228 if (buf->b_sfname != buf->b_ffname)
3229 vim_free(buf->b_sfname);
3214 vim_free(buf->b_ffname); 3230 vim_free(buf->b_ffname);
3215 buf->b_ffname = vim_strsave(name); 3231 buf->b_ffname = vim_strsave(name);
3216 buf->b_sfname = NULL; 3232 buf->b_sfname = NULL;
3217 /* Allocate ffname and expand into full path. Also resolves .lnk 3233 /* Allocate ffname and expand into full path. Also resolves .lnk
3218 * files on Win32. */ 3234 * files on Win32. */
4818 return fname; 4834 return fname;
4819 #endif 4835 #endif
4820 } 4836 }
4821 4837
4822 /* 4838 /*
4823 * Make "ffname" a full file name, set "sfname" to "ffname" if not NULL. 4839 * Make "*ffname" a full file name, set "*sfname" to "*ffname" if not NULL.
4824 * "ffname" becomes a pointer to allocated memory (or NULL). 4840 * "*ffname" becomes a pointer to allocated memory (or NULL).
4841 * When resolving a link both "*sfname" and "*ffname" will point to the same
4842 * allocated memory.
4843 * The "*ffname" and "*sfname" pointer values on call will not be freed.
4844 * Note that the resulting "*ffname" pointer should be considered not allocaed.
4825 */ 4845 */
4826 void 4846 void
4827 fname_expand( 4847 fname_expand(
4828 buf_T *buf UNUSED, 4848 buf_T *buf UNUSED,
4829 char_u **ffname, 4849 char_u **ffname,
4830 char_u **sfname) 4850 char_u **sfname)
4831 { 4851 {
4832 if (*ffname == NULL) /* if no file name given, nothing to do */ 4852 if (*ffname == NULL) // no file name given, nothing to do
4833 return; 4853 return;
4834 if (*sfname == NULL) /* if no short file name given, use ffname */ 4854 if (*sfname == NULL) // no short file name given, use ffname
4835 *sfname = *ffname; 4855 *sfname = *ffname;
4836 *ffname = fix_fname(*ffname); /* expand to full path */ 4856 *ffname = fix_fname(*ffname); // expand to full path
4837 4857
4838 #ifdef FEAT_SHORTCUT 4858 #ifdef FEAT_SHORTCUT
4839 if (!buf->b_p_bin) 4859 if (!buf->b_p_bin)
4840 { 4860 {
4841 char_u *rfname; 4861 char_u *rfname;
4842 4862
4843 /* If the file name is a shortcut file, use the file it links to. */ 4863 // If the file name is a shortcut file, use the file it links to.
4844 rfname = mch_resolve_shortcut(*ffname); 4864 rfname = mch_resolve_shortcut(*ffname);
4845 if (rfname != NULL) 4865 if (rfname != NULL)
4846 { 4866 {
4847 vim_free(*ffname); 4867 vim_free(*ffname);
4848 *ffname = rfname; 4868 *ffname = rfname;