Harden compiler flags, simplify CWE-134 script, fix bugs found by new warnings

configure.ac:
- Replace basic -Wformat/-Wformat-nonliteral with -Wformat=2
- Add -Wextra, -Wnull-dereference, -Wpointer-arith, -Wimplicit-function-declaration
- Add -fstack-protector-strong, -fno-common, -D_FORTIFY_SOURCE=2
- Add GCC-specific flags via AC_COMPILE_IFELSE: -Wlogical-op, -Wduplicated-cond,
  -Wduplicated-branches, -Wstringop-overflow
- Add linker hardening via AC_LINK_IFELSE: -Wl,-z,relro -Wl,-z,now
- Suppress noisy -Wextra sub-warnings: -Wno-unused-parameter,
  -Wno-missing-field-initializers, -Wno-sign-compare, -Wno-cast-function-type
- Remove AM_CFLAGS/CFLAGS duplication line

check-cwe134.sh:
- Reduce from 5 checks to 2 (checks 1-3 are now redundant with -Wformat=2)
- Check 1: verify known wrappers have G_GNUC_PRINTF attribute
- Check 2: auto-detect unannotated variadic printf-like functions

Bug fixes found by -Wduplicated-branches:
- chatlog.c: non-MUCPM redact path passed resourcepart instead of NULL
- rosterwin.c: two instances of if/else with identical branches in roster count
- omemo.c: redundant else-if branch in omemo_automatic_start

Other fixes for new warnings:
- console.c: pointer compared to integer 0 instead of NULL (2 instances)
- vcard.c: NULL guard for filename before g_file_set_contents
- files.c: refactor to early return, eliminating NULL logfile path
- database.c: const-correctness for type, query, sort variables
- form.c/xmpp.h: const-correctness for form_set_value parameter
- muc.c/muc.h: remove meaningless top-level const on return type
- common.c: const-correctness for URL string literal
- xmpp/omemo.c: scope block for declarations after goto, move from decl
  before goto, replace goto with direct return
- http_common.h: add G_GNUC_PRINTF attributes for http_print_transfer*
- test_common.c: add currb NULL check to silence -Wnull-dereference
This commit is contained in:
2026-03-04 21:18:35 +03:00
parent 92953099e1
commit bb6d29a060
17 changed files with 156 additions and 240 deletions

View File

@@ -204,7 +204,7 @@ chat_log_omemo_msg_in(ProfMessage* message)
if (message->type == PROF_MSG_TYPE_MUCPM) {
_chat_log_chat(mybarejid, message->from_jid->barejid, "[redacted]", PROF_IN_LOG, message->timestamp, message->from_jid->resourcepart);
} else {
_chat_log_chat(mybarejid, message->from_jid->barejid, "[redacted]", PROF_IN_LOG, message->timestamp, message->from_jid->resourcepart);
_chat_log_chat(mybarejid, message->from_jid->barejid, "[redacted]", PROF_IN_LOG, message->timestamp, NULL);
}
}
}

View File

@@ -383,7 +383,7 @@ utf8_display_len(const char* const str)
char*
release_get_latest(void)
{
char* url = "https://profanity-im.github.io/profanity_version.txt";
const char* url = "https://profanity-im.github.io/profanity_version.txt";
CURL* handle = curl_easy_init();
struct curl_data_t output;

View File

@@ -114,30 +114,26 @@ gchar*
files_get_log_file(const char* const log_file)
{
auto_gchar gchar* xdg_data = _files_get_xdg_data_home();
GString* logfile;
if (log_file) {
auto_gchar gchar* log_path = g_path_get_dirname(log_file);
if (!create_dir(log_path)) {
log_error("Error while creating directory %s", log_path);
}
logfile = g_string_new(log_file);
} else {
logfile = g_string_new(xdg_data);
g_string_append(logfile, "/profanity/logs/profanity");
if (!prefs_get_boolean(PREF_LOG_SHARED)) {
g_string_append_printf(logfile, "%d", getpid());
}
g_string_append(logfile, ".log");
return g_strdup(log_file);
}
GString* logfile = g_string_new(xdg_data);
g_string_append(logfile, "/profanity/logs/profanity");
if (!prefs_get_boolean(PREF_LOG_SHARED)) {
g_string_append_printf(logfile, "%d", getpid());
}
g_string_append(logfile, ".log");
gchar* result = g_strdup(logfile->str);
g_string_free(logfile, TRUE);
return result;
}

View File

@@ -55,7 +55,7 @@
static sqlite3* g_chatlog_database;
static void _add_to_db(ProfMessage* message, char* type, const Jid* const from_jid, const Jid* const to_jid);
static void _add_to_db(ProfMessage* message, const char* type, const Jid* const from_jid, const Jid* const to_jid);
static char* _get_db_filename(ProfAccount* account);
static prof_msg_type_t _get_message_type_type(const char* const type);
static prof_enc_t _get_message_enc_type(const char* const encstr);
@@ -167,7 +167,7 @@ log_database_init(ProfAccount* account)
// replace_id is the ID from XEP-0308: Last Message Correction
// replaces_db_id is ID (primary key) of the original message that LMC message corrects/replaces
// replaced_by_db_id is ID (primary key) of the last correcting (LMC) message for the original message
char* query = "CREATE TABLE IF NOT EXISTS `ChatLogs` ("
const char* query = "CREATE TABLE IF NOT EXISTS `ChatLogs` ("
"`id` INTEGER PRIMARY KEY AUTOINCREMENT, "
"`from_jid` TEXT NOT NULL, "
"`to_jid` TEXT NOT NULL, "
@@ -272,7 +272,7 @@ log_database_add_incoming(ProfMessage* message)
}
static void
_log_database_add_outgoing(char* type, const char* const id, const char* const barejid, const char* const message, const char* const replace_id, prof_enc_t enc)
_log_database_add_outgoing(const char* type, const char* const id, const char* const barejid, const char* const message, const char* const replace_id, prof_enc_t enc)
{
ProfMessage* msg = message_init();
@@ -379,8 +379,8 @@ log_database_get_previous_chat(const gchar* const contact_barejid, const gchar*
}
// Flip order when querying older pages
gchar* sort1 = from_start ? "ASC" : "DESC";
gchar* sort2 = !flip ? "ASC" : "DESC";
const gchar* sort1 = from_start ? "ASC" : "DESC";
const gchar* sort2 = !flip ? "ASC" : "DESC";
GDateTime* now = g_date_time_new_now_local();
auto_gchar gchar* end_date_fmt = end_time ? g_strdup(end_time) : g_date_time_format_iso8601(now);
auto_sqlite gchar* query = sqlite3_mprintf("SELECT * FROM ("
@@ -499,7 +499,7 @@ _get_message_enc_type(const char* const encstr)
}
static void
_add_to_db(ProfMessage* message, char* type, const Jid* const from_jid, const Jid* const to_jid)
_add_to_db(ProfMessage* message, const char* type, const Jid* const from_jid, const Jid* const to_jid)
{
auto_gchar gchar* pref_dblog = prefs_get_string(PREF_DBLOG);
sqlite_int64 original_message_id = -1;

View File

@@ -1406,8 +1406,6 @@ omemo_automatic_start(const char* const recipient)
case PROF_OMEMOPOLICY_AUTOMATIC:
if (g_list_find_custom(account->omemo_enabled, recipient, (GCompareFunc)g_strcmp0)) {
result = TRUE;
} else if (g_list_find_custom(account->omemo_disabled, recipient, (GCompareFunc)g_strcmp0)) {
result = FALSE;
} else {
result = FALSE;
}

View File

@@ -36,9 +36,12 @@
#ifndef TOOLS_HTTP_COMMON_H
#define TOOLS_HTTP_COMMON_H
#include <glib.h>
#include "ui/window.h"
G_GNUC_PRINTF(3, 4)
void http_print_transfer(ProfWin* window, char* id, const char* fmt, ...);
G_GNUC_PRINTF(3, 4)
void http_print_transfer_update(ProfWin* window, char* id, const char* fmt, ...);
#endif

View File

@@ -470,7 +470,7 @@ cons_show_wins(gboolean unread)
GSList* curr = window_strings;
while (curr) {
if (g_strstr_len((char*)curr->data, strlen((char*)curr->data), " unread") > 0) {
if (g_strstr_len((char*)curr->data, strlen((char*)curr->data), " unread") != NULL) {
win_println(console, THEME_CMD_WINS_UNREAD, "-", "%s", (char*)curr->data);
} else {
win_println(console, THEME_DEFAULT, "-", "%s", (char*)curr->data);
@@ -491,7 +491,7 @@ cons_show_wins_attention()
GSList* curr = window_strings;
while (curr) {
if (g_strstr_len((char*)curr->data, strlen((char*)curr->data), " unread") > 0) {
if (g_strstr_len((char*)curr->data, strlen((char*)curr->data), " unread") != NULL) {
win_println(console, THEME_CMD_WINS_UNREAD, "-", "%s", (char*)curr->data);
} else {
win_println(console, THEME_DEFAULT, "-", "%s", (char*)curr->data);

View File

@@ -983,7 +983,7 @@ _rosterwin_unsubscribed_header(ProfLayoutSplit* layout, GList* wins)
int itemcount = g_list_length(wins);
if (itemcount == 0 && prefs_get_boolean(PREF_ROSTER_COUNT_ZERO)) {
g_string_append_printf(header, " (%d)", itemcount);
} else {
} else if (itemcount > 0) {
g_string_append_printf(header, " (%d)", itemcount);
}
} else if (g_strcmp0(countpref, "unread") == 0) {
@@ -1028,7 +1028,7 @@ _rosterwin_contacts_header(ProfLayoutSplit* layout, const char* const title, GSL
int itemcount = g_slist_length(contacts);
if (itemcount == 0 && prefs_get_boolean(PREF_ROSTER_COUNT_ZERO)) {
g_string_append_printf(header, " (%d)", itemcount);
} else {
} else if (itemcount > 0) {
g_string_append_printf(header, " (%d)", itemcount);
}
} else if (g_strcmp0(countpref, "unread") == 0) {

View File

@@ -458,7 +458,7 @@ form_get_field_type(DataForm* form, const char* const tag)
}
void
form_set_value(DataForm* form, const char* const tag, char* value)
form_set_value(DataForm* form, const char* const tag, const char* value)
{
char* var = g_hash_table_lookup(form->tag_to_var, tag);
if (var) {

View File

@@ -427,7 +427,7 @@ muc_rooms(void)
* Return current users nickname for the specified room
* The nickname is owned by the chat room and should not be modified or freed
*/
const char* const
const char*
muc_nick(const char* const room)
{
ChatRoom* chat_room = g_hash_table_lookup(rooms, room);

View File

@@ -93,7 +93,7 @@ GList* muc_rooms(void);
void muc_set_features(const char* const room, GSList* features);
const char* const muc_nick(const char* const room);
const char* muc_nick(const char* const room);
char* muc_password(const char* const room);
void muc_nick_change_start(const char* const room, const char* const new_nick);

View File

@@ -353,6 +353,7 @@ omemo_receive_message(xmpp_stanza_t* const stanza, gboolean* trusted)
{
char* plaintext = NULL;
const char* type = xmpp_stanza_get_type(stanza);
const char* from = xmpp_stanza_get_from(stanza);
GList* keys = NULL;
unsigned char* iv_raw = NULL;
unsigned char* payload_raw = NULL;
@@ -434,8 +435,6 @@ omemo_receive_message(xmpp_stanza_t* const stanza, gboolean* trusted)
keys = g_list_append(keys, key);
}
const char* from = xmpp_stanza_get_from(stanza);
plaintext = omemo_on_message_recv(from, sid, iv_raw, iv_len,
keys, payload_raw, payload_len,
g_strcmp0(type, STANZA_TYPE_GROUPCHAT) == 0, trusted);
@@ -471,7 +470,8 @@ _omemo_receive_devicelist(xmpp_stanza_t* const stanza, void* const userdata)
const char* code = xmpp_stanza_get_attribute(error, "code");
if (g_strcmp0(code, "404") == 0) {
goto out;
omemo_set_device_list(from, NULL);
return 1;
}
}
@@ -520,22 +520,25 @@ _omemo_receive_devicelist(xmpp_stanza_t* const stanza, void* const userdata)
goto out;
}
xmpp_stanza_t* list = xmpp_stanza_get_child_by_ns(item, STANZA_NS_OMEMO);
if (!list) {
return 1;
}
xmpp_stanza_t* device;
for (device = xmpp_stanza_get_children(list); device != NULL; device = xmpp_stanza_get_next(device)) {
if (g_strcmp0(xmpp_stanza_get_name(device), "device") != 0) {
continue;
/* New scope to keep declarations after goto out above */
{
xmpp_stanza_t* list = xmpp_stanza_get_child_by_ns(item, STANZA_NS_OMEMO);
if (!list) {
return 1;
}
const char* id = xmpp_stanza_get_id(device);
if (id != NULL) {
device_list = g_list_append(device_list, GINT_TO_POINTER(strtoul(id, NULL, 10)));
} else {
log_error("[OMEMO] received device without ID");
xmpp_stanza_t* device;
for (device = xmpp_stanza_get_children(list); device != NULL; device = xmpp_stanza_get_next(device)) {
if (g_strcmp0(xmpp_stanza_get_name(device), "device") != 0) {
continue;
}
const char* id = xmpp_stanza_get_id(device);
if (id != NULL) {
device_list = g_list_append(device_list, GINT_TO_POINTER(strtoul(id, NULL, 10)));
} else {
log_error("[OMEMO] received device without ID");
}
}
}

View File

@@ -1300,7 +1300,7 @@ _vcard_photo_result(xmpp_stanza_t* const stanza, void* userdata)
return 1;
}
GString* filename;
GString* filename = NULL;
if (!data->filename) {
auto_gchar gchar* path = files_get_data_path(DIR_PHOTOS);
@@ -1340,6 +1340,11 @@ _vcard_photo_result(xmpp_stanza_t* const stanza, void* userdata)
GError* err = NULL;
if (!filename) {
cons_show_error("Unable to determine filename for photo");
return 1;
}
if (g_file_set_contents(filename->str, (gchar*)photo->data, photo->length, &err) == FALSE) {
cons_show_error("Unable to save photo: %s", err->message);
g_error_free(err);

View File

@@ -305,7 +305,7 @@ char* blocked_ac_find(const char* const search_str, gboolean previous, void* con
void blocked_ac_reset(void);
void form_destroy(DataForm* form);
void form_set_value(DataForm* form, const char* const tag, char* value);
void form_set_value(DataForm* form, const char* const tag, const char* value);
gboolean form_add_unique_value(DataForm* form, const char* const tag, char* value);
void form_add_value(DataForm* form, const char* const tag, char* value);
gboolean form_remove_value(DataForm* form, const char* const tag, char* value);