diff --git a/src/autocomplete.c b/src/autocomplete.c index 8cf703c..6bc3c6a 100644 --- a/src/autocomplete.c +++ b/src/autocomplete.c @@ -93,7 +93,7 @@ int complete_line(ToxWindow *self, const void *list, int n_items, int size) { ChatContext *ctx = self->chatwin; - if (ctx->pos <= 0 || ctx->len <= 0 || ctx->len >= MAX_STR_SIZE || size > MAX_STR_SIZE) + if (ctx->pos <= 0 || ctx->len <= 0 || ctx->pos > ctx->len || ctx->len >= MAX_STR_SIZE || size > MAX_STR_SIZE) return -1; const char *L = (char *) list; @@ -136,7 +136,7 @@ int complete_line(ToxWindow *self, const void *list, int n_items, int size) } } - if (string_is_empty(sub)) { + if (!sub[0]) { free(sub); return -1; } @@ -185,7 +185,7 @@ int complete_line(ToxWindow *self, const void *list, int n_items, int size) return -1; char tmpend[MAX_STR_SIZE]; - strcpy(tmpend, &ubuf[ctx->pos]); + snprintf(tmpend, sizeof(tmpend), "%s", &ubuf[ctx->pos]); strcpy(&ubuf[strt], match); strcpy(&ubuf[strt + m_len], endchrs); strcpy(&ubuf[strt + m_len + n_endchrs], tmpend); @@ -193,7 +193,7 @@ int complete_line(ToxWindow *self, const void *list, int n_items, int size) /* convert to widechar and copy back to original buf */ wchar_t newbuf[MAX_STR_SIZE]; - if (mbs_to_wcs_buf(newbuf, ubuf, MAX_STR_SIZE) == -1) + if (mbs_to_wcs_buf(newbuf, ubuf, sizeof(newbuf) / sizeof(wchar_t)) == -1) return -1; wcscpy(ctx->line, newbuf); @@ -218,7 +218,7 @@ static void complt_home_dir(ToxWindow *self, char *path, int pathsize, const cha wchar_t wline[MAX_STR_SIZE]; - if (mbs_to_wcs_buf(wline, newline, sizeof(wline)) == -1) + if (mbs_to_wcs_buf(wline, newline, sizeof(wline) / sizeof(wchar_t)) == -1) return; int newlen = wcslen(wline); @@ -261,10 +261,10 @@ int dir_match(ToxWindow *self, Tox *m, const wchar_t *line, const wchar_t *cmd) } else if (!si && b_path[0] != '/') { /* look for matches in pwd */ char tmp[MAX_STR_SIZE]; snprintf(tmp, sizeof(tmp), ".%s", b_path); - strcpy(b_path, tmp); + snprintf(b_path, sizeof(b_path), "%s", tmp); } - strcpy(b_name, &b_path[si + 1]); + snprintf(b_name, sizeof(b_name), "%s", &b_path[si + 1]); b_path[si + 1] = '\0'; int b_name_len = strlen(b_name); DIR *dp = opendir(b_path); diff --git a/src/chat.c b/src/chat.c index 2671feb..97ab127 100644 --- a/src/chat.c +++ b/src/chat.c @@ -541,7 +541,7 @@ static void chat_onFileRecv(ToxWindow *self, Tox *m, uint32_t friendnum, uint32_ snprintf(file_path, sizeof(file_path), "%s", filename); } - if (path_len >= sizeof(ft->file_path) || name_length >= sizeof(ft->file_name)) { + if (path_len >= sizeof(file_path) || path_len >= sizeof(ft->file_path) || name_length >= sizeof(ft->file_name)) { tox_file_control(m, friendnum, filenum, TOX_FILE_CONTROL_CANCEL, NULL); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File transfer faield: File path too long."); return; @@ -937,7 +937,7 @@ static void chat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr) if (diff != -1) { if (x + diff > x2 - 1) { - int wlen = wcswidth(ctx->line, sizeof(ctx->line)); + int wlen = MAX(0, wcswidth(ctx->line, sizeof(ctx->line) / sizeof(wchar_t))); ctx->start = wlen < x2 ? 0 : wlen - x2 + 1; } } else { @@ -1091,7 +1091,7 @@ static void chat_onDraw(ToxWindow *self, Tox *m) int y, x; getyx(self->window, y, x); (void) x; - int new_x = ctx->start ? x2 - 1 : wcswidth(ctx->line, ctx->pos); + int new_x = ctx->start ? x2 - 1 : MAX(0, wcswidth(ctx->line, ctx->pos)); wmove(self->window, y + 1, new_x); wrefresh(self->window); diff --git a/src/dns.c b/src/dns.c index ade723c..0403f6c 100644 --- a/src/dns.c +++ b/src/dns.c @@ -234,12 +234,16 @@ static int parse_dns_response(ToxWindow *self, u_char *answer, int ans_len, char and the domain in dombuf. return length of username on success, -1 on failure */ -static int parse_addr(const char *addr, char *namebuf, char *dombuf) +static int parse_addr(const char *addr, char *namebuf, size_t namebuf_sz, char *dombuf, size_t dombuf_sz) { - char tmpaddr[MAX_STR_SIZE]; - char *tmpname, *tmpdom; + if (strlen(addr) >= MAX_STR_SIZE) + return -1; - strcpy(tmpaddr, addr); + char tmpaddr[MAX_STR_SIZE]; + char *tmpname = NULL; + char *tmpdom = NULL; + + snprintf(tmpaddr, sizeof(tmpaddr), "%s", addr); tmpname = strtok(tmpaddr, "@"); tmpdom = strtok(NULL, ""); @@ -247,8 +251,8 @@ static int parse_addr(const char *addr, char *namebuf, char *dombuf) return -1; str_to_lower(tmpdom); - strcpy(namebuf, tmpname); - strcpy(dombuf, tmpdom); + snprintf(namebuf, namebuf_sz, "%s", tmpname); + snprintf(dombuf, dombuf_sz, "%s", tmpdom); return strlen(namebuf); } @@ -295,7 +299,7 @@ void *dns3_lookup_thread(void *data) char inputdomain[MAX_STR_SIZE]; char name[MAX_STR_SIZE]; - int namelen = parse_addr(t_data.addr, name, inputdomain); + int namelen = parse_addr(t_data.addr, name, sizeof(name), inputdomain, sizeof(inputdomain)); if (namelen == -1) { dns_error(self, "Must be a Tox ID or an address in the form username@domain"); diff --git a/src/file_transfers.c b/src/file_transfers.c index 7cd915f..64261cc 100644 --- a/src/file_transfers.c +++ b/src/file_transfers.c @@ -285,7 +285,7 @@ void close_file_transfer(ToxWindow *self, Tox *m, struct FileTransfer *ft, int C tox_file_control(m, ft->friendnum, ft->filenum, (TOX_FILE_CONTROL) CTRL, NULL); if (message && self) { - if (self->active_box != -1) + if (self->active_box != -1 && sound_type != silent) box_notify2(self, sound_type, NT_NOFOCUS | NT_WNDALERT_2, self->active_box, "%s", message); else box_notify(self, sound_type, NT_NOFOCUS | NT_WNDALERT_2, &self->active_box, self->name, "%s", message); diff --git a/src/friendlist.c b/src/friendlist.c index c8df965..0e0b394 100644 --- a/src/friendlist.c +++ b/src/friendlist.c @@ -139,8 +139,10 @@ static int save_blocklist(char *path) int count = 0; for (i = 0; i < Blocked.max_idx; ++i) { - if (count > Blocked.num_blocked) - goto on_error; + if (count > Blocked.num_blocked) { + free(data); + return -1; + } if (Blocked.list[i].active) { BlockedFriend tmp; @@ -161,19 +163,20 @@ static int save_blocklist(char *path) FILE *fp = fopen(path, "wb"); - if (fp == NULL) - goto on_error; + if (fp == NULL) { + free(data); + return -1; + } - if (fwrite(data, len, 1, fp) != 1) - goto on_error; + if (fwrite(data, len, 1, fp) != 1) { + fclose(fp); + free(data); + return -1; + } fclose(fp); free(data); return 0; - -on_error: - free(data); - return -1; } static void sort_blocklist_index(void); @@ -221,9 +224,10 @@ int load_blocklist(char *path) int i; for (i = 0; i < num; ++i) { + BlockedFriend tmp; + memset(&tmp, 0, sizeof(BlockedFriend)); memset(&Blocked.list[i], 0, sizeof(BlockedFriend)); - BlockedFriend tmp; memcpy(&tmp, data + i * sizeof(BlockedFriend), sizeof(BlockedFriend)); Blocked.list[i].active = true; Blocked.list[i].num = i; diff --git a/src/global_commands.c b/src/global_commands.c index b823b80..170a9ff 100644 --- a/src/global_commands.c +++ b/src/global_commands.c @@ -249,19 +249,22 @@ void cmd_connect(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv) const char *ip = argv[1]; const char *port = argv[2]; - const char *key = argv[3]; + const char *ascii_key = argv[3]; if (atoi(port) == 0) { line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid port."); return; } - char *binary_string = hex_string_to_bin(key); + char key_binary[TOX_PUBLIC_KEY_SIZE * 2 + 1]; + if (hex_string_to_bin(ascii_key, strlen(ascii_key), key_binary, TOX_PUBLIC_KEY_SIZE) == -1) { + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid key."); + return; + } TOX_ERR_BOOTSTRAP err; - tox_bootstrap(m, ip, atoi(port), (uint8_t *) binary_string, &err); - tox_add_tcp_relay(m, ip, atoi(port), (uint8_t *) binary_string, &err); - free(binary_string); + tox_bootstrap(m, ip, atoi(port), (uint8_t *) key_binary, &err); + tox_add_tcp_relay(m, ip, atoi(port), (uint8_t *) key_binary, &err); switch (err) { case TOX_ERR_BOOTSTRAP_BAD_HOST: diff --git a/src/groupchat.c b/src/groupchat.c index 9375e2d..ce568d8 100644 --- a/src/groupchat.c +++ b/src/groupchat.c @@ -593,7 +593,7 @@ static void groupchat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr) if (diff != -1) { if (x + diff > x2 - 1) { - int wlen = wcswidth(ctx->line, sizeof(ctx->line)); + int wlen = MAX(0, wcswidth(ctx->line, sizeof(ctx->line) / sizeof(wchar_t))); ctx->start = wlen < x2 ? 0 : wlen - x2 + 1; } } else { @@ -698,7 +698,7 @@ static void groupchat_onDraw(ToxWindow *self, Tox *m) int y, x; getyx(self->window, y, x); (void) x; - int new_x = ctx->start ? x2 - 1 : wcswidth(ctx->line, ctx->pos); + int new_x = ctx->start ? x2 - 1 : MAX(0, wcswidth(ctx->line, ctx->pos)); wmove(self->window, y + 1, new_x); wrefresh(self->window); @@ -795,66 +795,66 @@ static int group_audio_close_out_device(int groupnum) return 0; } -static int group_audio_write(int peernum, int groupnum, const int16_t *pcm, unsigned int samples, uint8_t channels, - unsigned int sample_rate) -{ - if (!pcm) - return -1; +// static int group_audio_write(int peernum, int groupnum, const int16_t *pcm, unsigned int samples, uint8_t channels, +// unsigned int sample_rate) +// { +// if (!pcm) +// return -1; - if (channels == 0 || channels > 2) - return -2; +// if (channels == 0 || channels > 2) +// return -2; - ALuint bufid; - ALint processed = 0, queued = 0; +// ALuint bufid; +// ALint processed = 0, queued = 0; - alGetSourcei(groupchats[groupnum].audio.source, AL_BUFFERS_PROCESSED, &processed); - alGetSourcei(groupchats[groupnum].audio.source, AL_BUFFERS_QUEUED, &queued); - fprintf(stderr, "source: %d, queued: %d, processed: %d\n", groupchats[groupnum].audio.source, queued, processed); +// alGetSourcei(groupchats[groupnum].audio.source, AL_BUFFERS_PROCESSED, &processed); +// alGetSourcei(groupchats[groupnum].audio.source, AL_BUFFERS_QUEUED, &queued); +// fprintf(stderr, "source: %d, queued: %d, processed: %d\n", groupchats[groupnum].audio.source, queued, processed); - if (processed) { - ALuint bufids[processed]; - alSourceUnqueueBuffers(groupchats[groupnum].audio.source, processed, bufids); - alDeleteBuffers(processed - 1, bufids + 1); - bufid = bufids[0]; - } else if (queued < 16) { - alGenBuffers(1, &bufid); - } else { - return -3; - } +// if (processed) { +// ALuint bufids[processed]; +// alSourceUnqueueBuffers(groupchats[groupnum].audio.source, processed, bufids); +// alDeleteBuffers(processed - 1, bufids + 1); +// bufid = bufids[0]; +// } else if (queued < 16) { +// alGenBuffers(1, &bufid); +// } else { +// return -3; +// } - int length = samples * channels * sizeof(int16_t); +// int length = samples * channels * sizeof(int16_t); - alBufferData(bufid, (channels == 1) ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16, pcm, length, sample_rate); - alSourceQueueBuffers(groupchats[groupnum].audio.source, 1, &bufid); +// alBufferData(bufid, (channels == 1) ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16, pcm, length, sample_rate); +// alSourceQueueBuffers(groupchats[groupnum].audio.source, 1, &bufid); - ALint state; - alGetSourcei(groupchats[groupnum].audio.source, AL_SOURCE_STATE, &state); +// ALint state; +// alGetSourcei(groupchats[groupnum].audio.source, AL_SOURCE_STATE, &state); - if (state != AL_PLAYING) - alSourcePlay(groupchats[groupnum].audio.source); +// if (state != AL_PLAYING) +// alSourcePlay(groupchats[groupnum].audio.source); - return 0; -} +// return 0; +// } static void groupchat_onWriteDevice(ToxWindow *self, Tox *m, int groupnum, int peernum, const int16_t *pcm, unsigned int samples, uint8_t channels, unsigned int sample_rate) { return; - if (groupnum != self->num) - return; + // if (groupnum != self->num) + // return; - if (peernum < 0) - return; + // if (peernum < 0) + // return; - if (groupchats[groupnum].audio.dvhandle == NULL) - fprintf(stderr, "dvhandle is null)\n"); + // if (groupchats[groupnum].audio.dvhandle == NULL) + // fprintf(stderr, "dvhandle is null)\n"); - if (groupchats[groupnum].audio.dvctx == NULL) - fprintf(stderr, "ctx is null\n"); + // if (groupchats[groupnum].audio.dvctx == NULL) + // fprintf(stderr, "ctx is null\n"); - int ret = group_audio_write(peernum, groupnum, pcm, samples, channels, sample_rate); - fprintf(stderr, "write: %d\n", ret); + // int ret = group_audio_write(peernum, groupnum, pcm, samples, channels, sample_rate); + // fprintf(stderr, "write: %d\n", ret); } #endif /* AUDIO */ diff --git a/src/input.c b/src/input.c index 86f94f1..4186c4d 100644 --- a/src/input.c +++ b/src/input.c @@ -125,7 +125,7 @@ static void input_yank(ToxWindow *self, int x, int mx_x) if (x + yank_cols >= mx_x) { int rmdr = MAX(0, (x + yank_cols) - mx_x); - int s_len = wcswidth(&ctx->line[ctx->start], rmdr); + int s_len = MAX(0, wcswidth(&ctx->line[ctx->start], rmdr)); ctx->start += s_len + 1; } } @@ -137,7 +137,7 @@ static void input_mv_end(ToxWindow *self, int y, int mx_x) ctx->pos = ctx->len; - int wlen = wcswidth(ctx->line, sizeof(ctx->line)); + int wlen = MAX(0, wcswidth(ctx->line, sizeof(ctx->line) / sizeof(wchar_t))); ctx->start = MAX(0, 1 + (mx_x * (wlen / mx_x) - mx_x) + (wlen % mx_x)); } @@ -196,7 +196,7 @@ static void input_history(ToxWindow *self, wint_t key, int mx_x) ChatContext *ctx = self->chatwin; fetch_hist_item(ctx, key); - int wlen = wcswidth(ctx->line, sizeof(ctx->line)); + int wlen = MAX(0, wcswidth(ctx->line, sizeof(ctx->line) / sizeof(wchar_t))); ctx->start = wlen < mx_x ? 0 : wlen - mx_x + 1; } diff --git a/src/line_info.c b/src/line_info.c index 2283908..6a84282 100644 --- a/src/line_info.c +++ b/src/line_info.c @@ -133,6 +133,9 @@ static struct line_info *line_info_ret_queue(struct history *hst) void line_info_add(ToxWindow *self, const char *timestr, const char *name1, const char *name2, uint8_t type, uint8_t bold, uint8_t colour, const char *msg, ...) { + if (!self) + return; + struct history *hst = self->chatwin->hst; if (hst->queue_sz >= MAX_LINE_INFO_QUEUE) diff --git a/src/log.c b/src/log.c index edd49ea..2d48dbc 100644 --- a/src/log.c +++ b/src/log.c @@ -179,7 +179,7 @@ void load_chat_history(ToxWindow *self, struct chatlog *log) if (sz <= 0) return; - char *hstbuf = malloc(sz); + char *hstbuf = malloc(sz + 1); if (hstbuf == NULL) exit_toxic_err("failed in load_chat_history", FATALERR_MEMORY); @@ -196,6 +196,8 @@ void load_chat_history(ToxWindow *self, struct chatlog *log) return; } + hstbuf[sz] = '\0'; + /* Number of history lines to load: must not be larger than MAX_LINE_INFO_QUEUE - 2 */ int L = MIN(MAX_LINE_INFO_QUEUE - 2, user_settings->history_size); int start, count = 0; diff --git a/src/misc_tools.c b/src/misc_tools.c index 3734aa2..bcf422f 100644 --- a/src/misc_tools.c +++ b/src/misc_tools.c @@ -109,22 +109,27 @@ void get_elapsed_time_str(char *buf, int bufsize, uint64_t secs) snprintf(buf, bufsize, "%ld:%.2ld:%.2ld", hours, minutes, seconds); } -char *hex_string_to_bin(const char *hex_string) +/* + * Converts a hexidecimal string of length hex_len to binary format and puts the result in output. + * output_size must be exactly half of hex_len. + * + * Returns 0 on success. + * Returns -1 on failure. + */ +int hex_string_to_bin(const char *hex_string, size_t hex_len, char *output, size_t output_size) { - size_t len = strlen(hex_string); - char *val = malloc(len); + if (output_size == 0 || hex_len != output_size * 2) + return -1; - if (val == NULL) - exit_toxic_err("failed in hex_string_to_bin", FATALERR_MEMORY); + for (size_t i = 0; i < output_size; ++i) { + sscanf(hex_string, "%2hhx", &output[i]); + hex_string += 2; + } - size_t i; - - for (i = 0; i < len; ++i, hex_string += 2) - sscanf(hex_string, "%2hhx", &val[i]); - - return val; + return 0; } + int hex_string_to_bytes(char *buf, int size, const char *keystr) { if (size % 2 != 0) @@ -147,6 +152,9 @@ int hex_string_to_bytes(char *buf, int size, const char *keystr) /* Returns 1 if the string is empty, 0 otherwise */ int string_is_empty(const char *string) { + if (!string) + return true; + return string[0] == '\0'; } diff --git a/src/misc_tools.h b/src/misc_tools.h index 325411c..e64b896 100644 --- a/src/misc_tools.h +++ b/src/misc_tools.h @@ -41,8 +41,14 @@ void hst_to_net(uint8_t *num, uint16_t numbytes); -/* convert a hex string to binary */ -char *hex_string_to_bin(const char *hex_string); +/* + * Converts a hexidecimal string of length hex_len to binary format and puts the result in output. + * output_size must be exactly half of hex_len. + * + * Returns 0 on success. + * Returns -1 on failure. + */ +int hex_string_to_bin(const char *hex_string, size_t hex_len, char *output, size_t output_size); /* convert a hex string to bytes. returns 0 on success, -1 on failure */ int hex_string_to_bytes(char *buf, int size, const char *keystr); diff --git a/src/notify.c b/src/notify.c index 8560659..35535cf 100644 --- a/src/notify.c +++ b/src/notify.c @@ -90,7 +90,7 @@ struct _ActiveNotifications { #ifdef BOX_NOTIFY NotifyNotification* box; char messages[MAX_BOX_MSG_LEN + 1][MAX_BOX_MSG_LEN + 1]; - char title[24]; + char title[64]; size_t size; time_t n_timeout; #endif @@ -153,25 +153,26 @@ bool is_playing(int source) static bool device_opened = false; time_t last_opened_update = 0; -bool m_open_device() +/* Opens primary device. Returns true on succe*/ +void m_open_device() { last_opened_update = get_unix_time(); - if (device_opened) return true; + if (device_opened) return; /* Blah error check */ open_primary_device(output, &Control.device_idx, 48000, 20, 1); - return (device_opened = true); + device_opened = true; } -bool m_close_device() +void m_close_device() { - if (!device_opened) return true; + if (!device_opened) return; close_device(output, Control.device_idx); - return !(device_opened = false); + device_opened = false; } /* Terminate all sounds but wait for them to finish first */ @@ -598,9 +599,12 @@ int box_notify(ToxWindow* self, Notification notif, uint64_t flags, int* id_indi actives[id].id_indicator = id_indicator; if (id_indicator) *id_indicator = id; } -#endif +#else + if (id == -1) + return -1; +#endif /* SOUND_NOTIFY */ - strncpy(actives[id].title, title, 24); + snprintf(actives[id].title, sizeof(actives[id].title), "%s", title); if (strlen(title) > 23) strcpy(actives[id].title + 20, "..."); va_list __ARGS__; va_start (__ARGS__, format); @@ -699,7 +703,7 @@ int box_silent_notify(ToxWindow* self, uint64_t flags, int* id_indicator, const *id_indicator = id; } - strncpy(actives[id].title, title, 24); + snprintf(actives[id].title, sizeof(actives[id].title), "%s", title); if (strlen(title) > 23) strcpy(actives[id].title + 20, "..."); va_list __ARGS__; va_start (__ARGS__, format); diff --git a/src/prompt.c b/src/prompt.c index 17369de..c032711 100644 --- a/src/prompt.c +++ b/src/prompt.c @@ -212,7 +212,7 @@ static void prompt_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr) if (diff != -1) { if (x + diff > x2 - 1) { - int wlen = wcswidth(ctx->line, sizeof(ctx->line)); + int wlen = MAX(0, wcswidth(ctx->line, sizeof(ctx->line) / sizeof(wchar_t))); ctx->start = wlen < x2 ? 0 : wlen - x2 + 1; } } else { @@ -330,7 +330,7 @@ static void prompt_onDraw(ToxWindow *self, Tox *m) getyx(self->window, y, x); (void) x; - int new_x = ctx->start ? x2 - 1 : wcswidth(ctx->line, ctx->pos); + int new_x = ctx->start ? x2 - 1 : MAX(0, wcswidth(ctx->line, ctx->pos)); wmove(self->window, y + 1, new_x); wrefresh(self->window); diff --git a/src/prompt.h b/src/prompt.h index 4842f6c..1917375 100644 --- a/src/prompt.h +++ b/src/prompt.h @@ -41,6 +41,7 @@ typedef struct { } FriendRequests; ToxWindow new_prompt(void); + void prep_prompt_win(void); void prompt_init_statusbar(ToxWindow *self, Tox *m); void prompt_update_nick(ToxWindow *prompt, const char *nick); diff --git a/src/term_mplex.c b/src/term_mplex.c index 130e868..35bf082 100644 --- a/src/term_mplex.c +++ b/src/term_mplex.c @@ -167,6 +167,10 @@ static int detect_gnu_screen () free (dyn_buffer); dyn_buffer = NULL; + + if (strlen(socket_path) + strlen(PATH_SEP_S) + strlen(socket_name) >= sizeof(mplex_data)) + goto nomplex; + strcpy (mplex_data, socket_path); strcat (mplex_data, PATH_SEP_S); strcat (mplex_data, socket_name); @@ -181,6 +185,8 @@ nomplex: pclose (session_info_stream); if (dyn_buffer) free (dyn_buffer); + if (socket_path) + free(socket_path); return 0; } @@ -196,7 +202,7 @@ static int detect_tmux () return 0; /* store the session number string for later use */ - strcpy (mplex_data, pos + 1); + snprintf (mplex_data, sizeof(mplex_data), "%s", pos + 1); mplex = MPLEX_TMUX; return 1; } diff --git a/src/toxic.c b/src/toxic.c index c6d1f55..50eb4e3 100644 --- a/src/toxic.c +++ b/src/toxic.c @@ -77,6 +77,9 @@ char *DATA_FILE = NULL; char *BLOCK_FILE = NULL; ToxWindow *prompt = NULL; +#define DATANAME "data" +#define BLOCKNAME "data-blocklist" + #define AUTOSAVE_FREQ 60 #define MIN_PASSWORD_LEN 6 #define MAX_PASSWORD_LEN 64 @@ -119,6 +122,24 @@ static void init_signal_catchers(void) signal(SIGSEGV, catch_SIGSEGV); } +void free_global_data(void) +{ + if (DATA_FILE) { + free(DATA_FILE); + DATA_FILE = NULL; + } + + if (BLOCK_FILE) { + free(BLOCK_FILE); + BLOCK_FILE = NULL; + } + + if (user_settings) { + free(user_settings); + user_settings = NULL; + } +} + void exit_toxic_success(Tox *m) { store_data(m, DATA_FILE); @@ -131,10 +152,7 @@ void exit_toxic_success(Tox *m) terminate_audio(); #endif /* AUDIO */ - free(DATA_FILE); - free(BLOCK_FILE); - free(user_settings); - + free_global_data(); tox_kill(m); endwin(); @@ -150,6 +168,7 @@ void exit_toxic_success(Tox *m) void exit_toxic_err(const char *errmsg, int errcode) { + free_global_data(); freopen("/dev/tty", "w", stderr); endwin(); fprintf(stderr, "Toxic session aborted with error code %d (%s)\n", errcode, errmsg); @@ -289,9 +308,11 @@ static int load_nodelist(const char *filename) toxNodes.nodes[toxNodes.lines][NODELEN - 1] = 0; toxNodes.ports[toxNodes.lines] = atoi(port); - char *key_binary = hex_string_to_bin(key_ascii); + char key_binary[TOX_PUBLIC_KEY_SIZE + 2 + 1]; + if (hex_string_to_bin(key_ascii, strlen(key_ascii), key_binary, TOX_PUBLIC_KEY_SIZE) == -1) + continue; + memcpy(toxNodes.keys[toxNodes.lines], key_binary, TOX_PUBLIC_KEY_SIZE); - free(key_binary); toxNodes.lines++; } @@ -933,10 +954,22 @@ static void parse_args(int argc, char *argv[]) case 'f': arg_opts.use_custom_data = 1; - DATA_FILE = strdup(optarg); + + if (DATA_FILE) + free(DATA_FILE); + + if (BLOCK_FILE) + free(BLOCK_FILE); + + DATA_FILE = malloc(strlen(optarg) + 1); + strcpy(DATA_FILE, optarg); + + if (DATA_FILE == NULL) + exit_toxic_err("failed in parse_args", FATALERR_MEMORY); + BLOCK_FILE = malloc(strlen(optarg) + strlen("-blocklist") + 1); - if (DATA_FILE == NULL || BLOCK_FILE == NULL) + if (BLOCK_FILE == NULL) exit_toxic_err("failed in parse_args", FATALERR_MEMORY); strcpy(BLOCK_FILE, optarg); @@ -1007,8 +1040,6 @@ static void parse_args(int argc, char *argv[]) } } -#define DATANAME "data" -#define BLOCKNAME "data-blocklist" static int init_default_data_files(void) { if (arg_opts.use_custom_data) diff --git a/src/windows.c b/src/windows.c index 142bebc..6324b38 100644 --- a/src/windows.c +++ b/src/windows.c @@ -568,7 +568,7 @@ ToxWindow *get_window_ptr(int i) { ToxWindow *toxwin = NULL; - if (i >= 0 && i <= MAX_WINDOWS_NUM && windows[i].active) + if (i >= 0 && i < MAX_WINDOWS_NUM && windows[i].active) toxwin = &windows[i]; return toxwin; @@ -595,7 +595,7 @@ void kill_all_windows(Tox *m) if (windows[i].is_chat) kill_chat_window(&windows[i], m); else if (windows[i].is_groupchat) - close_groupchat(&windows[i], m, i); + close_groupchat(&windows[i], m, windows[i].num); } kill_prompt_window(prompt); diff --git a/src/xtra.c b/src/xtra.c index 51eeb86..05004c3 100644 --- a/src/xtra.c +++ b/src/xtra.c @@ -72,24 +72,24 @@ Property read_property(Window s, Atom p) unsigned long read_num; unsigned long left_bytes; unsigned char *data = NULL; - + int read_bytes = 1024; - + /* Keep trying to read the property until there are no bytes unread */ do { if (data) XFree(data); - - XGetWindowProperty(Xtra.display, s, - p, 0, - read_bytes, + + XGetWindowProperty(Xtra.display, s, + p, 0, + read_bytes, False, AnyPropertyType, - &read_type, &read_format, - &read_num, &left_bytes, + &read_type, &read_format, + &read_num, &left_bytes, &data); - + read_bytes *= 2; } while (left_bytes != 0); - + Property property = {data, read_format, read_num, read_type}; return property; } @@ -107,7 +107,7 @@ Atom get_dnd_type(long *a, int l) static void handle_xdnd_enter(XClientMessageEvent* e) { Xtra.handling_version = (e->data.l[1] >> 24); - + if ((e->data.l[1] & 1)) { // Fetch the list of possible conversions Property p = read_property(e->data.l[0], XdndTypeList); @@ -120,7 +120,7 @@ static void handle_xdnd_enter(XClientMessageEvent* e) } static void handle_xdnd_position(XClientMessageEvent* e) -{ +{ XEvent ev = { .xclient = { .type = ClientMessage, @@ -130,15 +130,15 @@ static void handle_xdnd_position(XClientMessageEvent* e) .format = 32, .data = { .l = { - Xtra.proxy_window, - (Xtra.expecting_type != XtraNil), - 0, 0, + Xtra.proxy_window, + (Xtra.expecting_type != XtraNil), + 0, 0, XdndActionCopy } } } }; - + XSendEvent(Xtra.display, e->data.l[0], False, NoEventMask, &ev); XFlush(Xtra.display); } @@ -159,7 +159,7 @@ static void handle_xdnd_drop(XClientMessageEvent* e) } } }; - + XSendEvent(Xtra.display, e->data.l[0], False, NoEventMask, &ev); } else { Xtra.source_window = e->data.l[0]; @@ -188,57 +188,57 @@ static void handle_xdnd_selection(XSelectionEvent* e) } }; XSendEvent(Xtra.display, Xtra.source_window, False, NoEventMask, &ev); - + Property p = read_property(Xtra.proxy_window, XdndSelection); DropType dt; - + if (strcmp(XGetAtomName(Xtra.display, p.read_type), "text/uri-list") == 0) dt = DT_file_list; else /* text/uri-list */ dt = DT_plain; - - + + /* Call callback for every entry */ if (Xtra.on_drop && p.read_num) { char *sptr; char *str = strtok_r((char *) p.data, "\n\r", &sptr); - + if (str) Xtra.on_drop(str, dt); while ((str = strtok_r(NULL, "\n\r", &sptr))) Xtra.on_drop(str, dt); } - + if (p.data) XFree(p.data); } void *event_loop(void* p) { /* Handle events like a real nigga */ - + (void) p; /* DINDUNOTHIN */ - + XEvent event; int pending; - + while (Xtra.display) { /* NEEDMOEVENTSFODEMPROGRAMS */ - + XLockDisplay(Xtra.display); if((pending = XPending(Xtra.display))) XNextEvent(Xtra.display, &event); - + if (!pending) { XUnlockDisplay(Xtra.display); usleep(10000); continue; } - + if (event.type == ClientMessage) { Atom type = event.xclient.message_type; - + if (type == XdndEnter) handle_xdnd_enter(&event.xclient); else if (type == XdndPosition) handle_xdnd_position(&event.xclient); else if (type == XdndDrop) handle_xdnd_drop(&event.xclient); @@ -247,11 +247,11 @@ void *event_loop(void* p) else if (event.type == SelectionNotify) handle_xdnd_selection(&event.xselection); /* AINNOBODYCANHANDLEDEMEVENTS*/ else XSendEvent(Xtra.display, Xtra.terminal_window, 0, 0, &event); - + XUnlockDisplay(Xtra.display); } - - /* Actual XTRA termination + + /* Actual XTRA termination * Please call xtra_terminate() at exit * otherwise HEWUSAGUDBOI happens */ @@ -262,23 +262,23 @@ void *event_loop(void* p) int init_xtra(drop_callback d) { memset(&Xtra, 0, sizeof(Xtra)); - + if (!d) return -1; else Xtra.on_drop = d; - + XInitThreads(); if ( !(Xtra.display = XOpenDisplay(NULL))) return -1; - + Xtra.terminal_window = focused_window_id(); - + { /* Create an invisible window which will act as proxy for the DnD operation. */ XSetWindowAttributes attr = {0}; - attr.event_mask = EnterWindowMask | - LeaveWindowMask | - ButtonMotionMask | - ButtonPressMask | - ButtonReleaseMask | + attr.event_mask = EnterWindowMask | + LeaveWindowMask | + ButtonMotionMask | + ButtonPressMask | + ButtonReleaseMask | ResizeRedirectMask; attr.do_not_propagate_mask = NoEventMask; @@ -286,14 +286,14 @@ int init_xtra(drop_callback d) Window root; int x, y; unsigned int wht, hht, b, d; - + /* Since we cannot capture resize events for parent window we will have to create - * this window to have maximum size as defined in root window + * this window to have maximum size as defined in root window */ XGetGeometry(Xtra.display, XDefaultRootWindow(Xtra.display), &root, &x, &y, &wht, &hht, &b, &d); - + if (! (Xtra.proxy_window = XCreateWindow (Xtra.display, Xtra.terminal_window, /* Parent */ 0, 0, /* Position */ @@ -306,7 +306,7 @@ int init_xtra(drop_callback d) &attr)) ) /* Attributes for value mask */ return -1; } - + XMapWindow(Xtra.display, Xtra.proxy_window); /* Show window (sandwich) */ XLowerWindow(Xtra.display, Xtra.proxy_window); /* Don't interfere with parent lmao */ @@ -321,7 +321,7 @@ int init_xtra(drop_callback d) XdndTypeList = XInternAtom(Xtra.display, "XdndTypeList", False); XdndActionCopy = XInternAtom(Xtra.display, "XdndActionCopy", False); XdndFinished = XInternAtom(Xtra.display, "XdndFinished", False); - + /* Inform my nigga windows that we are aware of dnd */ Atom XdndVersion = 3; XChangeProperty(Xtra.display, @@ -331,18 +331,20 @@ int init_xtra(drop_callback d) 32, PropModeReplace, (unsigned char*)&XdndVersion, 1); - + pthread_t id; - pthread_create(&id, NULL, event_loop, NULL); + if (pthread_create(&id, NULL, event_loop, NULL) != 0) + return -1; + pthread_detach(id); - + return 0; } void terminate_xtra() { if (!Xtra.display) return; - + XEvent terminate = { .xclient = { .type = ClientMessage, @@ -350,19 +352,19 @@ void terminate_xtra() .message_type = XtraTerminate, } }; - + XLockDisplay(Xtra.display); XDeleteProperty(Xtra.display, Xtra.proxy_window, XdndAware); XSendEvent(Xtra.display, Xtra.proxy_window, 0, NoEventMask, &terminate); XUnlockDisplay(Xtra.display); - + while (Xtra.display); /* Wait for termination */ } long unsigned int focused_window_id() { if (!Xtra.display) return 0; - + Window focus; int revert; XLockDisplay(Xtra.display);