]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 8.2.0151: detecting a script was already sourced is unreliable v8.2.0151
authorBram Moolenaar <Bram@vim.org>
Sun, 26 Jan 2020 16:38:12 +0000 (17:38 +0100)
committerBram Moolenaar <Bram@vim.org>
Sun, 26 Jan 2020 16:38:12 +0000 (17:38 +0100)
Problem:    Detecting a script was already sourced is unreliable.
Solution:   Do not use the inode number.

src/scriptfile.c
src/structs.h
src/testdir/test_vim9_script.vim
src/version.c

index 120c64351e94af5b2d80b89869dca9e2bdb53124..376e0c3e6113ccf1d381d0a6a5e5aa215a9f7011 100644 (file)
@@ -1091,10 +1091,6 @@ do_source(
     int                            save_debug_break_level = debug_break_level;
     int                            sid;
     scriptitem_T           *si = NULL;
-# ifdef UNIX
-    stat_T                 st;
-    int                            stat_ok;
-# endif
 #endif
 #ifdef STARTUPTIME
     struct timeval         tv_rel;
@@ -1121,26 +1117,17 @@ do_source(
 
 #ifdef FEAT_EVAL
     // See if we loaded this script before.
-# ifdef UNIX
-    stat_ok = (mch_stat((char *)fname_exp, &st) >= 0);
-# endif
     for (sid = script_items.ga_len; sid > 0; --sid)
     {
+       // We used to check inode here, but that doesn't work:
+       // - If a script is edited and written, it may get a different
+       //   inode number, even though to the user it is the same script.
+       // - If a script is deleted and another script is written, with a
+       //   different name, the inode may be re-used.
        si = &SCRIPT_ITEM(sid);
-       if (si->sn_name != NULL)
-       {
-# ifdef UNIX
-           // Compare dev/ino when possible, it catches symbolic links.  Also
-           // compare file names, the inode may change when the file was
-           // edited or it may be re-used for another script (esp. in tests).
-           if ((stat_ok && si->sn_dev_valid)
-                      && (si->sn_dev != st.st_dev || si->sn_ino != st.st_ino))
-               continue;
-# endif
-           if (fnamecmp(si->sn_name, fname_exp) == 0)
+       if (si->sn_name != NULL && fnamecmp(si->sn_name, fname_exp) == 0)
                // Found it!
                break;
-       }
     }
     if (sid > 0 && ret_sid != NULL)
     {
@@ -1324,16 +1311,6 @@ do_source(
        si = &SCRIPT_ITEM(current_sctx.sc_sid);
        si->sn_name = fname_exp;
        fname_exp = vim_strsave(si->sn_name);  // used for autocmd
-# ifdef UNIX
-       if (stat_ok)
-       {
-           si->sn_dev_valid = TRUE;
-           si->sn_dev = st.st_dev;
-           si->sn_ino = st.st_ino;
-       }
-       else
-           si->sn_dev_valid = FALSE;
-# endif
        if (ret_sid != NULL)
            *ret_sid = current_sctx.sc_sid;
     }
index 201a89bceacc7e877d5c0df7f468f261cc14a668..74bc2ff6ebd9f135c6b6373662706faa32c6a247 100644 (file)
@@ -1665,11 +1665,6 @@ typedef struct
     int                sn_had_command; // TRUE if any command was executed
     char_u     *sn_save_cpo;   // 'cpo' value when :vim9script found
 
-# ifdef UNIX
-    int                sn_dev_valid;
-    dev_t      sn_dev;
-    ino_t      sn_ino;
-# endif
 # ifdef FEAT_PROFILE
     int                sn_prof_on;     // TRUE when script is/was profiled
     int                sn_pr_force;    // forceit: profile functions in this script
index d6a78544b744ff665fd26315bbceb4c49a406970..09bf3247ab4007f61688edcf580520ac2832fbb6 100644 (file)
@@ -4,7 +4,7 @@ source check.vim
 
 " Check that "lines" inside ":def" results in an "error" message.
 func CheckDefFailure(lines, error)
-  call writefile(['def! Func()'] + a:lines + ['enddef'], 'Xdef')
+  call writefile(['def Func()'] + a:lines + ['enddef'], 'Xdef')
   call assert_fails('so Xdef', a:error, a:lines)
   call delete('Xdef')
 endfunc
@@ -126,10 +126,10 @@ enddef
 
 def Test_return_type_wrong()
   " TODO: why is ! needed for Mac and FreeBSD?
-  CheckScriptFailure(['def! Func(): number', 'return "a"', 'enddef'], 'expected number but got string')
-  CheckScriptFailure(['def! Func(): string', 'return 1', 'enddef'], 'expected string but got number')
-  CheckScriptFailure(['def! Func(): void', 'return "a"', 'enddef'], 'expected void but got string')
-  CheckScriptFailure(['def! Func()', 'return "a"', 'enddef'], 'expected void but got string')
+  CheckScriptFailure(['def Func(): number', 'return "a"', 'enddef'], 'expected number but got string')
+  CheckScriptFailure(['def Func(): string', 'return 1', 'enddef'], 'expected string but got number')
+  CheckScriptFailure(['def Func(): void', 'return "a"', 'enddef'], 'expected void but got string')
+  CheckScriptFailure(['def Func()', 'return "a"', 'enddef'], 'expected void but got string')
 enddef
 
 def Test_try_catch()
index 159d550363a7599d44cb5df1fb6ed41cd30dce85..88fadc7490ae801b020da944e962b611897d7170 100644 (file)
@@ -742,6 +742,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    151,
 /**/
     150,
 /**/