free->tfree. Memory checks, if compiled with -DDEBUG

This commit is contained in:
vysheng 2014-01-10 18:37:56 +04:00
parent a97603031c
commit f06d3c1625
14 changed files with 195 additions and 118 deletions

View File

@ -210,7 +210,7 @@ void replay_log_event (void) {
U->print_name = create_print_name (U->id, "!", P->user.first_name, P->user.last_name, 0);
} else {
static char buf[100];
sprintf (buf, "user#%d", U->user_id);
tsnprintf (buf, 99, "user#%d", U->user_id);
U->print_name = create_print_name (U->id, "!", buf, 0, 0);
}
}
@ -266,7 +266,7 @@ void replay_log_event (void) {
U->print_name = create_print_name (U->id, "!", P->user.first_name, P->user.last_name, 0);
} else {
static char buf[100];
sprintf (buf, "user#%d", U->user_id);
tsnprintf (buf, 99, "user#%d", U->user_id);
U->print_name = create_print_name (U->id, "!", buf, 0, 0);
}
}
@ -335,7 +335,7 @@ void replay_log_event (void) {
peer_id_t id = MK_USER (fetch_int ());
peer_t *U = user_chat_get (id);
assert (U);
if (U->user.phone) { free (U->user.phone); }
if (U->user.phone) { tfree_str (U->user.phone); }
U->user.phone = fetch_str_dup ();
}
rptr = in_ptr;
@ -379,8 +379,8 @@ void replay_log_event (void) {
peer_id_t id = MK_USER (fetch_int ());
peer_t *U = user_chat_get (id);
assert (U);
if (U->user.real_first_name) { free (U->user.real_first_name); }
if (U->user.real_last_name) { free (U->user.real_last_name); }
if (U->user.real_first_name) { tfree_str (U->user.real_first_name); }
if (U->user.real_last_name) { tfree_str (U->user.real_last_name); }
U->user.real_first_name = fetch_str_dup ();
U->user.real_last_name = fetch_str_dup ();
}
@ -397,13 +397,11 @@ void replay_log_event (void) {
U->flags |= FLAG_DELETED;
U->state = sc_deleted;
if (U->nonce) {
memset (U->nonce, 0, 256);
free (U->nonce);
tfree_secure (U->nonce, 256);
U->nonce = 0;
}
if (U->g_key) {
memset (U->g_key, 0, 256);
free (U->g_key);
tfree_secure (U->g_key, 256);
U->g_key = 0;
}
}
@ -431,8 +429,8 @@ void replay_log_event (void) {
if (Us) {
U->print_name = create_print_name (id, "!", Us->user.first_name, Us->user.last_name, 0);
} else {
static char buf[20];
sprintf (buf, "user#%d", U->user_id);
static char buf[100];
tsnprintf (buf, 99, "user#%d", U->user_id);
U->print_name = create_print_name (id, "!", buf, 0, 0);
}
U->g_key = talloc (256);
@ -515,7 +513,7 @@ void replay_log_event (void) {
case CODE_binlog_set_dh_params:
rptr ++;
{
if (encr_prime) { free (encr_prime); }
if (encr_prime) { tfree_str (encr_prime); }
encr_root = *(rptr ++);
encr_prime = talloc (256);
memcpy (encr_prime, rptr, 256);
@ -599,7 +597,7 @@ void replay_log_event (void) {
peer_t *_C = user_chat_get (MK_CHAT (fetch_int ()));
assert (_C && (_C->flags & FLAG_CREATED));
struct chat *C = &_C->chat;
if (C->title) { free (C->title); }
if (C->title) { tfree_str (C->title); }
C->title = fetch_str_dup ();
C->print_title = create_print_name (C->id, C->title, 0, 0, 0);
};
@ -646,8 +644,8 @@ void replay_log_event (void) {
peer_t *C = user_chat_get (MK_CHAT (*(rptr ++)));
assert (C && (C->flags & FLAG_CREATED));
C->chat.user_list_version = *(rptr ++);
if (C->chat.user_list) { tfree (C->chat.user_list, 12 * C->chat.user_list_size); }
C->chat.user_list_size = *(rptr ++);
if (C->chat.user_list) { free (C->chat.user_list); }
C->chat.user_list = talloc (12 * C->chat.user_list_size);
memcpy (C->chat.user_list, rptr, 12 * C->chat.user_list_size);
rptr += 3 * C->chat.user_list_size;
@ -685,7 +683,7 @@ void replay_log_event (void) {
assert (C->user_list[i].user_id != user);
}
C->user_list_size ++;
C->user_list = trealloc (C->user_list, 12 * C->user_list_size);
C->user_list = trealloc (C->user_list, 12 * C->user_list_size - 12, 12 * C->user_list_size);
C->user_list[C->user_list_size - 1].user_id = user;
C->user_list[C->user_list_size - 1].inviter_id = inviter;
C->user_list[C->user_list_size - 1].date = date;
@ -715,7 +713,7 @@ void replay_log_event (void) {
}
assert (C->user_list[C->user_list_size - 1].user_id == user);
C->user_list_size --;
C->user_list = trealloc (C->user_list, 12 * C->user_list_size);
C->user_list = trealloc (C->user_list, 12 * C->user_list_size + 12, 12 * C->user_list_size);
C->user_list_version = version;
}
break;
@ -1026,7 +1024,7 @@ void replay_log_event (void) {
M->id = *(rptr ++);
if (message_get (M->id)) {
free_message (M);
free (M);
tfree (M, sizeof (*M));
} else {
message_insert_tree (M);
message_add_peer (M);
@ -1046,7 +1044,7 @@ void replay_log_event (void) {
message_remove_tree (M);
message_del_peer (M);
free_message (M);
free (M);
tfree (M, sizeof (*M));
}
break;
case CODE_update_user_photo:

View File

@ -214,29 +214,29 @@ char *get_default_prompt (void) {
if (in_chat_mode) {
peer_t *U = user_chat_get (chat_mode_id);
assert (U && U->print_name);
l += sprintf (buf + l, COLOR_RED "%.*s " COLOR_NORMAL, 100, U->print_name);
l += tsnprintf (buf + l, 999 - l, COLOR_RED "%.*s " COLOR_NORMAL, 100, U->print_name);
}
if (unread_messages || cur_uploading_bytes || cur_downloading_bytes) {
l += sprintf (buf + l, COLOR_RED "[");
l += tsnprintf (buf + l, 999 - l, COLOR_RED "[");
int ok = 0;
if (unread_messages) {
l += sprintf (buf + l, "%d unread", unread_messages);
l += tsnprintf (buf + l, 999 - l, "%d unread", unread_messages);
ok = 1;
}
if (cur_uploading_bytes) {
if (ok) { *(buf + l) = ' '; l ++; }
ok = 1;
l += sprintf (buf + l, "%lld%%Up", 100 * cur_uploaded_bytes / cur_uploading_bytes);
l += tsnprintf (buf + l, 999 - l, "%lld%%Up", 100 * cur_uploaded_bytes / cur_uploading_bytes);
}
if (cur_downloading_bytes) {
if (ok) { *(buf + l) = ' '; l ++; }
ok = 1;
l += sprintf (buf + l, "%lld%%Down", 100 * cur_downloaded_bytes / cur_downloading_bytes);
l += tsnprintf (buf + l, 999 - l, "%lld%%Down", 100 * cur_downloaded_bytes / cur_downloading_bytes);
}
l += sprintf (buf + l, "]" COLOR_NORMAL);
l += tsnprintf (buf + l, 999 - l, "]" COLOR_NORMAL);
return buf;
}
l += sprintf (buf + l, "%s", default_prompt);
l += tsnprintf (buf + l, 999 - l, "%s", default_prompt);
return buf;
}
@ -413,7 +413,7 @@ int complete_user_list (int index, const char *text, int len, char **R) {
index ++;
}
if (index < peer_num) {
*R = tstrdup (Peers[index]->print_name);
*R = strdup (Peers[index]->print_name);
return index;
} else {
return -1;
@ -426,7 +426,7 @@ int complete_chat_list (int index, const char *text, int len, char **R) {
index ++;
}
if (index < peer_num) {
*R = tstrdup (Peers[index]->print_name);
*R = strdup (Peers[index]->print_name);
return index;
} else {
return -1;
@ -439,7 +439,7 @@ int complete_encr_chat_list (int index, const char *text, int len, char **R) {
index ++;
}
if (index < peer_num) {
*R = tstrdup (Peers[index]->print_name);
*R = strdup (Peers[index]->print_name);
return index;
} else {
return -1;
@ -452,7 +452,7 @@ int complete_user_chat_list (int index, const char *text, int len, char **R) {
index ++;
}
if (index < peer_num) {
*R = tstrdup (Peers[index]->print_name);
*R = strdup (Peers[index]->print_name);
return index;
} else {
return -1;
@ -465,7 +465,7 @@ int complete_string_list (char **list, int index, const char *text, int len, cha
index ++;
}
if (list[index]) {
*R = tstrdup (list[index]);
*R = strdup (list[index]);
return index;
} else {
*R = 0;
@ -505,7 +505,7 @@ char *command_generator (const char *text, int state) {
if (c) { rl_line_buffer[rl_point] = c; }
return R;
case 1:
index = complete_user_list (index, text, len, &R);
index = complete_user_list (index, text, len, &R);
if (c) { rl_line_buffer[rl_point] = c; }
return R;
case 2:
@ -1095,7 +1095,10 @@ void print_start (void) {
if (readline_active) {
saved_point = rl_point;
#ifdef READLINE_GNU
saved_line = rl_copy_text(0, rl_end);
saved_line = talloc (rl_end + 1);
saved_line[rl_end] = 0;
memcpy (saved_line, rl_line_buffer, rl_end);
rl_save_prompt();
rl_replace_line("", 0);
#else
@ -1122,7 +1125,7 @@ void print_end (void) {
#endif
rl_point = saved_point;
rl_redisplay();
free(saved_line);
tfree_str (saved_line);
}
prompt_was = 0;
}

4
loop.c
View File

@ -510,7 +510,7 @@ int loop (void) {
break;
}
printf ("Invalid code. Try again: ");
free (code);
tfree_str (code);
}
auth_state = 300;
} else {
@ -556,7 +556,7 @@ int loop (void) {
break;
}
printf ("Invalid code. Try again: ");
free (code);
tfree_str (code);
}
auth_state = 300;
}

26
main.c
View File

@ -83,7 +83,7 @@ int allow_weak_random;
void set_default_username (const char *s) {
if (default_username) {
free (default_username);
tfree_str (default_username);
}
default_username = tstrdup (s);
}
@ -143,7 +143,7 @@ char *get_home_directory (void) {
char *get_config_directory (void) {
char *config_directory;
assert (asprintf (&config_directory, "%s/" CONFIG_DIRECTORY, get_home_directory ()) >= 0);
tasprintf (&config_directory, "%s/" CONFIG_DIRECTORY, get_home_directory ());
return config_directory;
}
@ -174,8 +174,8 @@ char *get_binlog_file_name (void) {
char *make_full_path (char *s) {
if (*s != '/') {
char *t = s;
assert (asprintf (&s, "%s/%s", get_home_directory (), s) >= 0);
free (t);
tasprintf (&s, "%s/%s", get_home_directory (), s);
tfree_str (t);
}
return s;
}
@ -189,7 +189,7 @@ void running_for_first_time (void) {
if (config_filename) {
return; // Do not create custom config file
}
assert (asprintf (&config_filename, "%s/%s/%s", get_home_directory (), CONFIG_DIRECTORY, CONFIG_FILE) >= 0);
tasprintf (&config_filename, "%s/%s/%s", get_home_directory (), CONFIG_DIRECTORY, CONFIG_FILE);
config_filename = make_full_path (config_filename);
static struct stat config_file_stat;
@ -201,7 +201,7 @@ void running_for_first_time (void) {
printf ("[%s] created\n", config_directory);
}
free (config_directory);
tfree_str (config_directory);
config_directory = NULL;
// see if config file is there
if (stat (config_filename, &config_file_stat) != 0) {
@ -246,13 +246,13 @@ void parse_config_val (config_t *conf, char **s, char *param_name, const char *d
config_lookup_string (conf, buf, &r);
if (r) {
if (path) {
assert (asprintf (s, "%s/%s", path, r) >= 0);
tasprintf (s, "%s/%s", path, r);
} else {
*s = tstrdup (r);
}
} else {
if (path) {
assert (asprintf (s, "%s/%s", path, default_name) >= 0);
tasprintf (s, "%s/%s", path, default_name);
} else {
*s = tstrdup (default_name);
}
@ -316,11 +316,11 @@ void parse_config (void) {
#else
void parse_config (void) {
printf ("libconfig not enabled\n");
assert (asprintf (&auth_file_name, "%s/%s/%s", get_home_directory (), CONFIG_DIRECTORY, AUTH_KEY_FILE) >= 0);
assert (asprintf (&state_file_name, "%s/%s/%s", get_home_directory (), CONFIG_DIRECTORY, STATE_FILE) >= 0);
assert (asprintf (&secret_chat_file_name, "%s/%s/%s", get_home_directory (), CONFIG_DIRECTORY, SECRET_CHAT_FILE) >= 0);
assert (asprintf (&downloads_directory, "%s/%s/%s", get_home_directory (), CONFIG_DIRECTORY, DOWNLOADS_DIRECTORY) >= 0);
assert (asprintf (&binlog_file_name, "%s/%s/%s", get_home_directory (), CONFIG_DIRECTORY, BINLOG_FILE) >= 0);
tasprintf (&auth_file_name, "%s/%s/%s", get_home_directory (), CONFIG_DIRECTORY, AUTH_KEY_FILE);
tasprintf (&state_file_name, "%s/%s/%s", get_home_directory (), CONFIG_DIRECTORY, STATE_FILE);
tasprintf (&secret_chat_file_name, "%s/%s/%s", get_home_directory (), CONFIG_DIRECTORY, SECRET_CHAT_FILE);
tasprintf (&downloads_directory, "%s/%s/%s", get_home_directory (), CONFIG_DIRECTORY, DOWNLOADS_DIRECTORY);
tasprintf (&binlog_file_name, "%s/%s/%s", get_home_directory (), CONFIG_DIRECTORY, BINLOG_FILE);
}
#endif

View File

@ -830,9 +830,9 @@ void work_update_binlog (void) {
peer_t *UC = user_chat_get (user_id);
if (UC) {
struct user *U = &UC->user;
if (U->first_name) { free (U->first_name); }
if (U->last_name) { free (U->last_name); }
if (U->print_name) { free (U->print_name); }
if (U->first_name) { tfree_str (U->first_name); }
if (U->last_name) { tfree_str (U->last_name); }
if (U->print_name) { tfree_str (U->print_name); }
U->first_name = fetch_str_dup ();
U->last_name = fetch_str_dup ();
U->print_name = create_print_name (U->id, U->first_name, U->last_name, 0, 0);
@ -1199,8 +1199,8 @@ void work_update (struct connection *c UU, long long msg_id UU) {
s, location);
pop_color ();
print_end ();
free (s);
free (location);
tfree_str (s);
tfree_str (location);
}
break;
case CODE_update_new_geo_chat_message:

View File

@ -131,8 +131,7 @@ void prng_seed (const char *password_filename, int password_length) {
}
RAND_seed (a, s);
BN_ctx = BN_CTX_new ();
memset (a, 0, s);
free (a);
tfree_secure (a, 64 + password_length);
}
int serialize_bignum (BIGNUM *b, char *buffer, int maxlen) {

View File

@ -320,7 +320,7 @@ static inline int fetch_update_str (char **s) {
int l = prefetch_strlen ();
char *r = fetch_str (l);
if (memcmp (*s, r, l) || (*s)[l]) {
free (*s);
tfree_str (*s);
*s = talloc (l + 1);
memcpy (*s, r, l);
(*s)[l] = 0;

8
net.c
View File

@ -111,8 +111,8 @@ struct connection_buffer *new_connection_buffer (int size) {
}
void delete_connection_buffer (struct connection_buffer *b) {
free (b->start);
free (b);
tfree (b->start, b->end - b->start);
tfree (b, sizeof (*b));
}
int write_out (struct connection *c, const void *data, int len) {
@ -250,7 +250,7 @@ struct connection *create_connection (const char *host, int port, struct session
if (errno != EINPROGRESS) {
logprintf ( "Can not connect to %s:%d %m\n", host, port);
close (fd);
free (c);
tfree (c, sizeof (*c));
return 0;
}
}
@ -268,7 +268,7 @@ struct connection *create_connection (const char *host, int port, struct session
}
logprintf ("Connect with %s:%d timeout\n", host, port);
close (fd);
free (c);
tfree (c, sizeof (*c));
return 0;
}

View File

@ -191,8 +191,8 @@ void query_error (long long id) {
} else {
logprintf ( "error for query #%lld: #%d :%.*s\n", id, error_code, error_len, error);
}
free (q->data);
free (q);
tfree (q->data, q->data_len * 4);
tfree (q, sizeof (*q));
}
queries_num --;
}
@ -255,8 +255,8 @@ void query_result (long long id UU) {
q->methods->on_answer (q);
assert (in_ptr == in_end);
}
free (q->data);
free (q);
tfree (q->data, 4 * q->data_len);
tfree (q, sizeof (*q));
}
if (end) {
in_ptr = end;
@ -326,7 +326,7 @@ void do_insert_header (void) {
uname (&st);
out_string (st.machine);
static char buf[65536];
sprintf (buf, "%999s %999s %999s", st.sysname, st.release, st.version);
tsnprintf (buf, 65535, "%999s %999s %999s", st.sysname, st.release, st.version);
out_string (buf);
out_string (TG_VERSION " (build " TG_BUILD ")");
out_string ("En");
@ -399,7 +399,7 @@ int send_code_on_answer (struct query *q UU) {
int l = prefetch_strlen ();
char *s = fetch_str (l);
if (phone_code_hash) {
free (phone_code_hash);
tfree_str (phone_code_hash);
}
phone_code_hash = strndup (s, l);
want_dc_num = -1;
@ -933,7 +933,7 @@ void do_send_text (peer_id_t id, char *file_name) {
int fd = open (file_name, O_RDONLY);
if (fd < 0) {
rprintf ("No such file '%s'\n", file_name);
free (file_name);
tfree_str (file_name);
return;
}
static char buf[(1 << 20) + 1];
@ -941,12 +941,12 @@ void do_send_text (peer_id_t id, char *file_name) {
assert (x >= 0);
if (x == (1 << 20) + 1) {
rprintf ("Too big file '%s'\n", file_name);
free (file_name);
tfree_str (file_name);
close (fd);
} else {
buf[x] = 0;
do_send_message (id, buf, x);
free (file_name);
tfree_str (file_name);
close (fd);
}
}
@ -1437,7 +1437,7 @@ void send_part (struct send_file *f) {
MD5 (str, 64, md5);
out_int ((*(int *)md5) ^ (*(int *)(md5 + 4)));
free (f->iv);
tfree_secure (f->iv, 32);
M->media.encr_photo.key = f->key;
M->media.encr_photo.iv = f->init_iv;
@ -1456,8 +1456,8 @@ void send_part (struct send_file *f) {
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &send_encr_file_methods, M);
}
free (f->file_name);
free (f);
tfree_str (f->file_name);
tfree (f, sizeof (*f));
}
}
@ -1769,7 +1769,7 @@ void end_load (struct download *D) {
logprintf ("Done: %s\n", D->name);
} else if (D->next == 2) {
static char buf[PATH_MAX];
if (snprintf (buf, sizeof (buf), OPEN_BIN, D->name) >= (int) sizeof (buf)) {
if (tsnprintf (buf, sizeof (buf), OPEN_BIN, D->name) >= (int) sizeof (buf)) {
logprintf ("Open image command buffer overflow\n");
} else {
int x = system (buf);
@ -1780,10 +1780,10 @@ void end_load (struct download *D) {
}
}
if (D->iv) {
free (D->iv);
tfree_secure (D->iv, 32);
}
free (D->name);
free (D);
tfree_str (D->name);
tfree (D, sizeof (*D));
}
void load_next_part (struct download *D);
@ -1832,9 +1832,9 @@ void load_next_part (struct download *D) {
static char buf[PATH_MAX];
int l;
if (!D->id) {
l = snprintf (buf, sizeof (buf), "%s/download_%lld_%d", get_downloads_directory (), D->volume, D->local_id);
l = tsnprintf (buf, sizeof (buf), "%s/download_%lld_%d", get_downloads_directory (), D->volume, D->local_id);
} else {
l = snprintf (buf, sizeof (buf), "%s/download_%lld", get_downloads_directory (), D->id);
l = tsnprintf (buf, sizeof (buf), "%s/download_%lld", get_downloads_directory (), D->id);
}
if (l >= (int) sizeof (buf)) {
logprintf ("Download filename is too long");
@ -2027,7 +2027,7 @@ int import_auth_on_answer (struct query *q UU) {
assert (fetch_int () == (int)CODE_auth_authorization);
fetch_int (); // expires
fetch_alloc_user ();
free (export_auth_str);
tfree_str (export_auth_str);
export_auth_str = 0;
return 0;
}
@ -2353,8 +2353,7 @@ void do_create_keys_end (struct secret_chat *U) {
U->state = sc_deleted;
}
memset (t, 0, 256);
free (t);
tfree_secure (t, 256);
BN_clear_free (p);
BN_clear_free (g_b);
@ -2432,7 +2431,6 @@ void do_send_create_encr_chat (void *x, unsigned char *random) {
int get_dh_config_on_answer (struct query *q UU) {
unsigned x = fetch_int ();
assert (x == CODE_messages_dh_config || x == CODE_messages_dh_config_not_modified || LOG_DH_CONFIG);
logprintf ("old = %d\n", encr_param_version);
if (x == CODE_messages_dh_config || x == LOG_DH_CONFIG) {
int a = fetch_int ();
int l = prefetch_strlen ();
@ -2449,14 +2447,15 @@ int get_dh_config_on_answer (struct query *q UU) {
if (x == LOG_DH_CONFIG) { return 0; }
int l = prefetch_strlen ();
assert (l == 256);
unsigned char *random = (void *)fetch_str_dup ();
unsigned char *random = talloc (256);
memcpy (random, fetch_str (256), 256);
if (q->extra) {
void **x = q->extra;
((void (*)(void *, void *))(*x))(x[1], random);
free (x);
free (random);
tfree (x, 2 * sizeof (void *));
tfree_secure (random, 256);
} else {
free (random);
tfree_secure (random, 256);
}
return 0;
}

View File

@ -150,7 +150,7 @@ char *create_print_name (peer_id_t id, const char *a1, const char *a2, const cha
int p = 0;
for (i = 0; i < 4; i++) {
if (d[i] && strlen (d[i])) {
p += snprintf (buf + p, 9999 - p, "%s%s", p ? "_" : "", d[i]);
p += tsnprintf (buf + p, 9999 - p, "%s%s", p ? "_" : "", d[i]);
assert (p < 9990);
}
}
@ -177,7 +177,7 @@ char *create_print_name (peer_id_t id, const char *a1, const char *a2, const cha
}
cc ++;
assert (cc <= 9999);
sprintf (s + fl, "#%d", cc);
tsnprintf (s + fl, 9999 - fl, "#%d", cc);
}
return tstrdup (s);
}
@ -595,7 +595,7 @@ void fetch_chat_full (struct chat *C) {
}
if (version > 0) {
bl_do_set_chat_participants (C, version, users_num, users);
free (users);
tfree (users, sizeof (struct chat_user) * users_num);
}
bl_do_set_chat_full_photo (C, start, 4 * (end - start));
}
@ -945,7 +945,9 @@ void fetch_message_media (struct message_media *M) {
M->user_id = fetch_int ();
break;
case CODE_message_media_unsupported:
M->data = fetch_str_dup ();
M->data_size = prefetch_strlen ();
M->data = talloc (M->data_size);
memcpy (M->data, fetch_str (M->data_size), M->data_size);
break;
default:
logprintf ("type = 0x%08x\n", M->type);
@ -1582,41 +1584,41 @@ struct user *fetch_alloc_user_full (void) {
}
void free_user (struct user *U) {
if (U->first_name) { free (U->first_name); }
if (U->last_name) { free (U->last_name); }
if (U->print_name) { free (U->print_name); }
if (U->phone) { free (U->phone); }
if (U->first_name) { tfree_str (U->first_name); }
if (U->last_name) { tfree_str (U->last_name); }
if (U->print_name) { tfree_str (U->print_name); }
if (U->phone) { tfree_str (U->phone); }
}
void free_photo_size (struct photo_size *S) {
free (S->type);
tfree_str (S->type);
if (S->data) {
free (S->data);
tfree (S->data, S->size);
}
}
void free_photo (struct photo *P) {
if (!P->access_hash) { return; }
if (P->caption) { free (P->caption); }
if (P->caption) { tfree_str (P->caption); }
if (P->sizes) {
int i;
for (i = 0; i < P->sizes_num; i++) {
free_photo_size (&P->sizes[i]);
}
free (P->sizes);
tfree (P->sizes, sizeof (struct photo_size) * P->sizes_num);
}
}
void free_video (struct video *V) {
if (!V->access_hash) { return; }
free (V->caption);
tfree_str (V->caption);
free_photo_size (&V->thumb);
}
void free_document (struct document *D) {
if (!D->access_hash) { return; }
free (D->caption);
free (D->mime_type);
tfree_str (D->caption);
tfree_str (D->mime_type);
free_photo_size (&D->thumb);
}
@ -1633,22 +1635,22 @@ void free_message_media (struct message_media *M) {
free_video (&M->video);
return;
case CODE_message_media_contact:
free (M->phone);
free (M->first_name);
free (M->last_name);
tfree_str (M->phone);
tfree_str (M->first_name);
tfree_str (M->last_name);
return;
case CODE_message_media_document:
free_document (&M->document);
return;
case CODE_message_media_unsupported:
free (M->data);
tfree (M->data, M->data_size);
return;
case CODE_decrypted_message_media_photo:
case CODE_decrypted_message_media_video:
case CODE_decrypted_message_media_audio:
case CODE_decrypted_message_media_document:
free (M->encr_photo.key);
free (M->encr_photo.iv);
tfree_secure (M->encr_photo.key, 32);
tfree_secure (M->encr_photo.iv, 32);
return;
case 0:
break;
@ -1663,11 +1665,11 @@ void free_message_action (struct message_action *M) {
case CODE_message_action_empty:
break;
case CODE_message_action_chat_create:
free (M->title);
free (M->users);
tfree_str (M->title);
tfree (M->users, M->user_num * 4);
break;
case CODE_message_action_chat_edit_title:
free (M->new_title);
tfree_str (M->new_title);
break;
case CODE_message_action_chat_edit_photo:
free_photo (&M->photo);
@ -1687,7 +1689,7 @@ void free_message_action (struct message_action *M) {
void free_message (struct message *M) {
if (!M->service) {
if (M->message) { free (M->message); }
if (M->message) { tfree_str (M->message); }
free_message_media (&M->media);
} else {
free_message_action (&M->action);
@ -1808,7 +1810,7 @@ struct message *fetch_alloc_geo_message (void) {
message_del_peer (M1);
free_message (M1);
memcpy (M1, M, sizeof (*M));
free (M);
tfree (M, sizeof (*M));
message_add_use (M1);
message_add_peer (M1);
messages_allocated --;
@ -1904,12 +1906,12 @@ struct chat *fetch_alloc_chat_full (void) {
}
void free_chat (struct chat *U) {
if (U->title) { free (U->title); }
if (U->print_title) { free (U->print_title); }
if (U->title) { tfree_str (U->title); }
if (U->print_title) { tfree_str (U->print_title); }
}
int print_stat (char *s, int len) {
return snprintf (s, len,
return tsnprintf (s, len,
"users_allocated\t%d\n"
"chats_allocated\t%d\n"
"secret_chats_allocated\t%d\n"

View File

@ -298,6 +298,7 @@ struct message_media {
struct encr_document encr_document;
struct encr_file encr_file;
void *data;
int data_size;
};
};

69
tools.c
View File

@ -17,6 +17,8 @@
Copyright Vitaly Valtman 2013
*/
#define _GNU_SOURCE
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
@ -26,21 +28,79 @@
#include "interface.h"
#include "tools.h"
static void out_of_memory (void) {
logprintf ("Out of memory\n");
assert (0 && "Out of memory");
}
void *trealloc (void *ptr, size_t size) {
int tsnprintf (char *buf, int len, const char *format, ...) {
va_list ap;
va_start (ap, format);
int r = vsnprintf (buf, len, format, ap);
va_end (ap);
assert (r <= len && "tsnprintf buffer overflow");
return r;
}
int tasprintf (char **res, const char *format, ...) {
va_list ap;
va_start (ap, format);
int r = vasprintf (res, format, ap);
assert (r >= 0);
va_end (ap);
void *rs = talloc (strlen (*res) + 1);
memcpy (rs, *res, strlen (*res) + 1);
free (*res);
*res = rs;
return r;
}
void tfree (void *ptr, int size) {
#ifdef DEBUG
ptr -= 4;
assert (*(int *)ptr == (int)((size) ^ 0xbedabeda));
assert (*(int *)(ptr + 4 + size) == (int)((size) ^ 0x0bed0bed));
memset (ptr, 0, size + 8);
#endif
free (ptr);
}
void tfree_str (void *ptr) {
if (!ptr) { return; }
tfree (ptr, strlen (ptr) + 1);
}
void tfree_secure (void *ptr, int size) {
memset (ptr, 0, size);
tfree (ptr, size);
}
void *trealloc (void *ptr, size_t old_size __attribute__ ((unused)), size_t size) {
#ifdef DEBUG
void *p = talloc (size);
memcpy (p, ptr, size >= old_size ? old_size : size);
tfree (ptr, old_size);
return p;
#else
void *p = realloc (ptr, size);
ensure_ptr (p);
return p;
#endif
}
void *talloc (size_t size) {
#ifdef DEBUG
void *p = malloc (size + 8);
ensure_ptr (p);
*(int *)p = size ^ 0xbedabeda;
*(int *)(p + 4 + size) = size ^ 0x0bed0bed;
return p + 4;
#else
void *p = malloc (size);
ensure_ptr (p);
return p;
#endif
}
void *talloc0 (size_t size) {
@ -50,11 +110,18 @@ void *talloc0 (size_t size) {
}
char *tstrdup (const char *s) {
#ifdef DEBUG
int l = strlen (s);
char *p = talloc (l + 1);
memcpy (p, s, l + 1);
return p;
#else
char *p = strdup (s);
if (p == NULL) {
out_of_memory ();
}
return p;
#endif
}
void ensure (int r) {

10
tools.h
View File

@ -21,10 +21,18 @@
#define __TOOLS_H__
void *talloc (size_t size);
void *trealloc (void *ptr, size_t size);
void *trealloc (void *ptr, size_t old_size, size_t size);
void *talloc0 (size_t size);
char *tstrdup (const char *s);
void ensure (int r);
void ensure_ptr (void *p);
void tfree (void *ptr, int size);
void tfree_str (void *ptr);
void tfree_secure (void *ptr, int size);
int tsnprintf (char *buf, int len, const char *format, ...) __attribute__ ((format (printf, 3, 4)));
int tasprintf (char **res, const char *format, ...) __attribute__ ((format (printf, 2, 3)));
#endif

2
tree.h
View File

@ -40,7 +40,7 @@ struct tree_ ## X_NAME *new_tree_node_ ## X_NAME (X_TYPE x, int y) {\
}\
\
void delete_tree_node_ ## X_NAME (struct tree_ ## X_NAME *T) {\
free (T);\
tfree (T, sizeof (*T));\
}\
\
void tree_split_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYPE x, struct tree_ ## X_NAME **L, struct tree_ ## X_NAME **R) {\