summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2023-01-04 15:56:51 +0000
committerBram Moolenaar <Bram@vim.org>2023-01-04 15:56:51 +0000
commitc32949b0779106ed5710ae3bffc5053e49083ab4 (patch)
tree14e2027724e250793fe942805c894b278d31321f
parent7b17eb4b063a234376c1ec909ee293e42cff290c (diff)
downloadvim-git-c32949b0779106ed5710ae3bffc5053e49083ab4.tar.gz
patch 9.0.1144: reading beyond textv9.0.1144
Problem: Reading beyond text. Solution: Add strlen_maxlen() and use it.
-rw-r--r--src/message.c3
-rw-r--r--src/proto/strings.pro1
-rw-r--r--src/strings.c15
-rw-r--r--src/testdir/test_cmdline.vim11
-rw-r--r--src/version.c2
5 files changed, 30 insertions, 2 deletions
diff --git a/src/message.c b/src/message.c
index 591691f3f..bb3517c94 100644
--- a/src/message.c
+++ b/src/message.c
@@ -3055,7 +3055,8 @@ msg_puts_printf(char_u *str, int maxlen)
{
char_u *tofree = NULL;
- if (maxlen > 0 && STRLEN(p) > (size_t)maxlen)
+ if (maxlen > 0 && vim_strlen_maxlen((char *)p, (size_t)maxlen)
+ >= (size_t)maxlen)
{
tofree = vim_strnsave(p, (size_t)maxlen);
p = tofree;
diff --git a/src/proto/strings.pro b/src/proto/strings.pro
index 50bbf29fe..602208831 100644
--- a/src/proto/strings.pro
+++ b/src/proto/strings.pro
@@ -12,6 +12,7 @@ char_u *strlow_save(char_u *orig);
void del_trailing_spaces(char_u *ptr);
void vim_strncpy(char_u *to, char_u *from, size_t len);
void vim_strcat(char_u *to, char_u *from, size_t tosize);
+size_t vim_strlen_maxlen(char *s, size_t maxlen);
int vim_stricmp(char *s1, char *s2);
int vim_strnicmp(char *s1, char *s2, size_t len);
char_u *vim_strchr(char_u *string, int c);
diff --git a/src/strings.c b/src/strings.c
index edcae6f8a..917426599 100644
--- a/src/strings.c
+++ b/src/strings.c
@@ -525,6 +525,19 @@ vim_strcat(char_u *to, char_u *from, size_t tosize)
mch_memmove(to + tolen, from, fromlen + 1);
}
+/*
+ * A version of strlen() that has a maximum length.
+ */
+ size_t
+vim_strlen_maxlen(char *s, size_t maxlen)
+{
+ size_t i;
+ for (i = 0; i < maxlen; ++i)
+ if (s[i] == NUL)
+ break;
+ return i;
+}
+
#if (!defined(HAVE_STRCASECMP) && !defined(HAVE_STRICMP)) || defined(PROTO)
/*
* Compare two strings, ignoring case, using current locale.
@@ -582,7 +595,7 @@ vim_strnicmp(char *s1, char *s2, size_t len)
* 128 to 255 correctly. It also doesn't return a pointer to the NUL at the
* end of the string.
*/
- char_u *
+ char_u *
vim_strchr(char_u *string, int c)
{
char_u *p;
diff --git a/src/testdir/test_cmdline.vim b/src/testdir/test_cmdline.vim
index 78f9ba22b..91ff6f156 100644
--- a/src/testdir/test_cmdline.vim
+++ b/src/testdir/test_cmdline.vim
@@ -654,6 +654,17 @@ func Test_getcompletion()
call assert_fails('call getcompletion("abc", [])', 'E1174:')
endfunc
+func Test_multibyte_expression()
+ " This was using uninitialized memory.
+ let lines =<< trim END
+ set verbose=6
+ norm @=ٷ
+ qall!
+ END
+ call writefile(lines, 'XmultiScript', 'D')
+ call RunVim('', '', '-u NONE -n -e -s -S XmultiScript')
+endfunc
+
" Test for getcompletion() with "fuzzy" in 'wildoptions'
func Test_getcompletion_wildoptions()
let save_wildoptions = &wildoptions
diff --git a/src/version.c b/src/version.c
index 4ccbd537a..6e652c697 100644
--- a/src/version.c
+++ b/src/version.c
@@ -696,6 +696,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1144,
+/**/
1143,
/**/
1142,