mirror of
https://github.com/neovim/neovim.git
synced 2025-09-06 11:28:22 +00:00
Merge pull request #18491 from zeertzjq/vim-8.2.4924
vim-patch:8.2.4924: maparg() may return a string that cannot be reused
This commit is contained in:
@@ -1618,6 +1618,10 @@ int msg_outtrans_special(const char_u *strstart, bool from, int maxlen)
|
|||||||
} else {
|
} else {
|
||||||
text = str2special((const char **)&str, from, false);
|
text = str2special((const char **)&str, from, false);
|
||||||
}
|
}
|
||||||
|
if (text[0] != NUL && text[1] == NUL) {
|
||||||
|
// single-byte character or illegal byte
|
||||||
|
text = (char *)transchar_byte((uint8_t)text[0]);
|
||||||
|
}
|
||||||
const int len = vim_strsize((char_u *)text);
|
const int len = vim_strsize((char_u *)text);
|
||||||
if (maxlen > 0 && retval + len >= maxlen) {
|
if (maxlen > 0 && retval + len >= maxlen) {
|
||||||
break;
|
break;
|
||||||
@@ -1666,6 +1670,7 @@ char *str2special_save(const char *const str, const bool replace_spaces, const b
|
|||||||
/// @return Converted key code, in a static buffer. Buffer is always one and the
|
/// @return Converted key code, in a static buffer. Buffer is always one and the
|
||||||
/// same, so save converted string somewhere before running str2special
|
/// same, so save converted string somewhere before running str2special
|
||||||
/// for the second time.
|
/// for the second time.
|
||||||
|
/// On illegal byte return a string with only that byte.
|
||||||
const char *str2special(const char **const sp, const bool replace_spaces, const bool replace_lt)
|
const char *str2special(const char **const sp, const bool replace_spaces, const bool replace_lt)
|
||||||
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_RET
|
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_RET
|
||||||
{
|
{
|
||||||
@@ -1699,32 +1704,26 @@ const char *str2special(const char **const sp, const bool replace_spaces, const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!IS_SPECIAL(c)) {
|
if (!IS_SPECIAL(c) && MB_BYTE2LEN(c) > 1) {
|
||||||
*sp = str;
|
*sp = str;
|
||||||
// Try to un-escape a multi-byte character after modifiers.
|
// Try to un-escape a multi-byte character after modifiers.
|
||||||
const char *p = mb_unescape(sp);
|
const char *p = mb_unescape(sp);
|
||||||
|
if (p != NULL) {
|
||||||
if (p == NULL) {
|
|
||||||
const int len = utf_ptr2len(str);
|
|
||||||
// Check for an illegal byte.
|
|
||||||
if (MB_BYTE2LEN((uint8_t)(*str)) > len) {
|
|
||||||
transchar_nonprint(curbuf, (char_u *)buf, c);
|
|
||||||
*sp = str + 1;
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
*sp = str + len;
|
|
||||||
p = str;
|
|
||||||
}
|
|
||||||
// Since 'special' is true the multi-byte character 'c' will be
|
// Since 'special' is true the multi-byte character 'c' will be
|
||||||
// processed by get_special_key_name().
|
// processed by get_special_key_name().
|
||||||
c = utf_ptr2char(p);
|
c = utf_ptr2char(p);
|
||||||
} else {
|
} else {
|
||||||
|
// illegal byte
|
||||||
|
*sp = str + 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// single-byte character or illegal byte
|
||||||
*sp = str + 1;
|
*sp = str + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make unprintable characters in <> form, also <M-Space> and <Tab>.
|
// Make special keys and C0 control characters in <> form, also <M-Space>.
|
||||||
if (special
|
if (special
|
||||||
|| char2cells(c) > 1
|
|| c < ' '
|
||||||
|| (replace_spaces && c == ' ')
|
|| (replace_spaces && c == ' ')
|
||||||
|| (replace_lt && c == '<')) {
|
|| (replace_lt && c == '<')) {
|
||||||
return (const char *)get_special_key_name(c, modifiers);
|
return (const char *)get_special_key_name(c, modifiers);
|
||||||
|
@@ -4980,7 +4980,11 @@ int get_option_value(const char *name, long *numval, char **stringval, int opt_f
|
|||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
if (stringval != NULL) {
|
if (stringval != NULL) {
|
||||||
*stringval = xstrdup(*(char **)varp);
|
if ((char_u **)varp == &p_pt) { // 'pastetoggle'
|
||||||
|
*stringval = str2special_save(*(char **)(varp), false, false);
|
||||||
|
} else {
|
||||||
|
*stringval = xstrdup(*(char **)(varp));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@@ -42,6 +42,20 @@ function Test_maparg()
|
|||||||
map abc y<S-char-114>y
|
map abc y<S-char-114>y
|
||||||
call assert_equal("yRy", maparg('abc'))
|
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 <M-…>
|
||||||
|
call assert_equal('<M-…>', maparg('abc'))
|
||||||
|
|
||||||
|
" illegal bytes
|
||||||
|
let str = ":\x7f:\x80:\x90:\xd0:"
|
||||||
|
exe 'nmap abc ' .. str
|
||||||
|
call assert_equal(str, maparg('abc'))
|
||||||
|
unlet str
|
||||||
|
|
||||||
omap { w
|
omap { w
|
||||||
let d = maparg('{', 'o', 0, 1)
|
let d = maparg('{', 'o', 0, 1)
|
||||||
call assert_equal(['{', 'w', 'o'], [d.lhs, d.rhs, d.mode])
|
call assert_equal(['{', 'w', 'o'], [d.lhs, d.rhs, d.mode])
|
||||||
|
@@ -488,6 +488,13 @@ func Test_list_mappings()
|
|||||||
call assert_equal(['n <M-…> foo'],
|
call assert_equal(['n <M-…> foo'],
|
||||||
\ execute('nmap <M-…>')->trim()->split("\n"))
|
\ execute('nmap <M-…>')->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
|
" map to CTRL-V
|
||||||
exe "nmap ,k \<C-V>"
|
exe "nmap ,k \<C-V>"
|
||||||
call assert_equal(['n ,k <Nop>'],
|
call assert_equal(['n ,k <Nop>'],
|
||||||
|
@@ -31,6 +31,26 @@ func Test_isfname()
|
|||||||
set isfname&
|
set isfname&
|
||||||
endfunc
|
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 = '<M-…>'
|
||||||
|
call assert_equal('<M-…>', &pastetoggle)
|
||||||
|
call assert_equal("\n pastetoggle=<M-…>", 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()
|
func Test_wildchar()
|
||||||
" Empty 'wildchar' used to access invalid memory.
|
" Empty 'wildchar' used to access invalid memory.
|
||||||
call assert_fails('set wildchar=', 'E521:')
|
call assert_fails('set wildchar=', 'E521:')
|
||||||
|
Reference in New Issue
Block a user