From d4a8d169a297bfe7aefb80b040062449a3152eaa Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Sat, 29 Nov 2025 10:34:24 -0500 Subject: [PATCH] vim-patch:9.0.0113: has() is not strict about parsing the patch version Problem: has() is not strict about parsing the patch version. Solution: Check the version more strictly. (Ken Takata, closes vim/vim#10752) https://github.com/vim/vim/commit/d90f91fe3075bb51668ed926182b2163da9df001 Co-authored-by: K.Takata --- src/nvim/eval/funcs.c | 27 ++++++++++++++++----------- test/old/testdir/test_expr.vim | 9 +++++++++ 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index e7b0e2bd7b..69a67aabb1 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -2801,18 +2801,23 @@ static void f_has(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) } else if (STRNICMP(name, "patch", 5) == 0) { if (name[5] == '-' && strlen(name) >= 11 - && ascii_isdigit(name[6]) - && ascii_isdigit(name[8]) - && ascii_isdigit(name[10])) { - int major = atoi(name + 6); - int minor = atoi(name + 8); + && (name[6] >= '1' && name[6] <= '9')) { + char *end; - // Expect "patch-9.9.01234". - n = (major < VIM_VERSION_MAJOR - || (major == VIM_VERSION_MAJOR - && (minor < VIM_VERSION_MINOR - || (minor == VIM_VERSION_MINOR - && has_vim_patch(atoi(name + 10)))))); + // This works for patch-8.1.2, patch-9.0.3, patch-10.0.4, etc. + // Not for patch-9.10.5. + int major = (int)strtoul(name + 6, &end, 10); + if (*end == '.' && ascii_isdigit(end[1]) + && end[2] == '.' && ascii_isdigit(end[3])) { + int minor = atoi(end + 1); + + // Expect "patch-9.9.01234". + n = (major < VIM_VERSION_MAJOR + || (major == VIM_VERSION_MAJOR + && (minor < VIM_VERSION_MINOR + || (minor == VIM_VERSION_MINOR + && has_vim_patch(atoi(end + 3)))))); + } } else if (ascii_isdigit(name[5])) { n = has_vim_patch(atoi(name + 5)); } diff --git a/test/old/testdir/test_expr.vim b/test/old/testdir/test_expr.vim index c62dc9845d..c5d3acb9b5 100644 --- a/test/old/testdir/test_expr.vim +++ b/test/old/testdir/test_expr.vim @@ -37,13 +37,22 @@ func Test_version() call assert_true(has('patch-6.9.999')) call assert_true(has('patch-7.1.999')) call assert_true(has('patch-7.4.123')) + call assert_true(has('patch-7.4.123 ')) " Traling space can be allowed. call assert_false(has('patch-7')) call assert_false(has('patch-7.4')) call assert_false(has('patch-7.4.')) call assert_false(has('patch-9.1.0')) call assert_false(has('patch-9.9.1')) + call assert_false(has('patch-abc')) + call assert_false(has('patchabc')) + + call assert_false(has('patch-8x001')) + call assert_false(has('patch-9X0X0')) + call assert_false(has('patch-9-0-0')) + call assert_false(has('patch-09.0.0')) + call assert_false(has('patch-9.00.0')) endfunc func Test_op_ternary()