CVE-2022-0685: Use of Out-of-range Pointer Offset (CWE-823)
value: Use of Out-of-range Pointer Offset in GitHub repository vim/vim prior to 8.2.4418.
CWE description: The product performs pointer arithmetic on a valid pointer, but it uses an offset that can point outside of the intended range of valid memory locations for the resulting pointer.
CVSS v3 base score: 7.8
Published: 2022-02-20T11:15Z
Repository: https://github.com/vim/vim
Language: C
Files changed: src/charset.c, src/filepath.c, src/proto/charset.pro, src/testdir/test_autochdir.vim, src/version.c
Commit date: 2022-02-19 11:20:12 +0000
Commit message: patch 8.2.4418: crash when using special multi-byte character

Problem:    Crash when using special multi-byte character.
Solution:   Don't use isalpha() for an arbitrary character.

Diff: diff --git a/src/charset.c b/src/charset.c
index 2ecb96c894ad..ed09bd23f441 100644
--- a/src/charset.c
+++ b/src/charset.c
@@ -1642,10 +1642,16 @@ vim_isupper(int c)
 	    return (latin1flags[c] & LATIN1UPPER) == LATIN1UPPER;
     }
     return isupper(c);
 }
 
+    int
+vim_isalpha(int c)
+{
+    return vim_islower(c) || vim_isupper(c);
+}
+
     int
 vim_toupper(int c)
 {
     if (c <= '@')
 	return c;
diff --git a/src/filepath.c b/src/filepath.c
index 929fa56a4d05..7a5dae441fd5 100644
--- a/src/filepath.c
+++ b/src/filepath.c
@@ -3624,11 +3624,11 @@ unix_expandpath(
 	    s = p + 1;
 	}
 	else if (path_end >= path + wildoff
 			 && (vim_strchr((char_u *)"*?[{~$", *path_end) != NULL
 			     || (!p_fic && (flags & EW_ICASE)
-					     && isalpha(PTR2CHAR(path_end)))))
+					  && vim_isalpha(PTR2CHAR(path_end)))))
 	    e = p;
 	if (has_mbyte)
 	{
 	    len = (*mb_ptr2len)(path_end);
 	    STRNCPY(p, path_end, len);
diff --git a/src/proto/charset.pro b/src/proto/charset.pro
index ee5370bccdb6..df097109c12e 100644
--- a/src/proto/charset.pro
+++ b/src/proto/charset.pro
@@ -48,10 +48,11 @@ char_u *skiptohex(char_u *q);
 int vim_isdigit(int c);
 int vim_isxdigit(int c);
 int vim_isbdigit(int c);
 int vim_islower(int c);
 int vim_isupper(int c);
+int vim_isalpha(int c);
 int vim_toupper(int c);
 int vim_tolower(int c);
 char_u *skiptowhite(char_u *p);
 char_u *skiptowhite_esc(char_u *p);
 long getdigits(char_u **pp);
@@ -61,7 +62,6 @@ void vim_str2nr(char_u *start, int *prep, int *len, int what, varnumber_T *nptr,
 int hex2nr(int c);
 int hexhex2nr(char_u *p);
 int rem_backslash(char_u *str);
 void backslash_halve(char_u *p);
 char_u *backslash_halve_save(char_u *p);
-void ebcdic2ascii(char_u *buffer, int len);
 /* vim: set ft=c : */
diff --git a/src/testdir/test_autochdir.vim b/src/testdir/test_autochdir.vim
index 5d367757fcc4..95004d278a85 100644
--- a/src/testdir/test_autochdir.vim
+++ b/src/testdir/test_autochdir.vim
@@ -108,6 +108,14 @@ func Test_verbose_pwd()
   bwipe!
   call chdir(cwd)
   call delete('Xautodir', 'rf')
 endfunc
 
+func Test_multibyte()
+  " using an invalid character should not cause a crash
+  set wic
+  call assert_fails('tc û¦*', 'E344:')
+  set nowic
+endfunc
+
+
 " vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/version.c b/src/version.c
index f95b395b7a2e..5cb7218706ce 100644
--- a/src/version.c
+++ b/src/version.c
@@ -748,10 +748,12 @@ static char *(features[]) =
 	NULL
 };
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    4418,
 /**/
     4417,
 /**/
     4416,
 /**/

Vulnerable code: 					     && isalpha(PTR2CHAR(path_end)))))
void ebcdic2ascii(char_u *buffer, int len);
Fixed code:     int
vim_isalpha(int c)
{
    return vim_islower(c) || vim_isupper(c);
}

					  && vim_isalpha(PTR2CHAR(path_end)))))
int vim_isalpha(int c);
func Test_multibyte()
  " using an invalid character should not cause a crash
  set wic
  call assert_fails('tc û¦*', 'E344:')
  set nowic
endfunc


/**/
    4418,