Skip to content

Commit

Permalink
patch 9.0.0220: invalid memory access with for loop over NULL string
Browse files Browse the repository at this point in the history
Problem:    Invalid memory access with for loop over NULL string.
Solution:   Make sure mb_ptr2len() consistently returns zero for NUL.
  • Loading branch information
brammool committed Aug 16, 2022
1 parent 948a389 commit f6d39c3
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 9 deletions.
3 changes: 2 additions & 1 deletion src/globals.h
Expand Up @@ -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
Expand Down
21 changes: 13 additions & 8 deletions src/mbyte.c
Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand Down
12 changes: 12 additions & 0 deletions src/testdir/test_eval_stuff.vim
Expand Up @@ -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'])
Expand Down
2 changes: 2 additions & 0 deletions src/version.c
Expand Up @@ -735,6 +735,8 @@ static char *(features[]) =

static int included_patches[] =
{ /* Add new patch number below this line */
/**/
220,
/**/
219,
/**/
Expand Down

0 comments on commit f6d39c3

Please sign in to comment.