To: vim_dev@googlegroups.com Subject: Patch 8.2.4924 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.4924 Problem: maparg() may return a string that cannot be reused. Solution: use msg_outtrans_special() instead of str2special(). (closes #10384) Files: src/message.c, src/option.c, src/testdir/test_map_functions.vim, src/testdir/test_mapping.vim, src/testdir/test_options.vim *** ../vim-8.2.4923/src/message.c 2022-05-07 20:01:10.058731693 +0100 --- src/message.c 2022-05-09 12:13:51.725297561 +0100 *************** *** 1721,1726 **** --- 1721,1729 ---- } else text = (char *)str2special(&str, from); + if (text[0] != NUL && text[1] == NUL) + // single-byte character or illegal byte + text = (char *)transchar_byte((char_u)text[0]); len = vim_strsize((char_u *)text); if (maxlen > 0 && retval + len >= maxlen) break; *************** *** 1755,1760 **** --- 1758,1764 ---- /* * Return the printable string for the key codes at "*sp". + * On illegal byte return a string with only that byte. * Used for translating the lhs or rhs of a mapping to printable chars. * Advances "sp" to the next code. */ *************** *** 1798,1835 **** special = TRUE; } ! if (has_mbyte && !IS_SPECIAL(c)) { char_u *p; *sp = str; // Try to un-escape a multi-byte character after modifiers. p = mb_unescape(sp); ! ! if (p == NULL) ! { ! int len = (*mb_ptr2len)(str); ! ! // Check for an illegal byte. ! if (MB_BYTE2LEN(*str) > len) ! { ! transchar_nonprint(curbuf, buf, c); ! *sp = str + 1; ! return buf; ! } ! *sp = str + len; ! p = str; ! } ! // Since 'special' is TRUE the multi-byte character 'c' will be ! // processed by get_special_key_name() ! c = (*mb_ptr2char)(p); } else *sp = str + 1; ! // Make unprintable characters in <> form, also and . // Use only for lhs of a mapping. ! if (special || char2cells(c) > 1 || (from && c == ' ')) return get_special_key_name(c, modifiers); buf[0] = c; buf[1] = NUL; --- 1802,1829 ---- special = TRUE; } ! if (has_mbyte && !IS_SPECIAL(c) && MB_BYTE2LEN(c) > 1) { char_u *p; *sp = str; // Try to un-escape a multi-byte character after modifiers. p = mb_unescape(sp); ! if (p != NULL) ! // Since 'special' is TRUE the multi-byte character 'c' will be ! // processed by get_special_key_name() ! c = (*mb_ptr2char)(p); ! else ! // illegal byte ! *sp = str + 1; } else + // single-byte character or illegal byte *sp = str + 1; ! // Make special keys and C0 control characters in <> form, also . // Use only for lhs of a mapping. ! if (special || c < ' ' || (from && c == ' ')) return get_special_key_name(c, modifiers); buf[0] = c; buf[1] = NUL; *** ../vim-8.2.4923/src/option.c 2022-05-08 21:10:52.653899496 +0100 --- src/option.c 2022-05-09 12:13:51.725297561 +0100 *************** *** 4017,4022 **** --- 4017,4024 ---- if ((char_u **)varp == &curbuf->b_p_key && **(char_u **)(varp) != NUL) *stringval = vim_strsave((char_u *)"*****"); + else if ((char_u **)varp == &p_pt) // 'pastetoggle' + *stringval = str2special_save(*(char_u **)(varp), FALSE); else #endif *stringval = vim_strsave(*(char_u **)(varp)); *** ../vim-8.2.4923/src/testdir/test_map_functions.vim 2022-05-04 15:40:16.032317666 +0100 --- src/testdir/test_map_functions.vim 2022-05-09 12:13:51.725297561 +0100 *************** *** 58,63 **** --- 58,77 ---- map abc yy call assert_equal("yRy", maparg('abc')) + " character with K_SPECIAL byte + nmap abc … + call assert_equal('…', maparg('abc')) + + " modified character with K_SPECIAL byte + nmap abc + call assert_equal('', maparg('abc')) + + " illegal bytes + let str = ":\x7f:\x80:\x90:\xd0:" + exe 'nmap abc ' .. str + call assert_equal(str, maparg('abc')) + unlet str + omap { w let d = maparg('{', 'o', 0, 1) call assert_equal(['{', 'w', 'o'], [d.lhs, d.rhs, d.mode]) *** ../vim-8.2.4923/src/testdir/test_mapping.vim 2022-05-04 18:51:38.178683646 +0100 --- src/testdir/test_mapping.vim 2022-05-09 12:13:51.725297561 +0100 *************** *** 502,507 **** --- 502,514 ---- call assert_equal(['n foo'], \ execute('nmap ')->trim()->split("\n")) + " illegal bytes + let str = ":\x7f:\x80:\x90:\xd0:" + exe 'nmap foo ' .. str + call assert_equal(['n foo ' .. strtrans(str)], + \ execute('nmap foo')->trim()->split("\n")) + unlet str + " map to CTRL-V exe "nmap ,k \" call assert_equal(['n ,k '], *** ../vim-8.2.4923/src/testdir/test_options.vim 2022-05-08 21:10:52.653899496 +0100 --- src/testdir/test_options.vim 2022-05-09 12:13:51.725297561 +0100 *************** *** 48,53 **** --- 48,73 ---- set isfname& endfunc + " Test for getting the value of 'pastetoggle' + func Test_pastetoggle() + " character with K_SPECIAL byte + let &pastetoggle = '…' + call assert_equal('…', &pastetoggle) + call assert_equal("\n pastetoggle=…", execute('set pastetoggle?')) + + " modified character with K_SPECIAL byte + let &pastetoggle = '' + call assert_equal('', &pastetoggle) + call assert_equal("\n pastetoggle=", execute('set pastetoggle?')) + + " illegal bytes + let str = ":\x7f:\x80:\x90:\xd0:" + let &pastetoggle = str + call assert_equal(str, &pastetoggle) + call assert_equal("\n pastetoggle=" .. strtrans(str), execute('set pastetoggle?')) + unlet str + endfunc + func Test_wildchar() " Empty 'wildchar' used to access invalid memory. call assert_fails('set wildchar=', 'E521:') *** ../vim-8.2.4923/src/version.c 2022-05-09 11:03:16.156322033 +0100 --- src/version.c 2022-05-09 12:15:29.773140926 +0100 *************** *** 748,749 **** --- 748,751 ---- { /* Add new patch number below this line */ + /**/ + 4924, /**/ -- Fingers not found - Pound head on keyboard to continue. /// 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 ///