refactor: optimize hash table iterations and fix security issues #58
Some checks failed
CI Code / Check coding style (pull_request) Successful in 38s
CI API Docs / Test Python API Documentation Generation (pull_request) Has been cancelled
CI API Docs / Test C API Documentation Generation (pull_request) Has been cancelled
CI Code / Check spelling (pull_request) Successful in 49s
CI Code / Linux (ubuntu) (pull_request) Successful in 6m22s
CI Code / Linux (debian) (pull_request) Successful in 9m3s
CI Code / Code Coverage (pull_request) Successful in 9m16s
CI Code / Linux (arch) (pull_request) Successful in 11m20s

- refactor(core): replace g_hash_table_get_keys with g_hash_table_iter_init
  * Eliminates temporary GList allocations
  * Improves iteration performance
  * Affected: connection.c, cmd_defs.c, cmd_funcs.c, omemo.c, gpg.c,
    disco.c, form.c, autocompleters.c, capabilities.c, callbacks.c

- fix(xmpp): correct queued_messages loop in connection.c:1031
  * Remove incorrect NULL check that prevented message storage
  * calloc zeros array, causing loop to skip immediately
  * Fixes dropped messages during reconnection with SM enabled

- fix(ui): prevent format string vulnerabilities in cons_show calls
  * Replace cons_show(variable) with cons_show("%s", variable)
  * Protects against format string attacks if variables contain %
  * Updated instances across cmd_funcs.c, connection.c, ox.c,
    console.c, core.c
This commit is contained in:
2025-11-10 18:51:16 +03:00
parent b2ce06923e
commit 58dd89be40
13 changed files with 143 additions and 177 deletions

View File

@@ -2825,16 +2825,15 @@ cmd_search_index_any(char* term)
int terms_len = g_strv_length(processed_terms); int terms_len = g_strv_length(processed_terms);
for (int i = 0; i < terms_len; i++) { for (int i = 0; i < terms_len; i++) {
GList* index_keys = g_hash_table_get_keys(search_index); GHashTableIter iter;
GList* curr = index_keys; gpointer key, value;
while (curr) { g_hash_table_iter_init(&iter, search_index);
char* index_entry = g_hash_table_lookup(search_index, curr->data); while (g_hash_table_iter_next(&iter, &key, &value)) {
char* index_entry = (char*)value;
if (g_str_match_string(processed_terms[i], index_entry, FALSE)) { if (g_str_match_string(processed_terms[i], index_entry, FALSE)) {
results = g_list_append(results, curr->data); results = g_list_append(results, key);
} }
curr = g_list_next(curr);
} }
g_list_free(index_keys);
} }
return results; return results;
@@ -2848,13 +2847,14 @@ cmd_search_index_all(char* term)
auto_gcharv gchar** terms = g_str_tokenize_and_fold(term, NULL, NULL); auto_gcharv gchar** terms = g_str_tokenize_and_fold(term, NULL, NULL);
int terms_len = g_strv_length(terms); int terms_len = g_strv_length(terms);
GList* commands = g_hash_table_get_keys(search_index); GHashTableIter iter;
GList* curr = commands; gpointer key, value;
while (curr) { g_hash_table_iter_init(&iter, search_index);
char* command = curr->data; while (g_hash_table_iter_next(&iter, &key, &value)) {
char* command = (char*)key;
char* command_index = (char*)value;
int matches = 0; int matches = 0;
for (int i = 0; i < terms_len; i++) { for (int i = 0; i < terms_len; i++) {
char* command_index = g_hash_table_lookup(search_index, command);
if (g_str_match_string(terms[i], command_index, FALSE)) { if (g_str_match_string(terms[i], command_index, FALSE)) {
matches++; matches++;
} }
@@ -2862,11 +2862,8 @@ cmd_search_index_all(char* term)
if (matches == terms_len) { if (matches == terms_len) {
results = g_list_append(results, command); results = g_list_append(results, command);
} }
curr = g_list_next(curr);
} }
g_list_free(commands);
return results; return results;
} }

View File

@@ -184,7 +184,7 @@ _string_matches_one_of(const char* what, const char* is, bool is_can_be_null, co
} }
va_end(ap); va_end(ap);
if (s > 0) if (s > 0)
cons_show(errmsg); cons_show("%s", errmsg);
} }
return ret; return ret;
} }
@@ -418,7 +418,7 @@ cmd_connect(ProfWin* window, const char* const command, gchar** args)
auto_char char* err_msg = NULL; auto_char char* err_msg = NULL;
gboolean res = strtoi_range(port_str, &port, 1, 65535, &err_msg); gboolean res = strtoi_range(port_str, &port, 1, 65535, &err_msg);
if (!res) { if (!res) {
cons_show(err_msg); cons_show("%s", err_msg);
cons_show(""); cons_show("");
port = 0; port = 0;
options_destroy(options); options_destroy(options);
@@ -711,7 +711,7 @@ _account_set_port(char* account_name, char* port)
auto_char char* err_msg = NULL; auto_char char* err_msg = NULL;
gboolean res = strtoi_range(port, &porti, 1, 65535, &err_msg); gboolean res = strtoi_range(port, &porti, 1, 65535, &err_msg);
if (!res) { if (!res) {
cons_show(err_msg); cons_show("%s", err_msg);
cons_show(""); cons_show("");
} else { } else {
accounts_set_port(account_name, porti); accounts_set_port(account_name, porti);
@@ -903,7 +903,7 @@ _account_set_max_sessions(char* account_name, char* max_sessions_raw)
auto_char char* err_msg = NULL; auto_char char* err_msg = NULL;
gboolean res = strtoi_range(max_sessions_raw, &max_sessions, 0, INT_MAX, &err_msg); gboolean res = strtoi_range(max_sessions_raw, &max_sessions, 0, INT_MAX, &err_msg);
if (!res) { if (!res) {
cons_show(err_msg); cons_show("%s", err_msg);
cons_show(""); cons_show("");
return TRUE; return TRUE;
} }
@@ -924,7 +924,7 @@ _account_set_presence_priority(char* account_name, char* presence, char* priorit
auto_char char* err_msg = NULL; auto_char char* err_msg = NULL;
gboolean res = strtoi_range(priority, &intval, -128, 127, &err_msg); gboolean res = strtoi_range(priority, &intval, -128, 127, &err_msg);
if (!res) { if (!res) {
cons_show(err_msg); cons_show("%s", err_msg);
return TRUE; return TRUE;
} }
@@ -1580,7 +1580,7 @@ _cmd_list_commands(GList* commands)
while (curr) { while (curr) {
gchar* cmd = curr->data; gchar* cmd = curr->data;
if (count == 5) { if (count == 5) {
cons_show(cmds->str); cons_show("%s", cmds->str);
g_string_free(cmds, TRUE); g_string_free(cmds, TRUE);
cmds = g_string_new(""); cmds = g_string_new("");
count = 0; count = 0;
@@ -1589,7 +1589,7 @@ _cmd_list_commands(GList* commands)
curr = g_list_next(curr); curr = g_list_next(curr);
count++; count++;
} }
cons_show(cmds->str); cons_show("%s", cmds->str);
g_string_free(cmds, TRUE); g_string_free(cmds, TRUE);
g_list_free(curr); g_list_free(curr);
@@ -2407,7 +2407,7 @@ cmd_roster(ProfWin* window, const char* const command, gchar** args)
} }
return TRUE; return TRUE;
} else { } else {
cons_show(err_msg); cons_show("%s", err_msg);
return TRUE; return TRUE;
} }
@@ -2467,7 +2467,7 @@ cmd_roster(ProfWin* window, const char* const command, gchar** args)
cons_show("Roster contact indent set to: %d", intval); cons_show("Roster contact indent set to: %d", intval);
rosterwin_roster(); rosterwin_roster();
} else { } else {
cons_show(err_msg); cons_show("%s", err_msg);
} }
} }
} else { } else {
@@ -2501,7 +2501,7 @@ cmd_roster(ProfWin* window, const char* const command, gchar** args)
cons_show("Roster resource indent set to: %d", intval); cons_show("Roster resource indent set to: %d", intval);
rosterwin_roster(); rosterwin_roster();
} else { } else {
cons_show(err_msg); cons_show("%s", err_msg);
} }
} }
} else if (g_strcmp0(args[1], "join") == 0) { } else if (g_strcmp0(args[1], "join") == 0) {
@@ -2527,7 +2527,7 @@ cmd_roster(ProfWin* window, const char* const command, gchar** args)
cons_show("Roster presence indent set to: %d", intval); cons_show("Roster presence indent set to: %d", intval);
rosterwin_roster(); rosterwin_roster();
} else { } else {
cons_show(err_msg); cons_show("%s", err_msg);
} }
} }
} else { } else {
@@ -4371,7 +4371,7 @@ cmd_occupants(ProfWin* window, const char* const command, gchar** args)
wins_resize_all(); wins_resize_all();
return TRUE; return TRUE;
} else { } else {
cons_show(err_msg); cons_show("%s", err_msg);
return TRUE; return TRUE;
} }
} }
@@ -4391,7 +4391,7 @@ cmd_occupants(ProfWin* window, const char* const command, gchar** args)
occupantswin_occupants_all(); occupantswin_occupants_all();
} else { } else {
cons_show(err_msg); cons_show("%s", err_msg);
} }
return TRUE; return TRUE;
} }
@@ -5836,7 +5836,7 @@ cmd_inpblock(ProfWin* window, const char* const command, gchar** args)
prefs_set_inpblock(intval); prefs_set_inpblock(intval);
inp_nonblocking(FALSE); inp_nonblocking(FALSE);
} else { } else {
cons_show(err_msg); cons_show("%s", err_msg);
} }
return TRUE; return TRUE;
@@ -6063,7 +6063,7 @@ cmd_statusbar(ProfWin* window, const char* const command, gchar** args)
ui_resize(); ui_resize();
return TRUE; return TRUE;
} else { } else {
cons_show(err_msg); cons_show("%s", err_msg);
cons_bad_cmd_usage(command); cons_bad_cmd_usage(command);
return TRUE; return TRUE;
} }
@@ -6094,7 +6094,7 @@ cmd_statusbar(ProfWin* window, const char* const command, gchar** args)
ui_resize(); ui_resize();
return TRUE; return TRUE;
} else { } else {
cons_show(err_msg); cons_show("%s", err_msg);
cons_bad_cmd_usage(command); cons_bad_cmd_usage(command);
return TRUE; return TRUE;
} }
@@ -6254,7 +6254,7 @@ cmd_log(ProfWin* window, const char* const command, gchar** args)
prefs_set_max_log_size(intval); prefs_set_max_log_size(intval);
cons_show("Log maximum size set to %d bytes", intval); cons_show("Log maximum size set to %d bytes", intval);
} else { } else {
cons_show(err_msg); cons_show("%s", err_msg);
} }
return TRUE; return TRUE;
} }
@@ -6304,7 +6304,7 @@ cmd_reconnect(ProfWin* window, const char* const command, gchar** args)
cons_show("Reconnect interval set to %d seconds.", intval); cons_show("Reconnect interval set to %d seconds.", intval);
} }
} else { } else {
cons_show(err_msg); cons_show("%s", err_msg);
cons_bad_cmd_usage(command); cons_bad_cmd_usage(command);
} }
@@ -6330,7 +6330,7 @@ cmd_autoping(ProfWin* window, const char* const command, gchar** args)
cons_show("Autoping interval set to %d seconds.", intval); cons_show("Autoping interval set to %d seconds.", intval);
} }
} else { } else {
cons_show(err_msg); cons_show("%s", err_msg);
cons_bad_cmd_usage(command); cons_bad_cmd_usage(command);
} }
@@ -6346,7 +6346,7 @@ cmd_autoping(ProfWin* window, const char* const command, gchar** args)
cons_show("Autoping timeout set to %d seconds.", intval); cons_show("Autoping timeout set to %d seconds.", intval);
} }
} else { } else {
cons_show(err_msg); cons_show("%s", err_msg);
cons_bad_cmd_usage(command); cons_bad_cmd_usage(command);
} }
@@ -6416,7 +6416,7 @@ cmd_autoaway(ProfWin* window, const char* const command, gchar** args)
cons_show("Auto away time set to: %d minutes.", minutesval); cons_show("Auto away time set to: %d minutes.", minutesval);
} }
} else { } else {
cons_show(err_msg); cons_show("%s", err_msg);
} }
return TRUE; return TRUE;
@@ -6439,7 +6439,7 @@ cmd_autoaway(ProfWin* window, const char* const command, gchar** args)
} }
} }
} else { } else {
cons_show(err_msg); cons_show("%s", err_msg);
} }
return TRUE; return TRUE;
@@ -6506,7 +6506,7 @@ cmd_priority(ProfWin* window, const char* const command, gchar** args)
cl_ev_presence_send(last_presence, 0); cl_ev_presence_send(last_presence, 0);
cons_show("Priority set to %d.", intval); cons_show("Priority set to %d.", intval);
} else { } else {
cons_show(err_msg); cons_show("%s", err_msg);
} }
return TRUE; return TRUE;
@@ -6576,7 +6576,7 @@ cmd_tray(ProfWin* window, const char* const command, gchar** args)
tray_set_timer(intval); tray_set_timer(intval);
} }
} else { } else {
cons_show(err_msg); cons_show("%s", err_msg);
} }
return TRUE; return TRUE;
@@ -7181,22 +7181,21 @@ cmd_pgp(ProfWin* window, const char* const command, gchar** args)
} }
cons_show("PGP keys:"); cons_show("PGP keys:");
GList* keylist = g_hash_table_get_keys(keys); GHashTableIter iter;
GList* curr = keylist; gpointer key, value;
while (curr) { g_hash_table_iter_init(&iter, keys);
ProfPGPKey* key = g_hash_table_lookup(keys, curr->data); while (g_hash_table_iter_next(&iter, &key, &value)) {
cons_show(" %s", key->name); ProfPGPKey* pgp_key = (ProfPGPKey*)value;
cons_show(" ID : %s", key->id); cons_show(" %s", pgp_key->name);
auto_char char* format_fp = p_gpg_format_fp_str(key->fp); cons_show(" ID : %s", pgp_key->id);
auto_char char* format_fp = p_gpg_format_fp_str(pgp_key->fp);
cons_show(" Fingerprint : %s", format_fp); cons_show(" Fingerprint : %s", format_fp);
if (key->secret) { if (pgp_key->secret) {
cons_show(" Type : PUBLIC, PRIVATE"); cons_show(" Type : PUBLIC, PRIVATE");
} else { } else {
cons_show(" Type : PUBLIC"); cons_show(" Type : PUBLIC");
} }
curr = g_list_next(curr);
} }
g_list_free(keylist);
p_gpg_free_keys(keys); p_gpg_free_keys(keys);
return TRUE; return TRUE;
} }
@@ -7237,25 +7236,24 @@ cmd_pgp(ProfWin* window, const char* const command, gchar** args)
return TRUE; return TRUE;
} }
GHashTable* pubkeys = p_gpg_pubkeys(); GHashTable* pubkeys = p_gpg_pubkeys();
GList* jids = g_hash_table_get_keys(pubkeys); if (!pubkeys || g_hash_table_size(pubkeys) == 0) {
if (!jids) {
cons_show("No contacts found with PGP public keys assigned."); cons_show("No contacts found with PGP public keys assigned.");
return TRUE; return TRUE;
} }
cons_show("Assigned PGP public keys:"); cons_show("Assigned PGP public keys:");
GList* curr = jids; GHashTableIter iter;
while (curr) { gpointer key, value;
char* jid = curr->data; g_hash_table_iter_init(&iter, pubkeys);
ProfPGPPubKeyId* pubkeyid = g_hash_table_lookup(pubkeys, jid); while (g_hash_table_iter_next(&iter, &key, &value)) {
char* jid = (char*)key;
ProfPGPPubKeyId* pubkeyid = (ProfPGPPubKeyId*)value;
if (pubkeyid->received) { if (pubkeyid->received) {
cons_show(" %s: %s (received)", jid, pubkeyid->id); cons_show(" %s: %s (received)", jid, pubkeyid->id);
} else { } else {
cons_show(" %s: %s (stored)", jid, pubkeyid->id); cons_show(" %s: %s (stored)", jid, pubkeyid->id);
} }
curr = g_list_next(curr);
} }
g_list_free(jids);
return TRUE; return TRUE;
} }
@@ -7468,22 +7466,21 @@ cmd_ox(ProfWin* window, const char* const command, gchar** args)
} }
cons_show("OpenPGP keys:"); cons_show("OpenPGP keys:");
GList* keylist = g_hash_table_get_keys(keys); GHashTableIter iter;
GList* curr = keylist; gpointer key, value;
while (curr) { g_hash_table_iter_init(&iter, keys);
ProfPGPKey* key = g_hash_table_lookup(keys, curr->data); while (g_hash_table_iter_next(&iter, &key, &value)) {
cons_show(" %s", key->name); ProfPGPKey* pgp_key = (ProfPGPKey*)value;
cons_show(" ID : %s", key->id); cons_show(" %s", pgp_key->name);
auto_char char* format_fp = p_gpg_format_fp_str(key->fp); cons_show(" ID : %s", pgp_key->id);
auto_char char* format_fp = p_gpg_format_fp_str(pgp_key->fp);
cons_show(" Fingerprint : %s", format_fp); cons_show(" Fingerprint : %s", format_fp);
if (key->secret) { if (pgp_key->secret) {
cons_show(" Type : PUBLIC, PRIVATE"); cons_show(" Type : PUBLIC, PRIVATE");
} else { } else {
cons_show(" Type : PUBLIC"); cons_show(" Type : PUBLIC");
} }
curr = g_list_next(curr);
} }
g_list_free(keylist);
p_gpg_free_keys(keys); p_gpg_free_keys(keys);
return TRUE; return TRUE;
} }
@@ -7491,8 +7488,8 @@ cmd_ox(ProfWin* window, const char* const command, gchar** args)
else if (g_strcmp0(args[0], "contacts") == 0) { else if (g_strcmp0(args[0], "contacts") == 0) {
GHashTable* keys = ox_gpg_public_keys(); GHashTable* keys = ox_gpg_public_keys();
cons_show("OpenPGP keys:"); cons_show("OpenPGP keys:");
GList* keylist = g_hash_table_get_keys(keys); GHashTableIter iter;
GList* curr = keylist; gpointer key, value;
GSList* roster_list = NULL; GSList* roster_list = NULL;
jabber_conn_status_t conn_status = connection_get_status(); jabber_conn_status_t conn_status = connection_get_status();
@@ -7502,15 +7499,16 @@ cmd_ox(ProfWin* window, const char* const command, gchar** args)
roster_list = roster_get_contacts(ROSTER_ORD_NAME); roster_list = roster_get_contacts(ROSTER_ORD_NAME);
} }
while (curr) { g_hash_table_iter_init(&iter, keys);
ProfPGPKey* key = g_hash_table_lookup(keys, curr->data); while (g_hash_table_iter_next(&iter, &key, &value)) {
ProfPGPKey* pgp_key = (ProfPGPKey*)value;
PContact contact = NULL; PContact contact = NULL;
if (roster_list) { if (roster_list) {
GSList* curr_c = roster_list; GSList* curr_c = roster_list;
while (!contact && curr_c) { while (!contact && curr_c) {
contact = curr_c->data; contact = curr_c->data;
auto_gchar gchar* xmppuri = g_strdup_printf("xmpp:%s", p_contact_barejid(contact)); auto_gchar gchar* xmppuri = g_strdup_printf("xmpp:%s", p_contact_barejid(contact));
if (g_strcmp0(key->name, xmppuri)) { if (g_strcmp0(pgp_key->name, xmppuri)) {
contact = NULL; contact = NULL;
} }
curr_c = g_slist_next(curr_c); curr_c = g_slist_next(curr_c);
@@ -7518,11 +7516,10 @@ cmd_ox(ProfWin* window, const char* const command, gchar** args)
} }
if (contact) { if (contact) {
cons_show("%s - %s", key->fp, key->name); cons_show("%s - %s", pgp_key->fp, pgp_key->name);
} else { } else {
cons_show("%s - %s (not in roster)", key->fp, key->name); cons_show("%s - %s (not in roster)", pgp_key->fp, pgp_key->name);
} }
curr = g_list_next(curr);
} }
} else if (g_strcmp0(args[0], "start") == 0) { } else if (g_strcmp0(args[0], "start") == 0) {
@@ -9612,7 +9609,7 @@ cmd_register(ProfWin* window, const char* const command, gchar** args)
auto_char char* err_msg = NULL; auto_char char* err_msg = NULL;
gboolean res = strtoi_range(port_str, &port, 1, 65535, &err_msg); gboolean res = strtoi_range(port_str, &port, 1, 65535, &err_msg);
if (!res) { if (!res) {
cons_show(err_msg); cons_show("%s", err_msg);
cons_show(""); cons_show("");
port = 0; port = 0;
options_destroy(options); options_destroy(options);
@@ -9682,7 +9679,7 @@ cmd_strophe(ProfWin* window, const char* const command, gchar** args)
prefs_set_string(PREF_STROPHE_VERBOSITY, args[1]); prefs_set_string(PREF_STROPHE_VERBOSITY, args[1]);
return TRUE; return TRUE;
} else { } else {
cons_show(err_msg); cons_show("%s", err_msg);
} }
} else if (g_strcmp0(args[0], "sm") == 0) { } else if (g_strcmp0(args[0], "sm") == 0) {
if (g_strcmp0(args[1], "no-resend") == 0) { if (g_strcmp0(args[1], "no-resend") == 0) {

View File

@@ -532,11 +532,13 @@ omemo_set_device_list(const char* const from, GList* device_list)
for (device_id = device_list; device_id != NULL; device_id = device_id->next) { for (device_id = device_list; device_id != NULL; device_id = device_id->next) {
GHashTable* known_identities = g_hash_table_lookup(omemo_ctx.known_devices, jid->barejid); GHashTable* known_identities = g_hash_table_lookup(omemo_ctx.known_devices, jid->barejid);
if (known_identities) { if (known_identities) {
GList* fp = NULL; GHashTableIter iter;
for (fp = g_hash_table_get_keys(known_identities); fp != NULL; fp = fp->next) { gpointer key, value;
if (device_id->data == g_hash_table_lookup(known_identities, fp->data)) { g_hash_table_iter_init(&iter, known_identities);
cons_show("OMEMO: Adding firstusage trust for %s device %d - Fingerprint %s", jid->barejid, device_id->data, omemo_format_fingerprint(fp->data)); while (g_hash_table_iter_next(&iter, &key, &value)) {
omemo_trust(jid->barejid, omemo_format_fingerprint(fp->data)); if (device_id->data == value) {
cons_show("OMEMO: Adding firstusage trust for %s device %d - Fingerprint %s", jid->barejid, device_id->data, omemo_format_fingerprint(key));
omemo_trust(jid->barejid, omemo_format_fingerprint(key));
} }
} }
} }

View File

@@ -345,14 +345,13 @@ p_gpg_list_keys(void)
// TODO: move autocomplete in other place // TODO: move autocomplete in other place
autocomplete_clear(key_ac); autocomplete_clear(key_ac);
GList* ids = g_hash_table_get_keys(result); GHashTableIter iter;
GList* curr = ids; gpointer key, value;
while (curr) { g_hash_table_iter_init(&iter, result);
ProfPGPKey* key = g_hash_table_lookup(result, curr->data); while (g_hash_table_iter_next(&iter, &key, &value)) {
autocomplete_add(key_ac, key->id); ProfPGPKey* pgp_key = (ProfPGPKey*)value;
curr = curr->next; autocomplete_add(key_ac, pgp_key->id);
} }
g_list_free(ids);
return result; return result;
} }

View File

@@ -141,18 +141,16 @@ autocompleters_complete(const char* const input, gboolean previous)
while (curr_hash) { while (curr_hash) {
GHashTable* key_to_ac = curr_hash->data; GHashTable* key_to_ac = curr_hash->data;
GList* keys = g_hash_table_get_keys(key_to_ac); GHashTableIter iter;
GList* curr = keys; gpointer key, value;
while (curr) { g_hash_table_iter_init(&iter, key_to_ac);
result = autocomplete_param_with_ac(input, curr->data, g_hash_table_lookup(key_to_ac, curr->data), TRUE, previous); while (g_hash_table_iter_next(&iter, &key, &value)) {
result = autocomplete_param_with_ac(input, key, value, TRUE, previous);
if (result) { if (result) {
g_list_free(ac_hashes); g_list_free(ac_hashes);
g_list_free(keys);
return result; return result;
} }
curr = g_list_next(curr);
} }
g_list_free(keys);
curr_hash = g_list_next(curr_hash); curr_hash = g_list_next(curr_hash);
} }
@@ -162,22 +160,19 @@ autocompleters_complete(const char* const input, gboolean previous)
curr_hash = filepath_hashes; curr_hash = filepath_hashes;
while (curr_hash) { while (curr_hash) {
GHashTable* prefixes_hash = curr_hash->data; GHashTable* prefixes_hash = curr_hash->data;
GList* prefixes = g_hash_table_get_keys(prefixes_hash); GHashTableIter iter;
GList* curr_prefix = prefixes; gpointer key, value;
while (curr_prefix) { g_hash_table_iter_init(&iter, prefixes_hash);
char* prefix = curr_prefix->data; while (g_hash_table_iter_next(&iter, &key, &value)) {
char* prefix = (char*)key;
if (g_str_has_prefix(input, prefix)) { if (g_str_has_prefix(input, prefix)) {
result = cmd_ac_complete_filepath(input, prefix, previous); result = cmd_ac_complete_filepath(input, prefix, previous);
if (result) { if (result) {
g_list_free(filepath_hashes); g_list_free(filepath_hashes);
g_list_free(prefixes);
return result; return result;
} }
} }
curr_prefix = g_list_next(curr_prefix);
} }
g_list_free(prefixes);
curr_hash = g_list_next(curr_hash); curr_hash = g_list_next(curr_hash);
} }

View File

@@ -149,15 +149,14 @@ callbacks_remove(const char* const plugin_name)
{ {
GHashTable* command_hash = g_hash_table_lookup(p_commands, plugin_name); GHashTable* command_hash = g_hash_table_lookup(p_commands, plugin_name);
if (command_hash) { if (command_hash) {
GList* commands = g_hash_table_get_keys(command_hash); GHashTableIter iter;
GList* curr = commands; gpointer key, value;
while (curr) { g_hash_table_iter_init(&iter, command_hash);
char* command = curr->data; while (g_hash_table_iter_next(&iter, &key, &value)) {
char* command = (char*)key;
cmd_ac_remove(command); cmd_ac_remove(command);
cmd_ac_remove_help(&command[1]); cmd_ac_remove_help(&command[1]);
curr = g_list_next(curr);
} }
g_list_free(commands);
} }
g_hash_table_remove(p_commands, plugin_name); g_hash_table_remove(p_commands, plugin_name);
@@ -165,13 +164,12 @@ callbacks_remove(const char* const plugin_name)
GHashTable* tag_to_win_cb_hash = g_hash_table_lookup(p_window_callbacks, plugin_name); GHashTable* tag_to_win_cb_hash = g_hash_table_lookup(p_window_callbacks, plugin_name);
if (tag_to_win_cb_hash) { if (tag_to_win_cb_hash) {
GList* tags = g_hash_table_get_keys(tag_to_win_cb_hash); GHashTableIter iter;
GList* curr = tags; gpointer key, value;
while (curr) { g_hash_table_iter_init(&iter, tag_to_win_cb_hash);
wins_close_plugin(curr->data); while (g_hash_table_iter_next(&iter, &key, &value)) {
curr = g_list_next(curr); wins_close_plugin(key);
} }
g_list_free(tags);
} }
g_hash_table_remove(p_window_callbacks, plugin_name); g_hash_table_remove(p_window_callbacks, plugin_name);

View File

@@ -107,10 +107,11 @@ disco_remove_features(const char* plugin_name)
return; return;
} }
GList* plugin_feature_list = g_hash_table_get_keys(plugin_features_set); GHashTableIter iter;
GList* curr = plugin_feature_list; gpointer key, value;
while (curr) { g_hash_table_iter_init(&iter, plugin_features_set);
char* feature = curr->data; while (g_hash_table_iter_next(&iter, &key, &value)) {
char* feature = (char*)key;
if (g_hash_table_contains(features, feature)) { if (g_hash_table_contains(features, feature)) {
void* refcountp = g_hash_table_lookup(features, feature); void* refcountp = g_hash_table_lookup(features, feature);
int refcount = GPOINTER_TO_INT(refcountp); int refcount = GPOINTER_TO_INT(refcountp);
@@ -121,10 +122,7 @@ disco_remove_features(const char* plugin_name)
g_hash_table_replace(features, strdup(feature), GINT_TO_POINTER(refcount)); g_hash_table_replace(features, strdup(feature), GINT_TO_POINTER(refcount));
} }
} }
curr = g_list_next(curr);
} }
g_list_free(plugin_feature_list);
} }
GList* GList*

View File

@@ -152,7 +152,7 @@ cons_bad_cmd_usage(const char* const cmd)
g_string_printf(msg, "Invalid usage, see '/help %s' for details.", &cmd[1]); g_string_printf(msg, "Invalid usage, see '/help %s' for details.", &cmd[1]);
cons_show(""); cons_show("");
cons_show(msg->str); cons_show("%s", msg->str);
g_string_free(msg, TRUE); g_string_free(msg, TRUE);
} }
@@ -773,7 +773,7 @@ cons_show_disco_info(const char* jid, GSList* identities, GSList* features)
if (identity->category) { if (identity->category) {
identity_str = g_string_append(identity_str, identity->category); identity_str = g_string_append(identity_str, identity->category);
} }
cons_show(identity_str->str); cons_show("%s", identity_str->str);
g_string_free(identity_str, TRUE); g_string_free(identity_str, TRUE);
identities = g_slist_next(identities); identities = g_slist_next(identities);
} }
@@ -1019,7 +1019,7 @@ cons_show_account(ProfAccount* account)
} }
curr = curr->next; curr = curr->next;
} }
cons_show(manual->str); cons_show("%s", manual->str);
g_string_free(manual, TRUE); g_string_free(manual, TRUE);
} }
if (g_list_length(account->otr_opportunistic) > 0) { if (g_list_length(account->otr_opportunistic) > 0) {
@@ -1032,7 +1032,7 @@ cons_show_account(ProfAccount* account)
} }
curr = curr->next; curr = curr->next;
} }
cons_show(opportunistic->str); cons_show("%s", opportunistic->str);
g_string_free(opportunistic, TRUE); g_string_free(opportunistic, TRUE);
} }
if (g_list_length(account->otr_always) > 0) { if (g_list_length(account->otr_always) > 0) {
@@ -1045,7 +1045,7 @@ cons_show_account(ProfAccount* account)
} }
curr = curr->next; curr = curr->next;
} }
cons_show(always->str); cons_show("%s", always->str);
g_string_free(always, TRUE); g_string_free(always, TRUE);
} }
@@ -2297,7 +2297,7 @@ cons_show_themes(GSList* themes)
} else { } else {
cons_show("Available themes:"); cons_show("Available themes:");
while (themes) { while (themes) {
cons_show(themes->data); cons_show("%s", themes->data);
themes = g_slist_next(themes); themes = g_slist_next(themes);
} }
} }
@@ -2315,7 +2315,7 @@ cons_show_scripts(GSList* scripts)
} else { } else {
cons_show("Scripts:"); cons_show("Scripts:");
while (scripts) { while (scripts) {
cons_show(scripts->data); cons_show("%s", scripts->data);
scripts = g_slist_next(scripts); scripts = g_slist_next(scripts);
} }
} }

View File

@@ -461,7 +461,7 @@ ui_invalid_command_usage(const char* const cmd, void (*setting_func)(void))
(*setting_func)(); (*setting_func)();
} else { } else {
cons_show(""); cons_show("");
cons_show(msg->str); cons_show("%s", msg->str);
ProfWin* current = wins_get_current(); ProfWin* current = wins_get_current();
if (current->type == WIN_CHAT) { if (current->type == WIN_CHAT) {
win_println(current, THEME_DEFAULT, "-", "%s", msg->str); win_println(current, THEME_DEFAULT, "-", "%s", msg->str);

View File

@@ -171,16 +171,15 @@ caps_get_features(void)
{ {
GList* result = NULL; GList* result = NULL;
GList* features_as_list = g_hash_table_get_keys(prof_features); GHashTableIter iter;
GList* curr = features_as_list; gpointer key, value;
while (curr) { g_hash_table_iter_init(&iter, prof_features);
result = g_list_append(result, strdup(curr->data)); while (g_hash_table_iter_next(&iter, &key, &value)) {
curr = g_list_next(curr); result = g_list_append(result, strdup((char*)key));
} }
g_list_free(features_as_list);
GList* plugin_features = plugins_get_disco_features(); GList* plugin_features = plugins_get_disco_features();
curr = plugin_features; GList* curr = plugin_features;
while (curr) { while (curr) {
result = g_list_append(result, strdup(curr->data)); result = g_list_append(result, strdup(curr->data));
curr = g_list_next(curr); curr = g_list_next(curr);

View File

@@ -148,7 +148,7 @@ connection_init(void)
if (string_to_verbosity(v, &verbosity, &err_msg)) { if (string_to_verbosity(v, &verbosity, &err_msg)) {
xmpp_ctx_set_verbosity(conn.xmpp_ctx, verbosity); xmpp_ctx_set_verbosity(conn.xmpp_ctx, verbosity);
} else { } else {
cons_show(err_msg); cons_show("%s", err_msg);
} }
conn.xmpp_conn = xmpp_conn_new(conn.xmpp_ctx); conn.xmpp_conn = xmpp_conn_new(conn.xmpp_ctx);
@@ -638,22 +638,18 @@ gboolean
connection_supports(const char* const feature) connection_supports(const char* const feature)
{ {
gboolean ret = FALSE; gboolean ret = FALSE;
GList* jids = g_hash_table_get_keys(conn.features_by_jid); GHashTableIter iter;
gpointer key, value;
GList* curr = jids; g_hash_table_iter_init(&iter, conn.features_by_jid);
while (curr) { while (g_hash_table_iter_next(&iter, &key, &value)) {
char* jid = curr->data; GHashTable* features = (GHashTable*)value;
GHashTable* features = g_hash_table_lookup(conn.features_by_jid, jid);
if (features && g_hash_table_lookup(features, feature)) { if (features && g_hash_table_lookup(features, feature)) {
ret = TRUE; ret = TRUE;
break; break;
} }
curr = g_list_next(curr);
} }
g_list_free(jids);
return ret; return ret;
} }
@@ -664,22 +660,17 @@ connection_jid_for_feature(const char* const feature)
return NULL; return NULL;
} }
GList* jids = g_hash_table_get_keys(conn.features_by_jid); GHashTableIter iter;
gpointer key, value;
GList* curr = jids; g_hash_table_iter_init(&iter, conn.features_by_jid);
while (curr) { while (g_hash_table_iter_next(&iter, &key, &value)) {
char* jid = curr->data; GHashTable* features = (GHashTable*)value;
GHashTable* features = g_hash_table_lookup(conn.features_by_jid, jid);
if (features && g_hash_table_lookup(features, feature)) { if (features && g_hash_table_lookup(features, feature)) {
g_list_free(jids); return (const char*)key;
return jid;
} }
curr = g_list_next(curr);
} }
g_list_free(jids);
return NULL; return NULL;
} }
@@ -1034,7 +1025,7 @@ _connection_handler(xmpp_conn_t* const xmpp_conn, const xmpp_conn_event_t status
conn.sm_state = xmpp_conn_get_sm_state(conn.xmpp_conn); conn.sm_state = xmpp_conn_get_sm_state(conn.xmpp_conn);
if (send_queue_len > 0 && prefs_get_boolean(PREF_STROPHE_SM_RESEND)) { if (send_queue_len > 0 && prefs_get_boolean(PREF_STROPHE_SM_RESEND)) {
conn.queued_messages = calloc(send_queue_len + 1, sizeof(*conn.queued_messages)); conn.queued_messages = calloc(send_queue_len + 1, sizeof(*conn.queued_messages));
for (int n = 0; n < send_queue_len && conn.queued_messages[n]; ++n) { for (int n = 0; n < send_queue_len; ++n) {
conn.queued_messages[n] = xmpp_conn_send_queue_drop_element(conn.xmpp_conn, XMPP_QUEUE_OLDEST); conn.queued_messages[n] = xmpp_conn_send_queue_drop_element(conn.xmpp_conn, XMPP_QUEUE_OLDEST);
} }
} else if (send_queue_len > 0) { } else if (send_queue_len > 0) {
@@ -1189,12 +1180,13 @@ connection_debug_print_features()
continue; continue;
} }
GList* feature_keys = g_hash_table_get_keys(features); GHashTableIter feature_iter;
for (GList* l = feature_keys; l != NULL; l = l->next) { gpointer feature_key, feature_value;
const char* feature = (const char*)l->data; g_hash_table_iter_init(&feature_iter, features);
while (g_hash_table_iter_next(&feature_iter, &feature_key, &feature_value)) {
const char* feature = (const char*)feature_key;
log_debug("%s:\t%s", jid, feature); log_debug("%s:\t%s", jid, feature);
} }
g_list_free(feature_keys);
} }
log_debug("=== End of Features ==="); log_debug("=== End of Features ===");

View File

@@ -437,18 +437,7 @@ form_get_form_type_field(DataForm* form)
gboolean gboolean
form_tag_exists(DataForm* form, const char* const tag) form_tag_exists(DataForm* form, const char* const tag)
{ {
GList* tags = g_hash_table_get_keys(form->tag_to_var); return g_hash_table_contains(form->tag_to_var, tag);
GList* curr = tags;
while (curr) {
if (g_strcmp0(curr->data, tag) == 0) {
g_list_free(tags);
return TRUE;
}
curr = g_list_next(curr);
}
g_list_free(tags);
return FALSE;
} }
form_field_type_t form_field_type_t

View File

@@ -326,7 +326,7 @@ _ox_metadata_result(xmpp_stanza_t* const stanza, void* const userdata)
if (fingerprint) { if (fingerprint) {
if (strlen(fingerprint) == KEYID_LENGTH) { if (strlen(fingerprint) == KEYID_LENGTH) {
cons_show(fingerprint); cons_show("%s", fingerprint);
} else { } else {
cons_show("OX: Wrong char size of public key"); cons_show("OX: Wrong char size of public key");
log_error("[OX] Wrong chat size of public key %s", fingerprint); log_error("[OX] Wrong chat size of public key %s", fingerprint);