To: vim_dev@googlegroups.com Subject: Patch 9.0.0220 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 9.0.0220 Problem: Invalid memory access with for loop over NULL string. Solution: Make sure mb_ptr2len() consistently returns zero for NUL. Files: src/globals.h, src/mbyte.c, src/testdir/test_eval_stuff.vim *** ../vim-9.0.0219/src/globals.h 2022-07-31 11:37:16.447058514 +0100 --- src/globals.h 2022-08-16 17:47:21.316417137 +0100 *************** *** 1035,1041 **** * (DBCS). * The value is set in mb_init(); */ ! // length of char in bytes, including following composing chars EXTERN int (*mb_ptr2len)(char_u *p) INIT(= latin_ptr2len); // idem, with limit on string length --- 1035,1042 ---- * (DBCS). * The value is set in mb_init(); */ ! // 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 *** ../vim-9.0.0219/src/mbyte.c 2022-08-09 12:53:09.907689958 +0100 --- src/mbyte.c 2022-08-16 17:49:02.276073146 +0100 *************** *** 1077,1100 **** } /* ! * 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. */ int latin_ptr2len(char_u *p) { ! return MB_BYTE2LEN(*p); } static int ! dbcs_ptr2len( ! char_u *p) { int len; ! // Check if second byte is not missing. len = MB_BYTE2LEN(*p); if (len == 2 && p[1] == NUL) len = 1; --- 1077,1104 ---- } /* ! * 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 *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) { int len; ! 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,2110 **** --- 2109,2115 ---- /* * 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) *** ../vim-9.0.0219/src/testdir/test_eval_stuff.vim 2022-07-29 15:28:24.019397903 +0100 --- src/testdir/test_eval_stuff.vim 2022-08-16 17:36:39.882781721 +0100 *************** *** 75,80 **** --- 75,92 ---- 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']) *** ../vim-9.0.0219/src/version.c 2022-08-16 16:09:53.599527502 +0100 --- src/version.c 2022-08-16 17:21:58.235446605 +0100 *************** *** 737,738 **** --- 737,740 ---- { /* Add new patch number below this line */ + /**/ + 220, /**/ -- Witches prefer brooms: vacuum-cleaners need extension cords! /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///