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

View File

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

4
loop.c
View File

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

26
main.c
View File

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

View File

@ -830,9 +830,9 @@ void work_update_binlog (void) {
peer_t *UC = user_chat_get (user_id); peer_t *UC = user_chat_get (user_id);
if (UC) { if (UC) {
struct user *U = &UC->user; struct user *U = &UC->user;
if (U->first_name) { free (U->first_name); } if (U->first_name) { tfree_str (U->first_name); }
if (U->last_name) { free (U->last_name); } if (U->last_name) { tfree_str (U->last_name); }
if (U->print_name) { free (U->print_name); } if (U->print_name) { tfree_str (U->print_name); }
U->first_name = fetch_str_dup (); U->first_name = fetch_str_dup ();
U->last_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); 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); s, location);
pop_color (); pop_color ();
print_end (); print_end ();
free (s); tfree_str (s);
free (location); tfree_str (location);
} }
break; break;
case CODE_update_new_geo_chat_message: 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); RAND_seed (a, s);
BN_ctx = BN_CTX_new (); BN_ctx = BN_CTX_new ();
memset (a, 0, s); tfree_secure (a, 64 + password_length);
free (a);
} }
int serialize_bignum (BIGNUM *b, char *buffer, int maxlen) { 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 (); int l = prefetch_strlen ();
char *r = fetch_str (l); char *r = fetch_str (l);
if (memcmp (*s, r, l) || (*s)[l]) { if (memcmp (*s, r, l) || (*s)[l]) {
free (*s); tfree_str (*s);
*s = talloc (l + 1); *s = talloc (l + 1);
memcpy (*s, r, l); memcpy (*s, r, l);
(*s)[l] = 0; (*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) { void delete_connection_buffer (struct connection_buffer *b) {
free (b->start); tfree (b->start, b->end - b->start);
free (b); tfree (b, sizeof (*b));
} }
int write_out (struct connection *c, const void *data, int len) { 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) { if (errno != EINPROGRESS) {
logprintf ( "Can not connect to %s:%d %m\n", host, port); logprintf ( "Can not connect to %s:%d %m\n", host, port);
close (fd); close (fd);
free (c); tfree (c, sizeof (*c));
return 0; 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); logprintf ("Connect with %s:%d timeout\n", host, port);
close (fd); close (fd);
free (c); tfree (c, sizeof (*c));
return 0; return 0;
} }

View File

@ -191,8 +191,8 @@ void query_error (long long id) {
} else { } else {
logprintf ( "error for query #%lld: #%d :%.*s\n", id, error_code, error_len, error); logprintf ( "error for query #%lld: #%d :%.*s\n", id, error_code, error_len, error);
} }
free (q->data); tfree (q->data, q->data_len * 4);
free (q); tfree (q, sizeof (*q));
} }
queries_num --; queries_num --;
} }
@ -255,8 +255,8 @@ void query_result (long long id UU) {
q->methods->on_answer (q); q->methods->on_answer (q);
assert (in_ptr == in_end); assert (in_ptr == in_end);
} }
free (q->data); tfree (q->data, 4 * q->data_len);
free (q); tfree (q, sizeof (*q));
} }
if (end) { if (end) {
in_ptr = end; in_ptr = end;
@ -326,7 +326,7 @@ void do_insert_header (void) {
uname (&st); uname (&st);
out_string (st.machine); out_string (st.machine);
static char buf[65536]; 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 (buf);
out_string (TG_VERSION " (build " TG_BUILD ")"); out_string (TG_VERSION " (build " TG_BUILD ")");
out_string ("En"); out_string ("En");
@ -399,7 +399,7 @@ int send_code_on_answer (struct query *q UU) {
int l = prefetch_strlen (); int l = prefetch_strlen ();
char *s = fetch_str (l); char *s = fetch_str (l);
if (phone_code_hash) { if (phone_code_hash) {
free (phone_code_hash); tfree_str (phone_code_hash);
} }
phone_code_hash = strndup (s, l); phone_code_hash = strndup (s, l);
want_dc_num = -1; 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); int fd = open (file_name, O_RDONLY);
if (fd < 0) { if (fd < 0) {
rprintf ("No such file '%s'\n", file_name); rprintf ("No such file '%s'\n", file_name);
free (file_name); tfree_str (file_name);
return; return;
} }
static char buf[(1 << 20) + 1]; static char buf[(1 << 20) + 1];
@ -941,12 +941,12 @@ void do_send_text (peer_id_t id, char *file_name) {
assert (x >= 0); assert (x >= 0);
if (x == (1 << 20) + 1) { if (x == (1 << 20) + 1) {
rprintf ("Too big file '%s'\n", file_name); rprintf ("Too big file '%s'\n", file_name);
free (file_name); tfree_str (file_name);
close (fd); close (fd);
} else { } else {
buf[x] = 0; buf[x] = 0;
do_send_message (id, buf, x); do_send_message (id, buf, x);
free (file_name); tfree_str (file_name);
close (fd); close (fd);
} }
} }
@ -1437,7 +1437,7 @@ void send_part (struct send_file *f) {
MD5 (str, 64, md5); MD5 (str, 64, md5);
out_int ((*(int *)md5) ^ (*(int *)(md5 + 4))); 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.key = f->key;
M->media.encr_photo.iv = f->init_iv; 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); send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &send_encr_file_methods, M);
} }
free (f->file_name); tfree_str (f->file_name);
free (f); tfree (f, sizeof (*f));
} }
} }
@ -1769,7 +1769,7 @@ void end_load (struct download *D) {
logprintf ("Done: %s\n", D->name); logprintf ("Done: %s\n", D->name);
} else if (D->next == 2) { } else if (D->next == 2) {
static char buf[PATH_MAX]; 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"); logprintf ("Open image command buffer overflow\n");
} else { } else {
int x = system (buf); int x = system (buf);
@ -1780,10 +1780,10 @@ void end_load (struct download *D) {
} }
} }
if (D->iv) { if (D->iv) {
free (D->iv); tfree_secure (D->iv, 32);
} }
free (D->name); tfree_str (D->name);
free (D); tfree (D, sizeof (*D));
} }
void load_next_part (struct download *D); void load_next_part (struct download *D);
@ -1832,9 +1832,9 @@ void load_next_part (struct download *D) {
static char buf[PATH_MAX]; static char buf[PATH_MAX];
int l; int l;
if (!D->id) { 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 { } 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)) { if (l >= (int) sizeof (buf)) {
logprintf ("Download filename is too long"); 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); assert (fetch_int () == (int)CODE_auth_authorization);
fetch_int (); // expires fetch_int (); // expires
fetch_alloc_user (); fetch_alloc_user ();
free (export_auth_str); tfree_str (export_auth_str);
export_auth_str = 0; export_auth_str = 0;
return 0; return 0;
} }
@ -2353,8 +2353,7 @@ void do_create_keys_end (struct secret_chat *U) {
U->state = sc_deleted; U->state = sc_deleted;
} }
memset (t, 0, 256); tfree_secure (t, 256);
free (t);
BN_clear_free (p); BN_clear_free (p);
BN_clear_free (g_b); 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) { int get_dh_config_on_answer (struct query *q UU) {
unsigned x = fetch_int (); unsigned x = fetch_int ();
assert (x == CODE_messages_dh_config || x == CODE_messages_dh_config_not_modified || LOG_DH_CONFIG); 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) { if (x == CODE_messages_dh_config || x == LOG_DH_CONFIG) {
int a = fetch_int (); int a = fetch_int ();
int l = prefetch_strlen (); 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; } if (x == LOG_DH_CONFIG) { return 0; }
int l = prefetch_strlen (); int l = prefetch_strlen ();
assert (l == 256); assert (l == 256);
unsigned char *random = (void *)fetch_str_dup (); unsigned char *random = talloc (256);
memcpy (random, fetch_str (256), 256);
if (q->extra) { if (q->extra) {
void **x = q->extra; void **x = q->extra;
((void (*)(void *, void *))(*x))(x[1], random); ((void (*)(void *, void *))(*x))(x[1], random);
free (x); tfree (x, 2 * sizeof (void *));
free (random); tfree_secure (random, 256);
} else { } else {
free (random); tfree_secure (random, 256);
} }
return 0; 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; int p = 0;
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
if (d[i] && strlen (d[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); assert (p < 9990);
} }
} }
@ -177,7 +177,7 @@ char *create_print_name (peer_id_t id, const char *a1, const char *a2, const cha
} }
cc ++; cc ++;
assert (cc <= 9999); assert (cc <= 9999);
sprintf (s + fl, "#%d", cc); tsnprintf (s + fl, 9999 - fl, "#%d", cc);
} }
return tstrdup (s); return tstrdup (s);
} }
@ -595,7 +595,7 @@ void fetch_chat_full (struct chat *C) {
} }
if (version > 0) { if (version > 0) {
bl_do_set_chat_participants (C, version, users_num, users); 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)); 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 (); M->user_id = fetch_int ();
break; break;
case CODE_message_media_unsupported: 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; break;
default: default:
logprintf ("type = 0x%08x\n", M->type); logprintf ("type = 0x%08x\n", M->type);
@ -1582,41 +1584,41 @@ struct user *fetch_alloc_user_full (void) {
} }
void free_user (struct user *U) { void free_user (struct user *U) {
if (U->first_name) { free (U->first_name); } if (U->first_name) { tfree_str (U->first_name); }
if (U->last_name) { free (U->last_name); } if (U->last_name) { tfree_str (U->last_name); }
if (U->print_name) { free (U->print_name); } if (U->print_name) { tfree_str (U->print_name); }
if (U->phone) { free (U->phone); } if (U->phone) { tfree_str (U->phone); }
} }
void free_photo_size (struct photo_size *S) { void free_photo_size (struct photo_size *S) {
free (S->type); tfree_str (S->type);
if (S->data) { if (S->data) {
free (S->data); tfree (S->data, S->size);
} }
} }
void free_photo (struct photo *P) { void free_photo (struct photo *P) {
if (!P->access_hash) { return; } if (!P->access_hash) { return; }
if (P->caption) { free (P->caption); } if (P->caption) { tfree_str (P->caption); }
if (P->sizes) { if (P->sizes) {
int i; int i;
for (i = 0; i < P->sizes_num; i++) { for (i = 0; i < P->sizes_num; i++) {
free_photo_size (&P->sizes[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) { void free_video (struct video *V) {
if (!V->access_hash) { return; } if (!V->access_hash) { return; }
free (V->caption); tfree_str (V->caption);
free_photo_size (&V->thumb); free_photo_size (&V->thumb);
} }
void free_document (struct document *D) { void free_document (struct document *D) {
if (!D->access_hash) { return; } if (!D->access_hash) { return; }
free (D->caption); tfree_str (D->caption);
free (D->mime_type); tfree_str (D->mime_type);
free_photo_size (&D->thumb); free_photo_size (&D->thumb);
} }
@ -1633,22 +1635,22 @@ void free_message_media (struct message_media *M) {
free_video (&M->video); free_video (&M->video);
return; return;
case CODE_message_media_contact: case CODE_message_media_contact:
free (M->phone); tfree_str (M->phone);
free (M->first_name); tfree_str (M->first_name);
free (M->last_name); tfree_str (M->last_name);
return; return;
case CODE_message_media_document: case CODE_message_media_document:
free_document (&M->document); free_document (&M->document);
return; return;
case CODE_message_media_unsupported: case CODE_message_media_unsupported:
free (M->data); tfree (M->data, M->data_size);
return; return;
case CODE_decrypted_message_media_photo: case CODE_decrypted_message_media_photo:
case CODE_decrypted_message_media_video: case CODE_decrypted_message_media_video:
case CODE_decrypted_message_media_audio: case CODE_decrypted_message_media_audio:
case CODE_decrypted_message_media_document: case CODE_decrypted_message_media_document:
free (M->encr_photo.key); tfree_secure (M->encr_photo.key, 32);
free (M->encr_photo.iv); tfree_secure (M->encr_photo.iv, 32);
return; return;
case 0: case 0:
break; break;
@ -1663,11 +1665,11 @@ void free_message_action (struct message_action *M) {
case CODE_message_action_empty: case CODE_message_action_empty:
break; break;
case CODE_message_action_chat_create: case CODE_message_action_chat_create:
free (M->title); tfree_str (M->title);
free (M->users); tfree (M->users, M->user_num * 4);
break; break;
case CODE_message_action_chat_edit_title: case CODE_message_action_chat_edit_title:
free (M->new_title); tfree_str (M->new_title);
break; break;
case CODE_message_action_chat_edit_photo: case CODE_message_action_chat_edit_photo:
free_photo (&M->photo); free_photo (&M->photo);
@ -1687,7 +1689,7 @@ void free_message_action (struct message_action *M) {
void free_message (struct message *M) { void free_message (struct message *M) {
if (!M->service) { if (!M->service) {
if (M->message) { free (M->message); } if (M->message) { tfree_str (M->message); }
free_message_media (&M->media); free_message_media (&M->media);
} else { } else {
free_message_action (&M->action); free_message_action (&M->action);
@ -1808,7 +1810,7 @@ struct message *fetch_alloc_geo_message (void) {
message_del_peer (M1); message_del_peer (M1);
free_message (M1); free_message (M1);
memcpy (M1, M, sizeof (*M)); memcpy (M1, M, sizeof (*M));
free (M); tfree (M, sizeof (*M));
message_add_use (M1); message_add_use (M1);
message_add_peer (M1); message_add_peer (M1);
messages_allocated --; messages_allocated --;
@ -1904,12 +1906,12 @@ struct chat *fetch_alloc_chat_full (void) {
} }
void free_chat (struct chat *U) { void free_chat (struct chat *U) {
if (U->title) { free (U->title); } if (U->title) { tfree_str (U->title); }
if (U->print_title) { free (U->print_title); } if (U->print_title) { tfree_str (U->print_title); }
} }
int print_stat (char *s, int len) { int print_stat (char *s, int len) {
return snprintf (s, len, return tsnprintf (s, len,
"users_allocated\t%d\n" "users_allocated\t%d\n"
"chats_allocated\t%d\n" "chats_allocated\t%d\n"
"secret_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_document encr_document;
struct encr_file encr_file; struct encr_file encr_file;
void *data; void *data;
int data_size;
}; };
}; };

69
tools.c
View File

@ -17,6 +17,8 @@
Copyright Vitaly Valtman 2013 Copyright Vitaly Valtman 2013
*/ */
#define _GNU_SOURCE
#include <assert.h> #include <assert.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -26,21 +28,79 @@
#include "interface.h" #include "interface.h"
#include "tools.h" #include "tools.h"
static void out_of_memory (void) { static void out_of_memory (void) {
logprintf ("Out of memory\n"); logprintf ("Out of memory\n");
assert (0 && "Out of memory"); 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); void *p = realloc (ptr, size);
ensure_ptr (p); ensure_ptr (p);
return p; return p;
#endif
} }
void *talloc (size_t size) { 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); void *p = malloc (size);
ensure_ptr (p); ensure_ptr (p);
return p; return p;
#endif
} }
void *talloc0 (size_t size) { void *talloc0 (size_t size) {
@ -50,11 +110,18 @@ void *talloc0 (size_t size) {
} }
char *tstrdup (const char *s) { 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); char *p = strdup (s);
if (p == NULL) { if (p == NULL) {
out_of_memory (); out_of_memory ();
} }
return p; return p;
#endif
} }
void ensure (int r) { void ensure (int r) {

10
tools.h
View File

@ -21,10 +21,18 @@
#define __TOOLS_H__ #define __TOOLS_H__
void *talloc (size_t size); 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); void *talloc0 (size_t size);
char *tstrdup (const char *s); char *tstrdup (const char *s);
void ensure (int r); void ensure (int r);
void ensure_ptr (void *p); 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 #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) {\ 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) {\ void tree_split_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYPE x, struct tree_ ## X_NAME **L, struct tree_ ## X_NAME **R) {\