summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2022-08-16 17:50:38 +0100
committerBram Moolenaar <Bram@vim.org>2022-08-16 17:50:38 +0100
commitf6d39c31d2177549a986d170e192d8351bd571e2 (patch)
tree88571362c680104807bb5201a8e1f52871b8de39
parent948a3894d98f5e2a6e7fc57189fe9c2a5919eebf (diff)
downloadvim-git-f6d39c31d2177549a986d170e192d8351bd571e2.tar.gz
patch 9.0.0220: invalid memory access with for loop over NULL stringv9.0.0220
Problem: Invalid memory access with for loop over NULL string. Solution: Make sure mb_ptr2len() consistently returns zero for NUL.
-rw-r--r--src/globals.h3
-rw-r--r--src/mbyte.c21
-rw-r--r--src/testdir/test_eval_stuff.vim12
-rw-r--r--src/version.c2
4 files changed, 29 insertions, 9 deletions
diff --git a/src/globals.h b/src/globals.h
index 1fadc744f..21fabdbb5 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -1035,7 +1035,8 @@ EXTERN vimconv_T output_conv; // type of output conversion
* (DBCS).
* The value is set in mb_init();
*/
-// length of char in bytes, including following composing chars
+// Length of char in bytes, including any following composing chars.
+// NUL has length zero.
EXTERN int (*mb_ptr2len)(char_u *p) INIT(= latin_ptr2len);
// idem, with limit on string length
diff --git a/src/mbyte.c b/src/mbyte.c
index 941411b4a..73065c739 100644
--- a/src/mbyte.c
+++ b/src/mbyte.c
@@ -1077,24 +1077,28 @@ dbcs_char2bytes(int c, char_u *buf)
}
/*
- * mb_ptr2len() function pointer.
- * Get byte length of character at "*p" but stop at a NUL.
- * For UTF-8 this includes following composing characters.
- * Returns 0 when *p is NUL.
+ * Get byte length of character at "*p". Returns zero when "*p" is NUL.
+ * Used for mb_ptr2len() when 'encoding' latin.
*/
int
latin_ptr2len(char_u *p)
{
- return MB_BYTE2LEN(*p);
+ return *p == NUL ? 0 : 1;
}
+/*
+ * Get byte length of character at "*p". Returns zero when "*p" is NUL.
+ * Used for mb_ptr2len() when 'encoding' DBCS.
+ */
static int
-dbcs_ptr2len(
- char_u *p)
+dbcs_ptr2len(char_u *p)
{
int len;
- // Check if second byte is not missing.
+ if (*p == NUL)
+ return 0;
+
+ // if the second byte is missing the length is 1
len = MB_BYTE2LEN(*p);
if (len == 2 && p[1] == NUL)
len = 1;
@@ -2105,6 +2109,7 @@ utf_ptr2len_len(char_u *p, int size)
/*
* Return the number of bytes the UTF-8 encoding of the character at "p" takes.
* This includes following composing characters.
+ * Returns zero for NUL.
*/
int
utfc_ptr2len(char_u *p)
diff --git a/src/testdir/test_eval_stuff.vim b/src/testdir/test_eval_stuff.vim
index c63082e8e..313d79185 100644
--- a/src/testdir/test_eval_stuff.vim
+++ b/src/testdir/test_eval_stuff.vim
@@ -75,6 +75,18 @@ func Test_for_invalid()
redraw
endfunc
+func Test_for_over_null_string()
+ let save_enc = &enc
+ set enc=iso8859
+ let cnt = 0
+ for c in test_null_string()
+ let cnt += 1
+ endfor
+ call assert_equal(0, cnt)
+
+ let &enc = save_enc
+endfunc
+
func Test_readfile_binary()
new
call setline(1, ['one', 'two', 'three'])
diff --git a/src/version.c b/src/version.c
index 3aff052a7..a6293e0cf 100644
--- a/src/version.c
+++ b/src/version.c
@@ -736,6 +736,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 220,
+/**/
219,
/**/
218,