mirror of
https://github.com/neovim/neovim.git
synced 2025-09-08 12:28:18 +00:00
Merge pull request #23246 from zeertzjq/backport-23225-to-release-0.9
[Backport release-0.9] fix(usercmd): fix buffer overflow in uc_list()
This commit is contained in:
@@ -470,7 +470,7 @@ static void uc_list(char *name, size_t name_len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Special cases
|
// Special cases
|
||||||
int len = 4;
|
size_t len = 4;
|
||||||
if (a & EX_BANG) {
|
if (a & EX_BANG) {
|
||||||
msg_putchar('!');
|
msg_putchar('!');
|
||||||
len--;
|
len--;
|
||||||
@@ -492,7 +492,7 @@ static void uc_list(char *name, size_t name_len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
msg_outtrans_attr(cmd->uc_name, HL_ATTR(HLF_D));
|
msg_outtrans_attr(cmd->uc_name, HL_ATTR(HLF_D));
|
||||||
len = (int)strlen(cmd->uc_name) + 4;
|
len = strlen(cmd->uc_name) + 4;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
msg_putchar(' ');
|
msg_putchar(' ');
|
||||||
@@ -501,7 +501,7 @@ static void uc_list(char *name, size_t name_len)
|
|||||||
|
|
||||||
// "over" is how much longer the name is than the column width for
|
// "over" is how much longer the name is than the column width for
|
||||||
// the name, we'll try to align what comes after.
|
// the name, we'll try to align what comes after.
|
||||||
const int over = len - 22;
|
const int64_t over = (int64_t)len - 22;
|
||||||
len = 0;
|
len = 0;
|
||||||
|
|
||||||
// Arguments
|
// Arguments
|
||||||
@@ -525,20 +525,22 @@ static void uc_list(char *name, size_t name_len)
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
IObuff[len++] = ' ';
|
IObuff[len++] = ' ';
|
||||||
} while (len < 5 - over);
|
} while ((int64_t)len < 5 - over);
|
||||||
|
|
||||||
// Address / Range
|
// Address / Range
|
||||||
if (a & (EX_RANGE | EX_COUNT)) {
|
if (a & (EX_RANGE | EX_COUNT)) {
|
||||||
if (a & EX_COUNT) {
|
if (a & EX_COUNT) {
|
||||||
// -count=N
|
// -count=N
|
||||||
snprintf(IObuff + len, IOSIZE, "%" PRId64 "c", cmd->uc_def);
|
int rc = snprintf(IObuff + len, IOSIZE - len, "%" PRId64 "c", cmd->uc_def);
|
||||||
len += (int)strlen(IObuff + len);
|
assert(rc > 0);
|
||||||
|
len += (size_t)rc;
|
||||||
} else if (a & EX_DFLALL) {
|
} else if (a & EX_DFLALL) {
|
||||||
IObuff[len++] = '%';
|
IObuff[len++] = '%';
|
||||||
} else if (cmd->uc_def >= 0) {
|
} else if (cmd->uc_def >= 0) {
|
||||||
// -range=N
|
// -range=N
|
||||||
snprintf(IObuff + len, IOSIZE, "%" PRId64 "", cmd->uc_def);
|
int rc = snprintf(IObuff + len, IOSIZE - len, "%" PRId64 "", cmd->uc_def);
|
||||||
len += (int)strlen(IObuff + len);
|
assert(rc > 0);
|
||||||
|
len += (size_t)rc;
|
||||||
} else {
|
} else {
|
||||||
IObuff[len++] = '.';
|
IObuff[len++] = '.';
|
||||||
}
|
}
|
||||||
@@ -546,32 +548,34 @@ static void uc_list(char *name, size_t name_len)
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
IObuff[len++] = ' ';
|
IObuff[len++] = ' ';
|
||||||
} while (len < 8 - over);
|
} while ((int64_t)len < 8 - over);
|
||||||
|
|
||||||
// Address Type
|
// Address Type
|
||||||
for (j = 0; addr_type_complete[j].expand != ADDR_NONE; j++) {
|
for (j = 0; addr_type_complete[j].expand != ADDR_NONE; j++) {
|
||||||
if (addr_type_complete[j].expand != ADDR_LINES
|
if (addr_type_complete[j].expand != ADDR_LINES
|
||||||
&& addr_type_complete[j].expand == cmd->uc_addr_type) {
|
&& addr_type_complete[j].expand == cmd->uc_addr_type) {
|
||||||
STRCPY(IObuff + len, addr_type_complete[j].shortname);
|
int rc = snprintf(IObuff + len, IOSIZE - len, "%s", addr_type_complete[j].shortname);
|
||||||
len += (int)strlen(IObuff + len);
|
assert(rc > 0);
|
||||||
|
len += (size_t)rc;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
IObuff[len++] = ' ';
|
IObuff[len++] = ' ';
|
||||||
} while (len < 13 - over);
|
} while ((int64_t)len < 13 - over);
|
||||||
|
|
||||||
// Completion
|
// Completion
|
||||||
char *cmd_compl = get_command_complete(cmd->uc_compl);
|
char *cmd_compl = get_command_complete(cmd->uc_compl);
|
||||||
if (cmd_compl != NULL) {
|
if (cmd_compl != NULL) {
|
||||||
STRCPY(IObuff + len, get_command_complete(cmd->uc_compl));
|
int rc = snprintf(IObuff + len, IOSIZE - len, "%s", get_command_complete(cmd->uc_compl));
|
||||||
len += (int)strlen(IObuff + len);
|
assert(rc > 0);
|
||||||
|
len += (size_t)rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
IObuff[len++] = ' ';
|
IObuff[len++] = ' ';
|
||||||
} while (len < 25 - over);
|
} while ((int64_t)len < 25 - over);
|
||||||
|
|
||||||
IObuff[len] = '\0';
|
IObuff[len] = '\0';
|
||||||
msg_outtrans(IObuff);
|
msg_outtrans(IObuff);
|
||||||
|
@@ -26,5 +26,9 @@ describe('Ex cmds', function()
|
|||||||
pcall_err(command, ':bdelete 9999999999999999999999999999999999999999'))
|
pcall_err(command, ':bdelete 9999999999999999999999999999999999999999'))
|
||||||
assert_alive()
|
assert_alive()
|
||||||
end)
|
end)
|
||||||
end)
|
|
||||||
|
|
||||||
|
it('listing long user command does not crash', function()
|
||||||
|
command('execute "command" repeat("T", 255) ":"')
|
||||||
|
command('command')
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
Reference in New Issue
Block a user