To: vim_dev@googlegroups.com Subject: Patch 8.2.0151 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.0151 Problem: Detecting a script was already sourced is unreliable. Solution: Do not use the inode number. Files: src/scriptfile.c, src/structs.h, src/testdir/test_vim9_script.vim *** ../vim-8.2.0150/src/scriptfile.c 2020-01-26 15:52:33.023833239 +0100 --- src/scriptfile.c 2020-01-26 17:23:56.403930133 +0100 *************** *** 1091,1100 **** 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; --- 1091,1096 ---- *************** *** 1121,1146 **** #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) { 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) // Found it! break; - } } if (sid > 0 && ret_sid != NULL) { --- 1117,1133 ---- #ifdef FEAT_EVAL // See if we loaded this script before. 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 && fnamecmp(si->sn_name, fname_exp) == 0) // Found it! break; } if (sid > 0 && ret_sid != NULL) { *************** *** 1324,1339 **** 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; } --- 1311,1316 ---- *** ../vim-8.2.0150/src/structs.h 2020-01-26 15:52:33.023833239 +0100 --- src/structs.h 2020-01-26 17:22:19.944327072 +0100 *************** *** 1665,1675 **** 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 --- 1665,1670 ---- *** ../vim-8.2.0150/src/testdir/test_vim9_script.vim 2020-01-26 16:50:02.522754194 +0100 --- src/testdir/test_vim9_script.vim 2020-01-26 17:24:37.207761741 +0100 *************** *** 4,10 **** " Check that "lines" inside ":def" results in an "error" message. func CheckDefFailure(lines, error) ! call writefile(['def! Func()'] + a:lines + ['enddef'], 'Xdef') call assert_fails('so Xdef', a:error, a:lines) call delete('Xdef') endfunc --- 4,10 ---- " Check that "lines" inside ":def" results in an "error" message. func CheckDefFailure(lines, error) ! call writefile(['def Func()'] + a:lines + ['enddef'], 'Xdef') call assert_fails('so Xdef', a:error, a:lines) call delete('Xdef') endfunc *************** *** 126,135 **** 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') enddef def Test_try_catch() --- 126,135 ---- 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') enddef def Test_try_catch() *** ../vim-8.2.0150/src/version.c 2020-01-26 16:50:02.526754177 +0100 --- src/version.c 2020-01-26 17:33:00.941650851 +0100 *************** *** 744,745 **** --- 744,747 ---- { /* Add new patch number below this line */ + /**/ + 151, /**/ -- Article in the first Free Software Magazine: "Bram Moolenaar studied electrical engineering at the Technical University of Delft and graduated in 1985 on a multi-processor Unix architecture." Response by "dimator": Could the school not afford a proper stage for the ceremony? /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///