mirror of
https://github.com/vim/vim.git
synced 2025-09-29 04:34:16 -04:00
patch 9.0.1532: crash when expanding "~" in substitute causes very long text
Problem: Crash when expanding "~" in substitute causes very long text. Solution: Limit the text length to MAXCOL.
This commit is contained in:
30
src/regexp.c
30
src/regexp.c
@@ -1767,10 +1767,7 @@ do_Lower(int *d, int c)
|
|||||||
regtilde(char_u *source, int magic)
|
regtilde(char_u *source, int magic)
|
||||||
{
|
{
|
||||||
char_u *newsub = source;
|
char_u *newsub = source;
|
||||||
char_u *tmpsub;
|
|
||||||
char_u *p;
|
char_u *p;
|
||||||
int len;
|
|
||||||
int prevlen;
|
|
||||||
|
|
||||||
for (p = newsub; *p; ++p)
|
for (p = newsub; *p; ++p)
|
||||||
{
|
{
|
||||||
@@ -1779,24 +1776,35 @@ regtilde(char_u *source, int magic)
|
|||||||
if (reg_prev_sub != NULL)
|
if (reg_prev_sub != NULL)
|
||||||
{
|
{
|
||||||
// length = len(newsub) - 1 + len(prev_sub) + 1
|
// length = len(newsub) - 1 + len(prev_sub) + 1
|
||||||
prevlen = (int)STRLEN(reg_prev_sub);
|
// Avoid making the text longer than MAXCOL, it will cause
|
||||||
tmpsub = alloc(STRLEN(newsub) + prevlen);
|
// trouble at some point.
|
||||||
|
size_t prevsublen = STRLEN(reg_prev_sub);
|
||||||
|
size_t newsublen = STRLEN(newsub);
|
||||||
|
if (prevsublen > MAXCOL || newsublen > MAXCOL
|
||||||
|
|| newsublen + prevsublen > MAXCOL)
|
||||||
|
{
|
||||||
|
emsg(_(e_resulting_text_too_long));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
char_u *tmpsub = alloc(newsublen + prevsublen);
|
||||||
if (tmpsub != NULL)
|
if (tmpsub != NULL)
|
||||||
{
|
{
|
||||||
// copy prefix
|
// copy prefix
|
||||||
len = (int)(p - newsub); // not including ~
|
size_t prefixlen = p - newsub; // not including ~
|
||||||
mch_memmove(tmpsub, newsub, (size_t)len);
|
mch_memmove(tmpsub, newsub, prefixlen);
|
||||||
// interpret tilde
|
// interpret tilde
|
||||||
mch_memmove(tmpsub + len, reg_prev_sub, (size_t)prevlen);
|
mch_memmove(tmpsub + prefixlen, reg_prev_sub,
|
||||||
|
prevsublen);
|
||||||
// copy postfix
|
// copy postfix
|
||||||
if (!magic)
|
if (!magic)
|
||||||
++p; // back off backslash
|
++p; // back off backslash
|
||||||
STRCPY(tmpsub + len + prevlen, p + 1);
|
STRCPY(tmpsub + prefixlen + prevsublen, p + 1);
|
||||||
|
|
||||||
if (newsub != source) // already allocated newsub
|
if (newsub != source) // allocated newsub before
|
||||||
vim_free(newsub);
|
vim_free(newsub);
|
||||||
newsub = tmpsub;
|
newsub = tmpsub;
|
||||||
p = newsub + len + prevlen;
|
p = newsub + prefixlen + prevsublen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (magic)
|
else if (magic)
|
||||||
|
@@ -1414,6 +1414,20 @@ func Test_substitute_short_cmd()
|
|||||||
bw!
|
bw!
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
" Check handling expanding "~" resulting in extremely long text.
|
||||||
|
func Test_substitute_tilde_too_long()
|
||||||
|
enew!
|
||||||
|
|
||||||
|
s/.*/ixxx
|
||||||
|
s//~~~~~~~~~AAAAAAA@(
|
||||||
|
|
||||||
|
" Either fails with "out of memory" or "text too long".
|
||||||
|
" This can take a long time.
|
||||||
|
call assert_fails('sil! norm &&&&&&&&&', ['E1240:\|E342:'])
|
||||||
|
|
||||||
|
bwipe!
|
||||||
|
endfunc
|
||||||
|
|
||||||
" This should be done last to reveal a memory leak when vim_regsub_both() is
|
" This should be done last to reveal a memory leak when vim_regsub_both() is
|
||||||
" called to evaluate an expression but it is not used in a second call.
|
" called to evaluate an expression but it is not used in a second call.
|
||||||
func Test_z_substitute_expr_leak()
|
func Test_z_substitute_expr_leak()
|
||||||
|
@@ -695,6 +695,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
1532,
|
||||||
/**/
|
/**/
|
||||||
1531,
|
1531,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user