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:
zeertzjq
2023-04-21 19:52:23 +08:00
committed by GitHub
2 changed files with 24 additions and 16 deletions

View File

@@ -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);

View File

@@ -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)