mirror of
https://github.com/Tha14/toxic.git
synced 2024-11-16 23:13:03 +01:00
fix undefined behaviour with string literals
This commit is contained in:
parent
b23ae5a4c3
commit
ce4f293574
@ -79,37 +79,39 @@ static struct cmd_func chat_commands[] = {
|
|||||||
|
|
||||||
/* Parses input command and puts args into arg array.
|
/* Parses input command and puts args into arg array.
|
||||||
Returns number of arguments on success, -1 on failure. */
|
Returns number of arguments on success, -1 on failure. */
|
||||||
static int parse_command(WINDOW *w, ToxWindow *self, char *cmd, char (*args)[MAX_STR_SIZE])
|
static int parse_command(WINDOW *w, ToxWindow *self, const char *input, char (*args)[MAX_STR_SIZE])
|
||||||
{
|
{
|
||||||
|
char *cmd = strdup(input);
|
||||||
int num_args = 0;
|
int num_args = 0;
|
||||||
bool cmd_end = false; /* flags when we get to the end of cmd */
|
int i = 0; /* index of last char in an argument */
|
||||||
char *end; /* points to the end of the current arg */
|
|
||||||
|
|
||||||
/* characters wrapped in double quotes count as one arg */
|
/* characters wrapped in double quotes count as one arg */
|
||||||
while (!cmd_end && num_args < MAX_NUM_ARGS) {
|
while (cmd[i] && num_args < MAX_NUM_ARGS) {
|
||||||
if (*cmd == '\"') {
|
int qt_ofst = 0; /* set to 1 to offset index for quote char at end of arg */
|
||||||
end = strchr(cmd + 1, '\"');
|
|
||||||
|
|
||||||
if (end++ == NULL) { /* Increment past the end quote */
|
if (*cmd == '\"') {
|
||||||
|
qt_ofst = 1;
|
||||||
|
|
||||||
|
i = char_find(1, cmd, '\"');
|
||||||
|
|
||||||
|
if (cmd[i] == '\0') {
|
||||||
char *errmsg = "Invalid argument. Did you forget a closing \"?";
|
char *errmsg = "Invalid argument. Did you forget a closing \"?";
|
||||||
line_info_add(self, NULL, NULL, NULL, errmsg, SYS_MSG, 0, 0);
|
line_info_add(self, NULL, NULL, NULL, errmsg, SYS_MSG, 0, 0);
|
||||||
|
free(cmd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd_end = *end == '\0';
|
|
||||||
} else {
|
} else {
|
||||||
end = strchr(cmd, ' ');
|
i = char_find(0, cmd, ' ');
|
||||||
cmd_end = end == NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cmd_end)
|
memcpy(args[num_args], cmd, i + qt_ofst);
|
||||||
*end++ = '\0'; /* mark end of current argument */
|
args[num_args++][i + qt_ofst] = '\0';
|
||||||
|
|
||||||
/* Copy from start of current arg to where we just inserted the null byte */
|
if (cmd[i] != '\0')
|
||||||
strcpy(args[num_args++], cmd);
|
strcpy(cmd, &cmd[i + 1]);
|
||||||
cmd = end;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(cmd);
|
||||||
return num_args;
|
return num_args;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,13 +131,13 @@ static int do_command(WINDOW *w, ToxWindow *self, Tox *m, int num_args, int num_
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void execute(WINDOW *w, ToxWindow *self, Tox *m, char *cmd, int mode)
|
void execute(WINDOW *w, ToxWindow *self, Tox *m, const char *input, int mode)
|
||||||
{
|
{
|
||||||
if (string_is_empty(cmd))
|
if (string_is_empty(input))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
char args[MAX_NUM_ARGS][MAX_STR_SIZE];
|
char args[MAX_NUM_ARGS][MAX_STR_SIZE];
|
||||||
int num_args = parse_command(w, self, cmd, args);
|
int num_args = parse_command(w, self, input, args);
|
||||||
|
|
||||||
if (num_args == -1)
|
if (num_args == -1)
|
||||||
return;
|
return;
|
||||||
|
@ -42,6 +42,6 @@ enum {
|
|||||||
GROUPCHAT_COMMAND_MODE,
|
GROUPCHAT_COMMAND_MODE,
|
||||||
};
|
};
|
||||||
|
|
||||||
void execute(WINDOW *w, ToxWindow *self, Tox *m, char *cmd, int mode);
|
void execute(WINDOW *w, ToxWindow *self, Tox *m, const char *input, int mode);
|
||||||
|
|
||||||
#endif /* #define _execute_h */
|
#endif /* #define _execute_h */
|
||||||
|
@ -185,7 +185,8 @@ static void input_history(ToxWindow *self, wint_t key, int mx_x)
|
|||||||
ChatContext *ctx = self->chatwin;
|
ChatContext *ctx = self->chatwin;
|
||||||
|
|
||||||
fetch_hist_item(ctx, key);
|
fetch_hist_item(ctx, key);
|
||||||
ctx->start = mx_x * (ctx->len / mx_x);
|
int wlen = wcswidth(ctx->line, sizeof(ctx->line));
|
||||||
|
ctx->start = wlen < mx_x ? 0 : wlen - mx_x + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handles non-printable input keys that behave the same for all types of chat windows.
|
/* Handles non-printable input keys that behave the same for all types of chat windows.
|
||||||
|
@ -108,7 +108,7 @@ char *hex_string_to_bin(const char *hex_string)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Returns 1 if the string is empty, 0 otherwise */
|
/* Returns 1 if the string is empty, 0 otherwise */
|
||||||
int string_is_empty(char *string)
|
int string_is_empty(const char *string)
|
||||||
{
|
{
|
||||||
return string[0] == '\0';
|
return string[0] == '\0';
|
||||||
}
|
}
|
||||||
@ -197,23 +197,23 @@ int valid_nick(char *nick)
|
|||||||
void get_file_name(char *namebuf, int bufsize, const char *pathname)
|
void get_file_name(char *namebuf, int bufsize, const char *pathname)
|
||||||
{
|
{
|
||||||
int idx = strlen(pathname) - 1;
|
int idx = strlen(pathname) - 1;
|
||||||
|
char *path = strdup(pathname);
|
||||||
char tmpname[MAX_STR_SIZE];
|
|
||||||
snprintf(tmpname, sizeof(tmpname), "%s", pathname);
|
|
||||||
|
|
||||||
while (idx >= 0 && pathname[idx] == '/')
|
while (idx >= 0 && pathname[idx] == '/')
|
||||||
tmpname[idx--] = '\0';
|
path[idx--] = '\0';
|
||||||
|
|
||||||
char *filename = strrchr(tmpname, '/');
|
char *finalname = strdup(path);
|
||||||
|
const char *basenm = strrchr(path, '/');
|
||||||
|
|
||||||
if (filename != NULL) {
|
if (basenm != NULL) {
|
||||||
if (!strlen(++filename))
|
if (basenm[1])
|
||||||
filename = tmpname;
|
strcpy(finalname, &basenm[1]);
|
||||||
} else {
|
|
||||||
filename = tmpname;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf(namebuf, bufsize, "%s", filename);
|
snprintf(namebuf, bufsize, "%s", finalname);
|
||||||
|
|
||||||
|
free(finalname);
|
||||||
|
free(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* converts str to all lowercase */
|
/* converts str to all lowercase */
|
||||||
@ -234,3 +234,17 @@ int get_nick_truncate(Tox *m, char *buf, int friendnum)
|
|||||||
buf[len] = '\0';
|
buf[len] = '\0';
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* returns index of the first instance of ch in s starting at idx.
|
||||||
|
returns length of s if char not found */
|
||||||
|
int char_find(int idx, const char *s, char ch)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
for (i = idx; s[i]; ++i) {
|
||||||
|
if (s[i] == ch)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
@ -52,7 +52,7 @@ struct tm *get_time(void);
|
|||||||
void update_unix_time(void);
|
void update_unix_time(void);
|
||||||
|
|
||||||
/* Returns 1 if the string is empty, 0 otherwise */
|
/* Returns 1 if the string is empty, 0 otherwise */
|
||||||
int string_is_empty(char *string);
|
int string_is_empty(const char *string);
|
||||||
|
|
||||||
/* convert a multibyte string to a wide character string (must provide buffer) */
|
/* convert a multibyte string to a wide character string (must provide buffer) */
|
||||||
int char_to_wcs_buf(wchar_t *buf, const char *string, size_t n);
|
int char_to_wcs_buf(wchar_t *buf, const char *string, size_t n);
|
||||||
@ -89,4 +89,8 @@ void str_to_lower(char *str);
|
|||||||
Returns nick len on success, -1 on failure */
|
Returns nick len on success, -1 on failure */
|
||||||
int get_nick_truncate(Tox *m, char *buf, int friendnum);
|
int get_nick_truncate(Tox *m, char *buf, int friendnum);
|
||||||
|
|
||||||
|
/* returns index of the first instance of ch in s starting at idx.
|
||||||
|
returns length of s if char not found */
|
||||||
|
int char_find(int idx, const char *s, char ch);
|
||||||
|
|
||||||
#endif /* #define _misc_tools_h */
|
#endif /* #define _misc_tools_h */
|
||||||
|
@ -641,7 +641,7 @@ int main(int argc, char *argv[])
|
|||||||
sort_friendlist_index();
|
sort_friendlist_index();
|
||||||
prompt_init_statusbar(prompt, m);
|
prompt_init_statusbar(prompt, m);
|
||||||
|
|
||||||
uint64_t last_save = get_unix_time();
|
uint64_t last_save = (uint64_t) time(NULL);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
update_unix_time();
|
update_unix_time();
|
||||||
|
Loading…
Reference in New Issue
Block a user