summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2020-01-26 17:38:12 +0100
committerBram Moolenaar <Bram@vim.org>2020-01-26 17:38:12 +0100
commit978d170bdce9c0a47e6683cd7c288bc2706f3fff (patch)
treed534d8a976251fb00bbb14b76faac7d8b8a69ee5
parent673660ab00d808d1e96e7181a60c5c8545c0ee75 (diff)
patch 8.2.0151: detecting a script was already sourced is unreliablev8.2.0151
Problem: Detecting a script was already sourced is unreliable. Solution: Do not use the inode number.
-rw-r--r--src/scriptfile.c35
-rw-r--r--src/structs.h5
-rw-r--r--src/testdir/test_vim9_script.vim10
-rw-r--r--src/version.c2
4 files changed, 13 insertions, 39 deletions
diff --git a/src/scriptfile.c b/src/scriptfile.c
index 120c64351e..376e0c3e61 100644
--- a/src/scriptfile.c
+++ b/src/scriptfile.c
@@ -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;
}
diff --git a/src/structs.h b/src/structs.h
index 201a89bcea..74bc2ff6eb 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -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
diff --git a/src/testdir/test_vim9_script.vim b/src/testdir/test_vim9_script.vim
index d6a78544b7..09bf3247ab 100644
--- a/src/testdir/test_vim9_script.vim
+++ b/src/testdir/test_vim9_script.vim
@@ -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()
diff --git a/src/version.c b/src/version.c
index 159d550363..88fadc7490 100644
--- a/src/version.c
+++ b/src/version.c
@@ -743,6 +743,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 151,
+/**/
150,
/**/
149,