comparison src/viminfo.c @ 18263:a5de1d88590d v8.1.2126

patch 8.1.2126: viminfo not sufficiently tested Commit: https://github.com/vim/vim/commit/6bd1d7706766a7899904163e8fd55ea117fb1953 Author: Bram Moolenaar <Bram@vim.org> Date: Wed Oct 9 22:01:25 2019 +0200 patch 8.1.2126: viminfo not sufficiently tested Problem: Viminfo not sufficiently tested. Solution: Add more test cases. Clean up comments. (Yegappan Lakshmanan, closes #5032)
author Bram Moolenaar <Bram@vim.org>
date Wed, 09 Oct 2019 22:15:04 +0200
parents 4d63d47d87ef
children 18d7337b6837
comparison
equal deleted inserted replaced
18262:3050e95a3c73 18263:a5de1d88590d
11 * viminfo.c: viminfo related functions 11 * viminfo.c: viminfo related functions
12 */ 12 */
13 13
14 #include "vim.h" 14 #include "vim.h"
15 #include "version.h" 15 #include "version.h"
16
17 /*
18 * Structure used for reading from the viminfo file.
19 */
20 typedef struct
21 {
22 char_u *vir_line; // text of the current line
23 FILE *vir_fd; // file descriptor
24 vimconv_T vir_conv; // encoding conversion
25 int vir_version; // viminfo version detected or -1
26 garray_T vir_barlines; // lines starting with |
27 } vir_T;
16 28
17 #if defined(FEAT_VIMINFO) || defined(PROTO) 29 #if defined(FEAT_VIMINFO) || defined(PROTO)
18 30
19 static int viminfo_errcnt; 31 static int viminfo_errcnt;
20 32
820 type == HIST_INPUT ? _("Input Line") : 832 type == HIST_INPUT ? _("Input Line") :
821 _("Debug Line")); 833 _("Debug Line"));
822 if (num_saved > hislen) 834 if (num_saved > hislen)
823 num_saved = hislen; 835 num_saved = hislen;
824 836
825 /* 837 // Merge typed and viminfo history:
826 * Merge typed and viminfo history: 838 // round 1: history of typed commands.
827 * round 1: history of typed commands. 839 // round 2: history from recently read viminfo.
828 * round 2: history from recently read viminfo.
829 */
830 for (round = 1; round <= 2; ++round) 840 for (round = 1; round <= 2; ++round)
831 { 841 {
832 if (round == 1) 842 if (round == 1)
833 // start at newest entry, somewhere in the list 843 // start at newest entry, somewhere in the list
834 i = *hisidx; 844 i = *hisidx;
2669 garray_T values; 2679 garray_T values;
2670 bval_T *vp; 2680 bval_T *vp;
2671 int i; 2681 int i;
2672 int read_next = TRUE; 2682 int read_next = TRUE;
2673 2683
2674 /* 2684 // The format is: |{bartype},{value},...
2675 * The format is: |{bartype},{value},... 2685 // For a very long string:
2676 * For a very long string: 2686 // |{bartype},>{length of "{text}{text2}"}
2677 * |{bartype},>{length of "{text}{text2}"} 2687 // |<{text1}
2678 * |<{text1} 2688 // |<{text2},{value}
2679 * |<{text2},{value} 2689 // For a long line not using a string
2680 * For a long line not using a string 2690 // |{bartype},{lots of values},>
2681 * |{bartype},{lots of values},> 2691 // |<{value},{value}
2682 * |<{value},{value}
2683 */
2684 if (*p == '<') 2692 if (*p == '<')
2685 { 2693 {
2686 // Continuation line of an unrecognized item. 2694 // Continuation line of an unrecognized item.
2687 if (writing) 2695 if (writing)
2688 ga_add_string(&virp->vir_barlines, virp->vir_line); 2696 ga_add_string(&virp->vir_barlines, virp->vir_line);
3030 goto end; 3038 goto end;
3031 fp_out = fdopen(fd, WRITEBIN); 3039 fp_out = fdopen(fd, WRITEBIN);
3032 } 3040 }
3033 else 3041 else
3034 { 3042 {
3035 /* 3043 // There is an existing viminfo file. Create a temporary file to
3036 * There is an existing viminfo file. Create a temporary file to 3044 // write the new viminfo into, in the same directory as the
3037 * write the new viminfo into, in the same directory as the 3045 // existing viminfo file, which will be renamed once all writing is
3038 * existing viminfo file, which will be renamed once all writing is 3046 // successful.
3039 * successful.
3040 */
3041 #ifdef UNIX 3047 #ifdef UNIX
3042 /* 3048 // For Unix we check the owner of the file. It's not very nice to
3043 * For Unix we check the owner of the file. It's not very nice to 3049 // overwrite a user's viminfo file after a "su root", with a
3044 * overwrite a user's viminfo file after a "su root", with a 3050 // viminfo file that the user can't read.
3045 * viminfo file that the user can't read.
3046 */
3047 st_old.st_dev = (dev_t)0; 3051 st_old.st_dev = (dev_t)0;
3048 st_old.st_ino = 0; 3052 st_old.st_ino = 0;
3049 st_old.st_mode = 0600; 3053 st_old.st_mode = 0600;
3050 if (mch_stat((char *)fname, &st_old) == 0 3054 if (mch_stat((char *)fname, &st_old) == 0
3051 && getuid() != ROOT_UID 3055 && getuid() != ROOT_UID
3067 #ifdef MSWIN 3071 #ifdef MSWIN
3068 // Get the file attributes of the existing viminfo file. 3072 // Get the file attributes of the existing viminfo file.
3069 hidden = mch_ishidden(fname); 3073 hidden = mch_ishidden(fname);
3070 #endif 3074 #endif
3071 3075
3072 /* 3076 // Make tempname, find one that does not exist yet.
3073 * Make tempname, find one that does not exist yet. 3077 // Beware of a race condition: If someone logs out and all Vim
3074 * Beware of a race condition: If someone logs out and all Vim 3078 // instances exit at the same time a temp file might be created between
3075 * instances exit at the same time a temp file might be created between 3079 // stat() and open(). Use mch_open() with O_EXCL to avoid that.
3076 * stat() and open(). Use mch_open() with O_EXCL to avoid that. 3080 // May try twice: Once normal and once with shortname set, just in
3077 * May try twice: Once normal and once with shortname set, just in 3081 // case somebody puts his viminfo file in an 8.3 filesystem.
3078 * case somebody puts his viminfo file in an 8.3 filesystem.
3079 */
3080 for (;;) 3082 for (;;)
3081 { 3083 {
3082 int next_char = 'z'; 3084 int next_char = 'z';
3083 char_u *wp; 3085 char_u *wp;
3084 3086
3096 #endif 3098 #endif
3097 FALSE); 3099 FALSE);
3098 if (tempname == NULL) // out of memory 3100 if (tempname == NULL) // out of memory
3099 break; 3101 break;
3100 3102
3101 /* 3103 // Try a series of names. Change one character, just before
3102 * Try a series of names. Change one character, just before 3104 // the extension. This should also work for an 8.3
3103 * the extension. This should also work for an 8.3 3105 // file name, when after adding the extension it still is
3104 * file name, when after adding the extension it still is 3106 // the same file as the original.
3105 * the same file as the original.
3106 */
3107 wp = tempname + STRLEN(tempname) - 5; 3107 wp = tempname + STRLEN(tempname) - 5;
3108 if (wp < gettail(tempname)) // empty file name? 3108 if (wp < gettail(tempname)) // empty file name?
3109 wp = gettail(tempname); 3109 wp = gettail(tempname);
3110 for (;;) 3110 for (;;)
3111 { 3111 {
3112 /* 3112 // Check if tempfile already exists. Never overwrite an
3113 * Check if tempfile already exists. Never overwrite an 3113 // existing file!
3114 * existing file!
3115 */
3116 if (mch_stat((char *)tempname, &st_new) == 0) 3114 if (mch_stat((char *)tempname, &st_new) == 0)
3117 { 3115 {
3118 #ifdef UNIX 3116 #ifdef UNIX
3119 /* 3117 // Check if tempfile is same as original file. May happen
3120 * Check if tempfile is same as original file. May happen 3118 // when modname() gave the same file back. E.g. silly
3121 * when modname() gave the same file back. E.g. silly 3119 // link, or file name-length reached. Try again with
3122 * link, or file name-length reached. Try again with 3120 // shortname set.
3123 * shortname set.
3124 */
3125 if (!shortname && st_new.st_dev == st_old.st_dev 3121 if (!shortname && st_new.st_dev == st_old.st_dev
3126 && st_new.st_ino == st_old.st_ino) 3122 && st_new.st_ino == st_old.st_ino)
3127 { 3123 {
3128 VIM_CLEAR(tempname); 3124 VIM_CLEAR(tempname);
3129 shortname = TRUE; 3125 shortname = TRUE;
3197 #if defined(UNIX) && defined(HAVE_FCHOWN) 3193 #if defined(UNIX) && defined(HAVE_FCHOWN)
3198 if (tempname != NULL && fp_out != NULL) 3194 if (tempname != NULL && fp_out != NULL)
3199 { 3195 {
3200 stat_T tmp_st; 3196 stat_T tmp_st;
3201 3197
3202 /* 3198 // Make sure the original owner can read/write the tempfile and
3203 * Make sure the original owner can read/write the tempfile and 3199 // otherwise preserve permissions, making sure the group matches.
3204 * otherwise preserve permissions, making sure the group matches.
3205 */
3206 if (mch_stat((char *)tempname, &tmp_st) >= 0) 3200 if (mch_stat((char *)tempname, &tmp_st) >= 0)
3207 { 3201 {
3208 if (st_old.st_uid != tmp_st.st_uid) 3202 if (st_old.st_uid != tmp_st.st_uid)
3209 // Changing the owner might fail, in which case the 3203 // Changing the owner might fail, in which case the
3210 // file will now owned by the current user, oh well. 3204 // file will now owned by the current user, oh well.
3220 (void)mch_setperm(tempname, 0600); 3214 (void)mch_setperm(tempname, 0600);
3221 } 3215 }
3222 #endif 3216 #endif
3223 } 3217 }
3224 3218
3225 /* 3219 // Check if the new viminfo file can be written to.
3226 * Check if the new viminfo file can be written to.
3227 */
3228 if (fp_out == NULL) 3220 if (fp_out == NULL)
3229 { 3221 {
3230 semsg(_("E138: Can't write viminfo file %s!"), 3222 semsg(_("E138: Can't write viminfo file %s!"),
3231 (fp_in == NULL || tempname == NULL) ? fname : tempname); 3223 (fp_in == NULL || tempname == NULL) ? fname : tempname);
3232 if (fp_in != NULL) 3224 if (fp_in != NULL)