mirror of
https://github.com/Tha14/toxic.git
synced 2024-12-23 03:03:25 +01:00
Convert all variable length arrays to heap allocations
VLA's are inherently unsafe so the safest option is to not use them
This commit is contained in:
parent
ff1620c923
commit
2b43340c90
2
Makefile
2
Makefile
@ -6,7 +6,7 @@ CFG_DIR = $(BASE_DIR)/cfg
|
||||
LIBS = toxcore ncursesw libconfig libcurl
|
||||
|
||||
CFLAGS ?= -g
|
||||
CFLAGS += -std=c99 -pthread -Wall -Wpedantic -Wunused -fstack-protector-all
|
||||
CFLAGS += -std=c99 -pthread -Wall -Wpedantic -Wunused -fstack-protector-all -Wvla
|
||||
CFLAGS += '-DTOXICVER="$(VERSION)"' -DHAVE_WIDECHAR -D_XOPEN_SOURCE_EXTENDED -D_FILE_OFFSET_BITS=64
|
||||
CFLAGS += '-DPACKAGE_DATADIR="$(abspath $(DATADIR))"'
|
||||
CFLAGS += ${USER_CFLAGS}
|
||||
|
@ -301,6 +301,16 @@ DeviceError open_device(DeviceType type, int32_t selection, uint32_t *device_idx
|
||||
return de_FailedStart;
|
||||
}
|
||||
|
||||
size_t zeros_size = frame_size * sizeof(uint16_t);
|
||||
uint16_t *zeros = calloc(1, zeros_size);
|
||||
|
||||
if (zeros == NULL) {
|
||||
free(device);
|
||||
running[type][*device_idx] = NULL;
|
||||
unlock;
|
||||
return de_FailedStart;
|
||||
}
|
||||
|
||||
device->ctx = alcCreateContext(device->dhndl, NULL);
|
||||
alcMakeContextCurrent(device->ctx);
|
||||
|
||||
@ -308,13 +318,12 @@ DeviceError open_device(DeviceType type, int32_t selection, uint32_t *device_idx
|
||||
alGenSources((uint32_t)1, &device->source);
|
||||
alSourcei(device->source, AL_LOOPING, AL_FALSE);
|
||||
|
||||
uint16_t zeros[frame_size];
|
||||
memset(zeros, 0, frame_size * 2);
|
||||
|
||||
for (i = 0; i < OPENAL_BUFS; ++i) {
|
||||
alBufferData(device->buffers[i], device->sound_mode, zeros, frame_size * 2, sample_rate);
|
||||
alBufferData(device->buffers[i], device->sound_mode, zeros, zeros_size, sample_rate);
|
||||
}
|
||||
|
||||
free(zeros);
|
||||
|
||||
alSourceQueueBuffers(device->source, OPENAL_BUFS, device->buffers);
|
||||
alSourcePlay(device->source);
|
||||
}
|
||||
@ -425,10 +434,16 @@ inline__ DeviceError write_out(uint32_t device_idx, const int16_t *data, uint32_
|
||||
alGetSourcei(device->source, AL_BUFFERS_QUEUED, &queued);
|
||||
|
||||
if (processed) {
|
||||
ALuint bufids[processed];
|
||||
ALuint *bufids = malloc(processed * sizeof(ALuint));
|
||||
|
||||
if (bufids == NULL) {
|
||||
return de_InternalError;
|
||||
}
|
||||
|
||||
alSourceUnqueueBuffers(device->source, processed, bufids);
|
||||
alDeleteBuffers(processed - 1, bufids + 1);
|
||||
bufid = bufids[0];
|
||||
free(bufids);
|
||||
} else if (queued < 16) {
|
||||
alGenBuffers(1, &bufid);
|
||||
} else {
|
||||
|
@ -38,20 +38,32 @@
|
||||
#include "execute.h"
|
||||
#include "configdir.h"
|
||||
|
||||
static void print_matches(ToxWindow *self, Tox *m, const void *list, size_t n_items, size_t size)
|
||||
static void print_ac_matches(ToxWindow *self, Tox *m, char **list, size_t n_matches)
|
||||
{
|
||||
if (m) {
|
||||
execute(self->chatwin->history, self, m, "/clear", GLOBAL_COMMAND_MODE);
|
||||
}
|
||||
|
||||
const char *L = (char *) list;
|
||||
int i;
|
||||
for (size_t i = 0; i < n_matches; ++i) {
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "%s", list[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < n_items; ++i) {
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "");
|
||||
}
|
||||
|
||||
static void print_dir_matches(ToxWindow *self, Tox *m, const void *list, size_t n_items, size_t size)
|
||||
{
|
||||
if (m) {
|
||||
execute(self->chatwin->history, self, m, "/clear", GLOBAL_COMMAND_MODE);
|
||||
}
|
||||
|
||||
const char *L = (char *)list;
|
||||
|
||||
for (size_t i = 0; i < n_items; ++i) {
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "%s", &L[i * size]);
|
||||
}
|
||||
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, ""); /* formatting */
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "");
|
||||
}
|
||||
|
||||
/* puts match in match buffer. if more than one match, add first n chars that are identical.
|
||||
@ -59,21 +71,19 @@ static void print_matches(ToxWindow *self, Tox *m, const void *list, size_t n_it
|
||||
*
|
||||
* Returns the length of the match.
|
||||
*/
|
||||
static size_t get_str_match(ToxWindow *self, char *match, size_t match_sz, char (*matches)[MAX_STR_SIZE], int n)
|
||||
static size_t get_str_match(ToxWindow *self, char *match, size_t match_sz, char **matches, size_t n_items,
|
||||
size_t max_size)
|
||||
{
|
||||
UNUSED_VAR(self);
|
||||
|
||||
if (n == 1) {
|
||||
if (n_items == 1) {
|
||||
return snprintf(match, match_sz, "%s", matches[0]);
|
||||
}
|
||||
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_STR_SIZE; ++i) {
|
||||
for (size_t i = 0; i < max_size; ++i) {
|
||||
char ch1 = matches[0][i];
|
||||
int j;
|
||||
|
||||
for (j = 0; j < n; ++j) {
|
||||
for (size_t j = 0; j < n_items; ++j) {
|
||||
char ch2 = matches[j][i];
|
||||
|
||||
if (ch1 != ch2 || !ch1) {
|
||||
@ -102,7 +112,7 @@ static size_t get_str_match(ToxWindow *self, char *match, size_t match_sz, char
|
||||
*
|
||||
* Note: This function should not be called directly. Use complete_line() and complete_path() instead.
|
||||
*/
|
||||
static int complete_line_helper(ToxWindow *self, const void *list, size_t n_items, size_t size, bool dir_search)
|
||||
static int complete_line_helper(ToxWindow *self, const void *list, const size_t n_items, size_t size, bool dir_search)
|
||||
{
|
||||
ChatContext *ctx = self->chatwin;
|
||||
|
||||
@ -161,7 +171,14 @@ static int complete_line_helper(ToxWindow *self, const void *list, size_t n_item
|
||||
|
||||
int s_len = strlen(sub);
|
||||
size_t n_matches = 0;
|
||||
char matches[n_items][MAX_STR_SIZE];
|
||||
|
||||
char **matches = (char **)malloc_ptr_array(n_items, MAX_STR_SIZE, sizeof(char *));
|
||||
|
||||
if (matches == NULL) {
|
||||
free(sub);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
|
||||
/* put all list matches in matches array */
|
||||
@ -177,15 +194,18 @@ static int complete_line_helper(ToxWindow *self, const void *list, size_t n_item
|
||||
free(sub);
|
||||
|
||||
if (!n_matches) {
|
||||
free_ptr_array((void **) matches, n_items);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!dir_search && n_matches > 1) {
|
||||
print_matches(self, NULL, matches, n_matches, MAX_STR_SIZE);
|
||||
print_ac_matches(self, NULL, matches, n_matches);
|
||||
}
|
||||
|
||||
char match[MAX_STR_SIZE];
|
||||
size_t match_len = get_str_match(self, match, sizeof(match), matches, n_matches);
|
||||
size_t match_len = get_str_match(self, match, sizeof(match), matches, n_matches, MAX_STR_SIZE);
|
||||
|
||||
free_ptr_array((void **) matches, n_items);
|
||||
|
||||
if (match_len == 0) {
|
||||
return 0;
|
||||
@ -365,7 +385,7 @@ int dir_match(ToxWindow *self, Tox *m, const wchar_t *line, const wchar_t *cmd)
|
||||
|
||||
if (dircount > 1) {
|
||||
qsort(dirnames, dircount, NAME_MAX + 1, qsort_strcasecmp_hlpr);
|
||||
print_matches(self, m, dirnames, dircount, NAME_MAX + 1);
|
||||
print_dir_matches(self, m, dirnames, dircount, NAME_MAX + 1);
|
||||
}
|
||||
|
||||
return complete_path(self, dirnames, dircount, NAME_MAX + 1);
|
||||
|
@ -196,17 +196,26 @@ void on_avatar_chunk_request(Tox *m, struct FileTransfer *ft, uint64_t position,
|
||||
ft->position = position;
|
||||
}
|
||||
|
||||
uint8_t send_data[length];
|
||||
size_t send_length = fread(send_data, 1, sizeof(send_data), ft->file);
|
||||
uint8_t *send_data = malloc(length);
|
||||
|
||||
if (send_data == NULL) {
|
||||
close_file_transfer(NULL, m, ft, TOX_FILE_CONTROL_CANCEL, NULL, silent);
|
||||
return;
|
||||
}
|
||||
|
||||
size_t send_length = fread(send_data, 1, length, ft->file);
|
||||
|
||||
if (send_length != length) {
|
||||
close_file_transfer(NULL, m, ft, TOX_FILE_CONTROL_CANCEL, NULL, silent);
|
||||
free(send_data);
|
||||
return;
|
||||
}
|
||||
|
||||
Tox_Err_File_Send_Chunk err;
|
||||
tox_file_send_chunk(m, ft->friendnum, ft->filenum, position, send_data, send_length, &err);
|
||||
|
||||
free(send_data);
|
||||
|
||||
if (err != TOX_ERR_FILE_SEND_CHUNK_OK) {
|
||||
fprintf(stderr, "tox_file_send_chunk failed in avatar callback (error %d)\n", err);
|
||||
}
|
||||
|
36
src/chat.c
36
src/chat.c
@ -422,18 +422,28 @@ static void chat_onFileChunkRequest(ToxWindow *self, Tox *m, uint32_t friendnum,
|
||||
ft->position = position;
|
||||
}
|
||||
|
||||
uint8_t send_data[length];
|
||||
size_t send_length = fread(send_data, 1, sizeof(send_data), ft->file);
|
||||
uint8_t *send_data = malloc(length);
|
||||
|
||||
if (send_data == NULL) {
|
||||
snprintf(msg, sizeof(msg), "File transfer for '%s' failed: Out of memory.", ft->file_name);
|
||||
close_file_transfer(self, m, ft, TOX_FILE_CONTROL_CANCEL, msg, notif_error);
|
||||
return;
|
||||
}
|
||||
|
||||
size_t send_length = fread(send_data, 1, length, ft->file);
|
||||
|
||||
if (send_length != length) {
|
||||
snprintf(msg, sizeof(msg), "File transfer for '%s' failed: Read fail.", ft->file_name);
|
||||
close_file_transfer(self, m, ft, TOX_FILE_CONTROL_CANCEL, msg, notif_error);
|
||||
free(send_data);
|
||||
return;
|
||||
}
|
||||
|
||||
Tox_Err_File_Send_Chunk err;
|
||||
tox_file_send_chunk(m, ft->friendnum, ft->filenum, position, send_data, send_length, &err);
|
||||
|
||||
free(send_data);
|
||||
|
||||
if (err != TOX_ERR_FILE_SEND_CHUNK_OK) {
|
||||
fprintf(stderr, "tox_file_send_chunk failed in chat callback (error %d)\n", err);
|
||||
}
|
||||
@ -613,20 +623,29 @@ static void chat_onFileRecv(ToxWindow *self, Tox *m, uint32_t friendnum, uint32_
|
||||
bytes_convert_str(sizestr, sizeof(sizestr), file_size);
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File transfer request for '%s' (%s)", filename, sizestr);
|
||||
|
||||
char file_path[PATH_MAX + name_length + 1];
|
||||
size_t file_path_buf_size = PATH_MAX + name_length + 1;
|
||||
char *file_path = malloc(file_path_buf_size);
|
||||
|
||||
if (file_path == NULL) {
|
||||
tox_file_control(m, friendnum, filenum, TOX_FILE_CONTROL_CANCEL, NULL);
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File transfer failed: Out of memory.");
|
||||
return;
|
||||
}
|
||||
|
||||
size_t path_len = name_length;
|
||||
|
||||
/* use specified download path in config if possible */
|
||||
if (!string_is_empty(user_settings->download_path)) {
|
||||
snprintf(file_path, sizeof(file_path), "%s%s", user_settings->download_path, filename);
|
||||
snprintf(file_path, file_path_buf_size, "%s%s", user_settings->download_path, filename);
|
||||
path_len += strlen(user_settings->download_path);
|
||||
} else {
|
||||
snprintf(file_path, sizeof(file_path), "%s", filename);
|
||||
snprintf(file_path, file_path_buf_size, "%s", filename);
|
||||
}
|
||||
|
||||
if (path_len >= sizeof(file_path) || path_len >= sizeof(ft->file_path) || name_length >= sizeof(ft->file_name)) {
|
||||
if (path_len >= file_path_buf_size || 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.");
|
||||
free(file_path);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -642,7 +661,7 @@ static void chat_onFileRecv(ToxWindow *self, Tox *m, uint32_t friendnum, uint32_
|
||||
++count;
|
||||
size_t d_len = strlen(d);
|
||||
|
||||
if (path_len + d_len >= sizeof(file_path)) {
|
||||
if (path_len + d_len >= file_path_buf_size) {
|
||||
path_len -= d_len;
|
||||
file_path[path_len] = '\0';
|
||||
}
|
||||
@ -653,6 +672,7 @@ static void chat_onFileRecv(ToxWindow *self, Tox *m, uint32_t friendnum, uint32_
|
||||
if (count > 999) {
|
||||
tox_file_control(m, friendnum, filenum, TOX_FILE_CONTROL_CANCEL, NULL);
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File transfer failed: invalid file path.");
|
||||
free(file_path);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -664,6 +684,8 @@ static void chat_onFileRecv(ToxWindow *self, Tox *m, uint32_t friendnum, uint32_
|
||||
snprintf(ft->file_name, sizeof(ft->file_name), "%s", filename);
|
||||
tox_file_get_file_id(m, friendnum, filenum, ft->file_id, NULL);
|
||||
|
||||
free(file_path);
|
||||
|
||||
if (self->active_box != -1) {
|
||||
box_notify2(self, transfer_pending, NT_WNDALERT_0 | NT_NOFOCUS | user_settings->bell_on_filetrans,
|
||||
self->active_box, "Incoming file: %s", filename);
|
||||
|
@ -81,10 +81,18 @@ void print_progress_bar(ToxWindow *self, double bps, double pct_done, uint32_t l
|
||||
strcat(prog_line, "-");
|
||||
}
|
||||
|
||||
char full_line[strlen(pct_str) + NUM_PROG_MARKS + strlen(bps_str) + 7];
|
||||
snprintf(full_line, sizeof(full_line), "%s [%s] %s/s", pct_str, prog_line, bps_str);
|
||||
size_t line_buf_size = strlen(pct_str) + NUM_PROG_MARKS + strlen(bps_str) + 7;
|
||||
char *full_line = malloc(line_buf_size);
|
||||
|
||||
if (full_line == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
snprintf(full_line, line_buf_size, "%s [%s] %s/s", pct_str, prog_line, bps_str);
|
||||
|
||||
line_info_set(self, line_id, full_line);
|
||||
|
||||
free(full_line);
|
||||
}
|
||||
|
||||
static void refresh_progress_helper(ToxWindow *self, struct FileTransfer *ft)
|
||||
|
@ -187,13 +187,21 @@ static int save_blocklist(char *path)
|
||||
return 0;
|
||||
}
|
||||
|
||||
char temp_path[strlen(path) + strlen(TEMP_BLOCKLIST_EXT) + 1];
|
||||
snprintf(temp_path, sizeof(temp_path), "%s%s", path, TEMP_BLOCKLIST_EXT);
|
||||
size_t temp_buf_size = strlen(path) + strlen(TEMP_BLOCKLIST_EXT) + 1;
|
||||
char *temp_path = malloc(temp_buf_size);
|
||||
|
||||
if (temp_path == NULL) {
|
||||
free(data);
|
||||
return -1;
|
||||
}
|
||||
|
||||
snprintf(temp_path, temp_buf_size, "%s%s", path, TEMP_BLOCKLIST_EXT);
|
||||
|
||||
FILE *fp = fopen(temp_path, "wb");
|
||||
|
||||
if (fp == NULL) {
|
||||
free(data);
|
||||
free(temp_path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -201,6 +209,7 @@ static int save_blocklist(char *path)
|
||||
fprintf(stderr, "Failed to write blocklist data.\n");
|
||||
fclose(fp);
|
||||
free(data);
|
||||
free(temp_path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -208,9 +217,12 @@ static int save_blocklist(char *path)
|
||||
free(data);
|
||||
|
||||
if (rename(temp_path, path) != 0) {
|
||||
free(temp_path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
free(temp_path);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -235,15 +247,22 @@ int load_blocklist(char *path)
|
||||
return -1;
|
||||
}
|
||||
|
||||
char data[len];
|
||||
char *data = malloc(len);
|
||||
|
||||
if (data == NULL) {
|
||||
fclose(fp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fread(data, len, 1, fp) != 1) {
|
||||
fclose(fp);
|
||||
free(data);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (len % sizeof(BlockedFriend) != 0) {
|
||||
fclose(fp);
|
||||
free(data);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -251,9 +270,7 @@ int load_blocklist(char *path)
|
||||
Blocked.max_idx = num;
|
||||
realloc_blocklist(num);
|
||||
|
||||
int i;
|
||||
|
||||
for (i = 0; i < num; ++i) {
|
||||
for (int i = 0; i < num; ++i) {
|
||||
BlockedFriend tmp;
|
||||
memset(&tmp, 0, sizeof(BlockedFriend));
|
||||
memset(&Blocked.list[i], 0, sizeof(BlockedFriend));
|
||||
@ -279,6 +296,8 @@ int load_blocklist(char *path)
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
free(data);
|
||||
|
||||
sort_blocklist_index();
|
||||
|
||||
return 0;
|
||||
|
@ -476,45 +476,79 @@ void cmd_myqr(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MA
|
||||
nick[nick_len] = '\0';
|
||||
|
||||
size_t data_file_len = strlen(DATA_FILE);
|
||||
char dir[data_file_len + 1];
|
||||
char *dir = malloc(data_file_len + 1);
|
||||
|
||||
if (dir == NULL) {
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to create QR code: Out of memory.");
|
||||
return;
|
||||
}
|
||||
|
||||
size_t dir_len = get_base_dir(DATA_FILE, data_file_len, dir);
|
||||
|
||||
#ifdef QRPNG
|
||||
|
||||
if (argc == 0) {
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Required 'txt' or 'png'");
|
||||
free(dir);
|
||||
return;
|
||||
} else if (!strcmp(argv[1], "txt")) {
|
||||
|
||||
#endif /* QRPNG */
|
||||
char qr_path[dir_len + nick_len + strlen(QRCODE_FILENAME_EXT) + 1];
|
||||
snprintf(qr_path, sizeof(qr_path), "%s%s%s", dir, nick, QRCODE_FILENAME_EXT);
|
||||
size_t qr_path_buf_size = dir_len + nick_len + strlen(QRCODE_FILENAME_EXT) + 1;
|
||||
char *qr_path = malloc(qr_path_buf_size);
|
||||
|
||||
if (qr_path == NULL) {
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to create QR code: Out of memory");
|
||||
free(dir);
|
||||
return;
|
||||
}
|
||||
|
||||
snprintf(qr_path, qr_path_buf_size, "%s%s%s", dir, nick, QRCODE_FILENAME_EXT);
|
||||
|
||||
if (ID_to_QRcode_txt(id_string, qr_path) == -1) {
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to create QR code.");
|
||||
free(dir);
|
||||
free(qr_path);
|
||||
return;
|
||||
}
|
||||
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "QR code has been printed to the file '%s'", qr_path);
|
||||
|
||||
free(qr_path);
|
||||
|
||||
#ifdef QRPNG
|
||||
} else if (!strcmp(argv[1], "png")) {
|
||||
char qr_path[dir_len + nick_len + strlen(QRCODE_FILENAME_EXT_PNG) + 1];
|
||||
snprintf(qr_path, sizeof(qr_path), "%s%s%s", dir, nick, QRCODE_FILENAME_EXT_PNG);
|
||||
size_t qr_path_buf_size = dir_len + nick_len + strlen(QRCODE_FILENAME_EXT_PNG) + 1;
|
||||
char *qr_path = malloc(qr_path_buf_size);
|
||||
|
||||
if (qr_path == NULL) {
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to create QR code: Out of memory");
|
||||
free(dir);
|
||||
return;
|
||||
}
|
||||
|
||||
snprintf(qr_path, qr_path_buf_size, "%s%s%s", dir, nick, QRCODE_FILENAME_EXT_PNG);
|
||||
|
||||
if (ID_to_QRcode_png(id_string, qr_path) == -1) {
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to create QR code.");
|
||||
free(dir);
|
||||
free(qr_path);
|
||||
return;
|
||||
}
|
||||
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "QR code has been printed to the file '%s'", qr_path);
|
||||
|
||||
free(qr_path);
|
||||
|
||||
} else {
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Unknown option '%s' -- Required 'txt' or 'png'", argv[1]);
|
||||
free(dir);
|
||||
return;
|
||||
}
|
||||
|
||||
#endif /* QRPNG */
|
||||
|
||||
free(dir);
|
||||
}
|
||||
#endif /* QRCODE */
|
||||
|
||||
|
@ -50,16 +50,20 @@ void clear_screen(void)
|
||||
void hst_to_net(uint8_t *num, uint16_t numbytes)
|
||||
{
|
||||
#ifndef WORDS_BIGENDIAN
|
||||
uint32_t i;
|
||||
uint8_t buff[numbytes];
|
||||
uint8_t *buff = malloc(numbytes);
|
||||
|
||||
for (i = 0; i < numbytes; ++i) {
|
||||
if (buff == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < numbytes; ++i) {
|
||||
buff[i] = num[numbytes - i - 1];
|
||||
}
|
||||
|
||||
memcpy(num, buff, numbytes);
|
||||
|
||||
free(buff);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
time_t get_unix_time(void)
|
||||
@ -527,20 +531,31 @@ off_t file_size(const char *path)
|
||||
return st.st_size;
|
||||
}
|
||||
|
||||
/* compares the first size bytes of fp to signature.
|
||||
Returns 0 if they are the same, 1 if they differ, and -1 on error.
|
||||
|
||||
On success this function will seek back to the beginning of fp */
|
||||
/* Compares the first size bytes of fp to signature.
|
||||
*
|
||||
* Returns 0 if they are the same
|
||||
* Returns 1 if they differ
|
||||
* Returns -1 on error.
|
||||
*
|
||||
* On success this function will seek back to the beginning of fp.
|
||||
*/
|
||||
int check_file_signature(const unsigned char *signature, size_t size, FILE *fp)
|
||||
{
|
||||
char buf[size];
|
||||
char *buf = malloc(size);
|
||||
|
||||
if (buf == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fread(buf, size, 1, fp) != 1) {
|
||||
free(buf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ret = memcmp(signature, buf, size);
|
||||
|
||||
free(buf);
|
||||
|
||||
if (fseek(fp, 0L, SEEK_SET) == -1) {
|
||||
return -1;
|
||||
}
|
||||
@ -603,3 +618,45 @@ bool is_ip6_address(const char *address)
|
||||
|
||||
return num_colons > 1 && num_colons < 8;
|
||||
}
|
||||
|
||||
/*
|
||||
* Frees `length` members of pointer array `arr` and frees `arr`.
|
||||
*/
|
||||
void free_ptr_array(void **arr, size_t length)
|
||||
{
|
||||
if (arr == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < length; ++i) {
|
||||
free(arr[i]);
|
||||
}
|
||||
|
||||
free(arr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a new array of `length` pointers of size `ptr_size`. Each pointer is allocated `bytes` bytes.
|
||||
* Returns NULL on failure.
|
||||
*
|
||||
* The caller is responsible for freeing the array with `free_ptr_array`.
|
||||
*/
|
||||
void **malloc_ptr_array(size_t length, size_t bytes, size_t ptr_size)
|
||||
{
|
||||
void **arr = malloc(length * ptr_size);
|
||||
|
||||
if (arr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < length; ++i) {
|
||||
arr[i] = malloc(bytes);
|
||||
|
||||
if (arr[i] == NULL) {
|
||||
free_ptr_array(arr, i);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return arr;
|
||||
}
|
||||
|
@ -169,10 +169,14 @@ File_Type file_type(const char *path);
|
||||
/* returns file size. If file doesn't exist returns 0. */
|
||||
off_t file_size(const char *path);
|
||||
|
||||
/* compares the first size bytes of fp and signature.
|
||||
Returns 0 if they are the same, 1 if they differ, and -1 on error.
|
||||
|
||||
On success this function will seek back to the beginning of fp */
|
||||
/* Compares the first size bytes of fp to signature.
|
||||
*
|
||||
* Returns 0 if they are the same
|
||||
* Returns 1 if they differ
|
||||
* Returns -1 on error.
|
||||
*
|
||||
* On success this function will seek back to the beginning of fp.
|
||||
*/
|
||||
int check_file_signature(const unsigned char *signature, size_t size, FILE *fp);
|
||||
|
||||
/* sets window title in tab bar. */
|
||||
@ -190,4 +194,18 @@ bool is_ip4_address(const char *address);
|
||||
*/
|
||||
bool is_ip6_address(const char *address);
|
||||
|
||||
|
||||
/*
|
||||
* Frees `length` members of pointer array `arr` and frees `arr`.
|
||||
*/
|
||||
void free_ptr_array(void **arr, size_t length);
|
||||
|
||||
/*
|
||||
* Returns a new array of `length` pointers of size `ptr_size`. Each pointer is allocated `bytes` bytes.
|
||||
* Returns NULL on failure.
|
||||
*
|
||||
* The caller is responsible for freeing the array with `free_ptr_array`.
|
||||
*/
|
||||
void **malloc_ptr_array(size_t length, size_t bytes, size_t ptr_size);
|
||||
|
||||
#endif /* MISC_TOOLS_H */
|
||||
|
@ -138,12 +138,18 @@ int ID_to_QRcode_png(const char *tox_id, const char *outfile)
|
||||
|
||||
real_width = (qr_obj->width + BORDER_LEN * 2) * SQUARE_SIZE;
|
||||
size_t row_size = real_width * 4;
|
||||
unsigned char row[row_size];
|
||||
unsigned char *row = malloc(row_size);
|
||||
|
||||
if (row == NULL) {
|
||||
fclose(fp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||
|
||||
if (png_ptr == NULL) {
|
||||
fclose(fp);
|
||||
free(row);
|
||||
QRcode_free(qr_obj);
|
||||
return -1;
|
||||
}
|
||||
@ -152,12 +158,14 @@ int ID_to_QRcode_png(const char *tox_id, const char *outfile)
|
||||
|
||||
if (info_ptr == NULL) {
|
||||
fclose(fp);
|
||||
free(row);
|
||||
QRcode_free(qr_obj);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (setjmp(png_jmpbuf(png_ptr))) {
|
||||
fclose(fp);
|
||||
free(row);
|
||||
QRcode_free(qr_obj);
|
||||
png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||
return -1;
|
||||
@ -206,10 +214,12 @@ int ID_to_QRcode_png(const char *tox_id, const char *outfile)
|
||||
png_write_row(png_ptr, row);
|
||||
}
|
||||
|
||||
free(row);
|
||||
fclose(fp);
|
||||
|
||||
png_write_end(png_ptr, info_ptr);
|
||||
png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||
|
||||
fclose(fp);
|
||||
QRcode_free(qr_obj);
|
||||
|
||||
return 0;
|
||||
|
92
src/toxic.c
92
src/toxic.c
@ -362,7 +362,13 @@ static void load_conferences(Tox *m)
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t chatlist[num_chats];
|
||||
uint32_t *chatlist = malloc(num_chats * sizeof(uint32_t));
|
||||
|
||||
if (chatlist == NULL) {
|
||||
fprintf(stderr, "malloc() failed in load_conferences()\n");
|
||||
return;
|
||||
}
|
||||
|
||||
tox_conference_get_chatlist(m, chatlist);
|
||||
|
||||
for (size_t i = 0; i < num_chats; ++i) {
|
||||
@ -402,6 +408,8 @@ static void load_conferences(Tox *m)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
free(chatlist);
|
||||
}
|
||||
|
||||
/* return length of password on success, 0 on failure */
|
||||
@ -567,12 +575,19 @@ int store_data(Tox *m, const char *path)
|
||||
return -1;
|
||||
}
|
||||
|
||||
char temp_path[strlen(path) + strlen(TEMP_PROFILE_EXT) + 1];
|
||||
snprintf(temp_path, sizeof(temp_path), "%s%s", path, TEMP_PROFILE_EXT);
|
||||
size_t temp_buf_size = strlen(path) + strlen(TEMP_PROFILE_EXT) + 1;
|
||||
char *temp_path = malloc(temp_buf_size);
|
||||
|
||||
if (temp_path == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
snprintf(temp_path, temp_buf_size, "%s%s", path, TEMP_PROFILE_EXT);
|
||||
|
||||
FILE *fp = fopen(temp_path, "wb");
|
||||
|
||||
if (fp == NULL) {
|
||||
free(temp_path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -580,6 +595,7 @@ int store_data(Tox *m, const char *path)
|
||||
char *data = malloc(data_len * sizeof(char));
|
||||
|
||||
if (data == NULL) {
|
||||
free(temp_path);
|
||||
fclose(fp);
|
||||
return -1;
|
||||
}
|
||||
@ -592,6 +608,7 @@ int store_data(Tox *m, const char *path)
|
||||
|
||||
if (enc_data == NULL) {
|
||||
fclose(fp);
|
||||
free(temp_path);
|
||||
free(data);
|
||||
return -1;
|
||||
}
|
||||
@ -603,6 +620,7 @@ int store_data(Tox *m, const char *path)
|
||||
if (err != TOX_ERR_ENCRYPTION_OK) {
|
||||
fprintf(stderr, "tox_pass_encrypt() failed with error %d\n", err);
|
||||
fclose(fp);
|
||||
free(temp_path);
|
||||
free(data);
|
||||
free(enc_data);
|
||||
return -1;
|
||||
@ -611,6 +629,7 @@ int store_data(Tox *m, const char *path)
|
||||
if (fwrite(enc_data, enc_len, 1, fp) != 1) {
|
||||
fprintf(stderr, "Failed to write profile data.\n");
|
||||
fclose(fp);
|
||||
free(temp_path);
|
||||
free(data);
|
||||
free(enc_data);
|
||||
return -1;
|
||||
@ -621,6 +640,7 @@ int store_data(Tox *m, const char *path)
|
||||
if (fwrite(data, data_len, 1, fp) != 1) {
|
||||
fprintf(stderr, "Failed to write profile data.\n");
|
||||
fclose(fp);
|
||||
free(temp_path);
|
||||
free(data);
|
||||
return -1;
|
||||
}
|
||||
@ -630,9 +650,12 @@ int store_data(Tox *m, const char *path)
|
||||
free(data);
|
||||
|
||||
if (rename(temp_path, path) != 0) {
|
||||
free(temp_path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
free(temp_path);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -719,13 +742,22 @@ static Tox *load_tox(char *data_path, struct Tox_Options *tox_opts, Tox_Err_New
|
||||
if (len == 0) {
|
||||
fclose(fp);
|
||||
exit_toxic_err("failed in load_tox", FATALERR_FILEOP);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char data[len];
|
||||
char *data = malloc(len);
|
||||
|
||||
if (fread(data, sizeof(data), 1, fp) != 1) {
|
||||
if (data == NULL) {
|
||||
fclose(fp);
|
||||
exit_toxic_err("failed in load_tox", FATALERR_MEMORY);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (fread(data, len, 1, fp) != 1) {
|
||||
fclose(fp);
|
||||
free(data);
|
||||
exit_toxic_err("failed in load_tox", FATALERR_FILEOP);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool is_encrypted = tox_is_data_encrypted((uint8_t *) data);
|
||||
@ -733,7 +765,9 @@ static Tox *load_tox(char *data_path, struct Tox_Options *tox_opts, Tox_Err_New
|
||||
/* attempt to encrypt an already encrypted data file */
|
||||
if (arg_opts.encrypt_data && is_encrypted) {
|
||||
fclose(fp);
|
||||
free(data);
|
||||
exit_toxic_err("failed in load_tox", FATALERR_ENCRYPT);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (arg_opts.unencrypt_data && is_encrypted) {
|
||||
@ -756,7 +790,13 @@ static Tox *load_tox(char *data_path, struct Tox_Options *tox_opts, Tox_Err_New
|
||||
}
|
||||
|
||||
size_t plain_len = len - TOX_PASS_ENCRYPTION_EXTRA_LENGTH;
|
||||
char plain[plain_len];
|
||||
char *plain = malloc(plain_len); // must be freed after tox_new()
|
||||
|
||||
if (plain == NULL) {
|
||||
fclose(fp);
|
||||
exit_toxic_err("failed in load_tox", FATALERR_MEMORY);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
fflush(stdout); // Flush before prompts so the user sees the question/message
|
||||
@ -771,6 +811,7 @@ static Tox *load_tox(char *data_path, struct Tox_Options *tox_opts, Tox_Err_New
|
||||
|
||||
if (strcasecmp(user_password.pass, "q") == 0) {
|
||||
fclose(fp);
|
||||
free(plain);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
@ -794,6 +835,8 @@ static Tox *load_tox(char *data_path, struct Tox_Options *tox_opts, Tox_Err_New
|
||||
|
||||
if (m == NULL) {
|
||||
fclose(fp);
|
||||
free(data);
|
||||
free(plain);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -805,9 +848,14 @@ static Tox *load_tox(char *data_path, struct Tox_Options *tox_opts, Tox_Err_New
|
||||
pweval = 0;
|
||||
} else {
|
||||
fclose(fp);
|
||||
free(data);
|
||||
free(plain);
|
||||
exit_toxic_err("tox_pass_decrypt() failed", pwerr);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
free(plain);
|
||||
} else { /* data is not encrypted */
|
||||
tox_options_set_savedata_type(tox_opts, TOX_SAVEDATA_TYPE_TOX_SAVE);
|
||||
tox_options_set_savedata_data(tox_opts, (uint8_t *) data, len);
|
||||
@ -816,14 +864,17 @@ static Tox *load_tox(char *data_path, struct Tox_Options *tox_opts, Tox_Err_New
|
||||
|
||||
if (m == NULL) {
|
||||
fclose(fp);
|
||||
free(data);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
free(data);
|
||||
} else { /* Data file does not/should not exist */
|
||||
if (file_exists(data_path)) {
|
||||
exit_toxic_err("failed in load_tox", FATALERR_FILEOP);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tox_options_set_savedata_type(tox_opts, TOX_SAVEDATA_TYPE_NONE);
|
||||
@ -836,6 +887,7 @@ static Tox *load_tox(char *data_path, struct Tox_Options *tox_opts, Tox_Err_New
|
||||
|
||||
if (store_data(m, data_path) == -1) {
|
||||
exit_toxic_err("failed in load_tox", FATALERR_FILEOP);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1207,38 +1259,60 @@ static void parse_args(int argc, char *argv[])
|
||||
#define OLD_DATA_BLOCKLIST_NAME "data-blocklist"
|
||||
static int rename_old_profile(const char *user_config_dir)
|
||||
{
|
||||
char old_data_file[strlen(user_config_dir) + strlen(CONFIGDIR) + strlen(OLD_DATA_NAME) + 1];
|
||||
snprintf(old_data_file, sizeof(old_data_file), "%s%s%s", user_config_dir, CONFIGDIR, OLD_DATA_NAME);
|
||||
size_t old_buf_size = strlen(user_config_dir) + strlen(CONFIGDIR) + strlen(OLD_DATA_NAME) + 1;
|
||||
char *old_data_file = malloc(old_buf_size);
|
||||
|
||||
if (old_data_file == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
snprintf(old_data_file, old_buf_size, "%s%s%s", user_config_dir, CONFIGDIR, OLD_DATA_NAME);
|
||||
|
||||
if (!file_exists(old_data_file)) {
|
||||
free(old_data_file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (file_exists(DATA_FILE)) {
|
||||
free(old_data_file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (rename(old_data_file, DATA_FILE) != 0) {
|
||||
free(old_data_file);
|
||||
return -1;
|
||||
}
|
||||
|
||||
free(old_data_file);
|
||||
|
||||
queue_init_message("Data file has been moved to %s", DATA_FILE);
|
||||
|
||||
char old_data_blocklist[strlen(user_config_dir) + strlen(CONFIGDIR) + strlen(OLD_DATA_BLOCKLIST_NAME) + 1];
|
||||
size_t old_block_buf_size = strlen(user_config_dir) + strlen(CONFIGDIR) + strlen(OLD_DATA_BLOCKLIST_NAME) + 1;
|
||||
char *old_data_blocklist = malloc(old_block_buf_size);
|
||||
|
||||
if (old_data_blocklist == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
snprintf(old_data_blocklist, sizeof(old_data_blocklist), "%s%s%s", user_config_dir, CONFIGDIR, OLD_DATA_BLOCKLIST_NAME);
|
||||
|
||||
if (!file_exists(old_data_blocklist)) {
|
||||
free(old_data_blocklist);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (file_exists(BLOCK_FILE)) {
|
||||
free(old_data_blocklist);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (rename(old_data_blocklist, BLOCK_FILE) != 0) {
|
||||
free(old_data_blocklist);
|
||||
return -1;
|
||||
}
|
||||
|
||||
free(old_data_blocklist);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user