Mercurial > vim
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; |