From a890c019a3689fc15d8a5710cfc0cb92c5ac041d Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Fri, 8 Jul 2022 11:01:46 +0800 Subject: vim-patch:8.2.0132: script may be re-used when deleting and creating a new one Problem: Script may be re-used when deleting and creating a new one. Solution: When the inode matches, also check the file name. https://github.com/vim/vim/commit/ca33eb256eb910af05e8c9852bc9f716cece1f5c --- src/nvim/ex_cmds2.c | 21 ++++++++++++--------- src/nvim/testdir/test_source.vim | 12 ++++++++++++ 2 files changed, 24 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c index defe22ea9a..82970e2566 100644 --- a/src/nvim/ex_cmds2.c +++ b/src/nvim/ex_cmds2.c @@ -2161,16 +2161,19 @@ scriptitem_T *get_current_script_id(char_u *fname, sctx_T *ret_sctx) bool file_id_ok = os_fileid((char *)fname, &file_id); assert(script_items.ga_len >= 0); - for (script_sctx.sc_sid = script_items.ga_len; script_sctx.sc_sid > 0; - script_sctx.sc_sid--) { + for (script_sctx.sc_sid = script_items.ga_len; script_sctx.sc_sid > 0; script_sctx.sc_sid--) { si = &SCRIPT_ITEM(script_sctx.sc_sid); - // Compare dev/ino when possible, it catches symbolic links. - // Also compare file names, the inode may change when the file was edited. - bool file_id_equal = file_id_ok && si->file_id_valid - && os_fileid_equal(&(si->file_id), &file_id); - if (si->sn_name != NULL - && (file_id_equal || FNAMECMP(si->sn_name, fname) == 0)) { - break; + if (si->sn_name != NULL) { + // 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 (file_id_ok && si->file_id_valid && !os_fileid_equal(&(si->file_id), &file_id)) { + continue; + } + if (FNAMECMP(si->sn_name, fname) == 0) { + // Found it! + break; + } } } if (script_sctx.sc_sid == 0) { diff --git a/src/nvim/testdir/test_source.vim b/src/nvim/testdir/test_source.vim index 09baec0b7d..a5f5d1fd89 100644 --- a/src/nvim/testdir/test_source.vim +++ b/src/nvim/testdir/test_source.vim @@ -46,3 +46,15 @@ func Test_source_sandbox() bwipe! call delete('Xsourcehello') endfunc + +" When deleting a file and immediately creating a new one the inode may be +" recycled. Vim should not recognize it as the same script. +func Test_different_script() + call ch_logfile('logfile', 'w') + call writefile(['let s:var = "asdf"'], 'XoneScript') + source XoneScript + call delete('XoneScript') + call writefile(['let g:var = s:var'], 'XtwoScript') + call assert_fails('source XtwoScript', 'E121:') + call delete('XtwoScript') +endfunc -- cgit From eafa09de7d4129fee10e0558ee8e47a49758f0fe Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Fri, 8 Jul 2022 11:03:33 +0800 Subject: vim-patch:8.2.0136: stray ch_logfile() call Problem: Stray ch_logfile() call. Solution: Remove it. (closes vim/vim#5503) https://github.com/vim/vim/commit/ed5adff1e6da412732514d82363005f85fe22e04 --- src/nvim/testdir/test_source.vim | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/nvim/testdir/test_source.vim b/src/nvim/testdir/test_source.vim index a5f5d1fd89..b8fe8422b3 100644 --- a/src/nvim/testdir/test_source.vim +++ b/src/nvim/testdir/test_source.vim @@ -50,7 +50,6 @@ endfunc " When deleting a file and immediately creating a new one the inode may be " recycled. Vim should not recognize it as the same script. func Test_different_script() - call ch_logfile('logfile', 'w') call writefile(['let s:var = "asdf"'], 'XoneScript') source XoneScript call delete('XoneScript') -- cgit From 159a0b651ff27fc5610ba8630b92d31f79664f4d Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Fri, 8 Jul 2022 11:26:03 +0800 Subject: vim-patch:8.2.0151: detecting a script was already sourced is unreliable Problem: Detecting a script was already sourced is unreliable. Solution: Do not use the inode number. https://github.com/vim/vim/commit/978d170bdce9c0a47e6683cd7c288bc2706f3fff --- src/nvim/ex_cmds2.c | 27 ++++++++------------------- src/nvim/ex_cmds2.h | 4 ---- 2 files changed, 8 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c index 82970e2566..897928abec 100644 --- a/src/nvim/ex_cmds2.c +++ b/src/nvim/ex_cmds2.c @@ -2156,34 +2156,23 @@ scriptitem_T *get_current_script_id(char_u *fname, sctx_T *ret_sctx) sctx_T script_sctx = { .sc_seq = ++last_current_SID_seq, .sc_lnum = 0, .sc_sid = 0 }; - FileID file_id; scriptitem_T *si = NULL; - bool file_id_ok = os_fileid((char *)fname, &file_id); assert(script_items.ga_len >= 0); for (script_sctx.sc_sid = script_items.ga_len; script_sctx.sc_sid > 0; script_sctx.sc_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(script_sctx.sc_sid); - if (si->sn_name != NULL) { - // 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 (file_id_ok && si->file_id_valid && !os_fileid_equal(&(si->file_id), &file_id)) { - continue; - } - if (FNAMECMP(si->sn_name, fname) == 0) { - // Found it! - break; - } + if (si->sn_name != NULL && FNAMECMP(si->sn_name, fname) == 0) { + // Found it! + break; } } if (script_sctx.sc_sid == 0) { si = new_script_item((char *)vim_strsave(fname), &script_sctx.sc_sid); - if (file_id_ok) { - si->file_id_valid = true; - si->file_id = file_id; - } else { - si->file_id_valid = false; - } } if (ret_sctx != NULL) { *ret_sctx = script_sctx; diff --git a/src/nvim/ex_cmds2.h b/src/nvim/ex_cmds2.h index 74e52dfb4b..c463bfa5ab 100644 --- a/src/nvim/ex_cmds2.h +++ b/src/nvim/ex_cmds2.h @@ -15,12 +15,8 @@ #define CCGD_ALLBUF 8 // may write all buffers #define CCGD_EXCMD 16 // may suggest using ! -/// Also store the dev/ino, so that we don't have to stat() each -/// script when going through the list. typedef struct scriptitem_S { char_u *sn_name; - bool file_id_valid; - FileID file_id; bool sn_prof_on; ///< true when script is/was profiled bool sn_pr_force; ///< forceit: profile functions in this script proftime_T sn_pr_child; ///< time set when going into first child -- cgit