From f7c6f38e1b44b05b24d81145a804462931e2b3f0 Mon Sep 17 00:00:00 2001 From: Steffen Jaeckel Date: Thu, 11 May 2023 10:37:20 +0200 Subject: [PATCH 1/6] Consider global CFLAGS and use libstrophe CFLAGS global `CFLAGS` were ignore before Signed-off-by: Steffen Jaeckel --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 0d200286..f01b88fd 100644 --- a/configure.ac +++ b/configure.ac @@ -371,7 +371,6 @@ AC_CHECK_LIB([expect], [exp_expectl], [AM_CONDITIONAL([HAVE_EXPECT], [true])], [AC_MSG_NOTICE([libexpect not found, will not be able to run functional tests])]) ## Default parameters -AM_CFLAGS="$AM_CFLAGS -Wall -Wno-deprecated-declarations -std=gnu99" AM_CFLAGS="$AM_CFLAGS -Wall -Wno-deprecated-declarations -std=gnu99 -ggdb3" AM_LDFLAGS="$AM_LDFLAGS -export-dynamic" @@ -380,9 +379,10 @@ AS_IF([test "x$PACKAGE_STATUS" = xdevelopment], AS_IF([test "x$PLATFORM" = xosx], [AM_CFLAGS="$AM_CFLAGS -Qunused-arguments"]) -AM_CFLAGS="$AM_CFLAGS $PTHREAD_CFLAGS $glib_CFLAGS $gio_CFLAGS $curl_CFLAGS ${SQLITE_CFLAGS} $libstrophe_CFLAGS" +AM_CFLAGS="$AM_CFLAGS $PTHREAD_CFLAGS $glib_CFLAGS $gio_CFLAGS $curl_CFLAGS ${SQLITE_CFLAGS}" AM_CFLAGS="$AM_CFLAGS $libnotify_CFLAGS ${GTK_CFLAGS} $python_CFLAGS" AM_CFLAGS="$AM_CFLAGS -DTHEMES_PATH=\"\\\"$THEMES_PATH\\\"\" -DICONS_PATH=\"\\\"$ICONS_PATH\\\"\" -DGLOBAL_PYTHON_PLUGINS_PATH=\"\\\"$GLOBAL_PYTHON_PLUGINS_PATH\\\"\" -DGLOBAL_C_PLUGINS_PATH=\"\\\"$GLOBAL_C_PLUGINS_PATH\\\"\"" +AM_CFLAGS="$AM_CFLAGS $CFLAGS" LIBS="$glib_LIBS $gio_LIBS $PTHREAD_LIBS $curl_LIBS $libnotify_LIBS $python_LIBS ${GTK_LIBS} ${SQLITE_LIBS} $LIBS" AC_SUBST(AM_LDFLAGS) From 860dd22bc5d91ced4b19f39e137e06a9324b9ff1 Mon Sep 17 00:00:00 2001 From: Steffen Jaeckel Date: Thu, 11 May 2023 10:48:08 +0200 Subject: [PATCH 2/6] Fix potential double-free introduced in 8d3c1f79ac7cc2b0830f0afed48dc1fb9008ab0e Signed-off-by: Steffen Jaeckel --- src/xmpp/iq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xmpp/iq.c b/src/xmpp/iq.c index 4f6eea40..eb72178d 100644 --- a/src/xmpp/iq.c +++ b/src/xmpp/iq.c @@ -2761,7 +2761,7 @@ _mam_rsm_id_handler(xmpp_stanza_t* const stanza, void* const userdata) // Convert to iso8601 start_str[strlen(start_str) - 3] = '\0'; } - auto_char char* end_str = NULL; + char* end_str = NULL; if (data->end_datestr) { end_str = strdup(data->end_datestr); // Convert to iso8601 From 76a8de891ea7800b62985b208c0ec2c4606d90c9 Mon Sep 17 00:00:00 2001 From: Steffen Jaeckel Date: Thu, 11 May 2023 10:52:54 +0200 Subject: [PATCH 3/6] Improve const-correctness of API Signed-off-by: Steffen Jaeckel --- src/database.c | 2 +- src/database.h | 2 +- src/ui/chatwin.c | 2 +- src/ui/ui.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/database.c b/src/database.c index ce936170..80439b9a 100644 --- a/src/database.c +++ b/src/database.c @@ -250,7 +250,7 @@ log_database_get_limits_info(const gchar* const contact_barejid, gboolean is_las // null the current time is used. from_start gets first few messages if true // otherwise the last ones. Flip flips the order of the results GSList* -log_database_get_previous_chat(const gchar* const contact_barejid, char* start_time, char* end_time, gboolean from_start, gboolean flip) +log_database_get_previous_chat(const gchar* const contact_barejid, const char* start_time, char* end_time, gboolean from_start, gboolean flip) { sqlite3_stmt* stmt = NULL; const char* jid = connection_get_fulljid(); diff --git a/src/database.h b/src/database.h index 3b5fd647..1e73c874 100644 --- a/src/database.h +++ b/src/database.h @@ -47,7 +47,7 @@ void log_database_add_incoming(ProfMessage* message); void log_database_add_outgoing_chat(const char* const id, const char* const barejid, const char* const message, const char* const replace_id, prof_enc_t enc); void log_database_add_outgoing_muc(const char* const id, const char* const barejid, const char* const message, const char* const replace_id, prof_enc_t enc); void log_database_add_outgoing_muc_pm(const char* const id, const char* const barejid, const char* const message, const char* const replace_id, prof_enc_t enc); -GSList* log_database_get_previous_chat(const gchar* const contact_barejid, char* start_time, char* end_time, gboolean from_start, gboolean flip); +GSList* log_database_get_previous_chat(const gchar* const contact_barejid, const char* start_time, char* end_time, gboolean from_start, gboolean flip); ProfMessage* log_database_get_limits_info(const gchar* const contact_barejid, gboolean is_last); void log_database_close(void); diff --git a/src/ui/chatwin.c b/src/ui/chatwin.c index 0c540998..b470dbd6 100644 --- a/src/ui/chatwin.c +++ b/src/ui/chatwin.c @@ -598,7 +598,7 @@ _chatwin_history(ProfChatWin* chatwin, const char* const contact_barejid) // first entry's timestamp in the buffer is used. Flip true to prepend to buffer. // Timestamps should be in iso8601 gboolean -chatwin_db_history(ProfChatWin* chatwin, char* start_time, char* end_time, gboolean flip) +chatwin_db_history(ProfChatWin* chatwin, const char* start_time, char* end_time, gboolean flip) { if (!end_time) { end_time = buffer_size(((ProfWin*)chatwin)->layout->buffer) == 0 ? NULL : g_date_time_format_iso8601(buffer_get_entry(((ProfWin*)chatwin)->layout->buffer, 0)->time); diff --git a/src/ui/ui.h b/src/ui/ui.h index d9534ed5..79fafd75 100644 --- a/src/ui/ui.h +++ b/src/ui/ui.h @@ -145,7 +145,7 @@ void chatwin_set_incoming_char(ProfChatWin* chatwin, const char* const ch); void chatwin_unset_incoming_char(ProfChatWin* chatwin); void chatwin_set_outgoing_char(ProfChatWin* chatwin, const char* const ch); void chatwin_unset_outgoing_char(ProfChatWin* chatwin); -gboolean chatwin_db_history(ProfChatWin* chatwin, char* start_time, char* end_time, gboolean flip); +gboolean chatwin_db_history(ProfChatWin* chatwin, const char* start_time, char* end_time, gboolean flip); // MUC window ProfMucWin* mucwin_new(const char* const barejid); From 12d76e4a214c392e6e3daa5fd9bcf816addf8746 Mon Sep 17 00:00:00 2001 From: Steffen Jaeckel Date: Thu, 11 May 2023 11:11:44 +0200 Subject: [PATCH 4/6] Fix memleaks & more auto-free `data_dir` would have been leaked if directory creation failed. `editor_argv` was leaked at some point, no idea why. ``` ==1244734== 118 (32 direct, 86 indirect) bytes in 1 blocks are definitely lost in loss record 6,299 of 7,824 ==1244734== at 0x4846CC3: realloc (vg_replace_malloc.c:1451) ==1244734== by 0x5E85AD0: g_realloc (in /usr/lib/libglib-2.0.so.0.7600.1) ==1244734== by 0x5E4A004: ??? (in /usr/lib/libglib-2.0.so.0.7600.1) ==1244734== by 0x5E4A7B1: g_ptr_array_add (in /usr/lib/libglib-2.0.so.0.7600.1) ==1244734== by 0x5EA4235: g_strsplit (in /usr/lib/libglib-2.0.so.0.7600.1) ==1244734== by 0x1F143C: get_message_from_editor (editor.c:92) ==1244734== by 0x193F6B: _inp_rl_send_to_editor (inputwin.c:950) ==1244734== by 0x614642F: _rl_dispatch_subseq (readline.c:916) ==1244734== by 0x6146C85: _rl_dispatch_callback (readline.c:823) ==1244734== by 0x616739F: rl_callback_read_char (callback.c:241) ==1244734== by 0x1923DB: inp_readline (inputwin.c:188) ==1244734== by 0x149860: prof_run (profanity.c:117) ==1244734== by 0x2283E8: main (main.c:186) ``` Signed-off-by: Steffen Jaeckel --- src/tools/editor.c | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/src/tools/editor.c b/src/tools/editor.c index 0efb4d6b..4cd70d9d 100644 --- a/src/tools/editor.c +++ b/src/tools/editor.c @@ -54,19 +54,18 @@ get_message_from_editor(gchar* message, gchar** returned_message) /* Make sure that there's no junk in the return-pointer in error cases */ *returned_message = NULL; - gchar* filename = NULL; + auto_gchar gchar* filename = NULL; GError* glib_error = NULL; auto_char char* jid = connection_get_barejid(); if (jid) { filename = files_file_in_account_data_path(DIR_EDITOR, jid, "compose.md"); } else { log_debug("[Editor] could not get JID"); - gchar* data_dir = files_get_data_path(DIR_EDITOR); + auto_gchar gchar* data_dir = files_get_data_path(DIR_EDITOR); if (!create_dir(data_dir)) { return TRUE; } filename = g_strdup_printf("%s/compose.md", data_dir); - g_free(data_dir); } if (!filename) { log_error("[Editor] something went wrong while creating compose file"); @@ -83,21 +82,17 @@ get_message_from_editor(gchar* message, gchar** returned_message) if (glib_error) { g_error_free(glib_error); } - g_free(filename); return TRUE; } - char* editor = prefs_get_string(PREF_COMPOSE_EDITOR); - gchar* editor_with_filename = g_strdup_printf("%s %s", editor, filename); - gchar** editor_argv = g_strsplit(editor_with_filename, " ", 0); - - g_free(editor_with_filename); + auto_gchar gchar* editor = prefs_get_string(PREF_COMPOSE_EDITOR); + auto_gchar gchar* editor_with_filename = g_strdup_printf("%s %s", editor, filename); + auto_gcharv gchar** editor_argv = g_strsplit(editor_with_filename, " ", 0); // Fork / exec pid_t pid = fork(); if (pid == 0) { int x = execvp(editor_argv[0], editor_argv); - g_strfreev(editor_argv); if (x == -1) { log_error("[Editor] Failed to exec %s", editor); } @@ -115,8 +110,6 @@ get_message_from_editor(gchar* message, gchar** returned_message) if (glib_error) { g_error_free(glib_error); } - g_free(filename); - g_free(editor); return TRUE; } /* Remove all trailing new-line characters */ @@ -127,10 +120,7 @@ get_message_from_editor(gchar* message, gchar** returned_message) } else { log_debug("[Editor] deleted file: %s", filename); } - g_free(filename); } - g_free(editor); - return FALSE; } From 197b839944c139672e2aa1e9e83632630138f6a7 Mon Sep 17 00:00:00 2001 From: Steffen Jaeckel Date: Thu, 11 May 2023 11:20:52 +0200 Subject: [PATCH 5/6] Remove VLA & calm Valgrind `MB_CUR_MAX` looks like a macro, but it's a function call and therefore creates a VLA. We don't want that. Also this array being uninitialized created the following Valgrind error ``` ==503529== Conditional jump or move depends on uninitialised value(s) ==503529== at 0x619F15E: waddnstr (lib_addstr.c:67) ==503529== by 0x1929B7: _inp_write (inputwin.c:353) ==503529== by 0x1937D5: _inp_redisplay (inputwin.c:619) ==503529== by 0x61511B1: rl_forced_update_display (display.c:2693) ==503529== by 0x193F9D: _inp_rl_send_to_editor (inputwin.c:957) ==503529== by 0x614642F: _rl_dispatch_subseq (readline.c:916) ==503529== by 0x6146C85: _rl_dispatch_callback (readline.c:823) ==503529== by 0x616739F: rl_callback_read_char (callback.c:241) ==503529== by 0x1923DB: inp_readline (inputwin.c:188) ==503529== by 0x149860: prof_run (profanity.c:117) ==503529== by 0x2283E8: main (main.c:186) ==503529== Uninitialised value was created by a stack allocation ==503529== at 0x1928B1: _inp_write (inputwin.c:334) ``` Signed-off-by: Steffen Jaeckel --- src/common.h | 3 +++ src/ui/inputwin.c | 8 +++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/common.h b/src/common.h index dee4a092..6f08d959 100644 --- a/src/common.h +++ b/src/common.h @@ -60,6 +60,9 @@ void auto_free_char(char** str); #define STR_MAYBE_NULL(p) (p) #endif +/* Our own define of MB_CUR_MAX but this time at compile time */ +#define PROF_MB_CUR_MAX 8 + // assume malloc stores at most 8 bytes for size of allocated memory // and page size is at least 4KB #define READ_BUF_SIZE 4088 diff --git a/src/ui/inputwin.c b/src/ui/inputwin.c index bc689d5f..9b652f1c 100644 --- a/src/ui/inputwin.c +++ b/src/ui/inputwin.c @@ -36,6 +36,7 @@ #define _XOPEN_SOURCE_EXTENDED #include "config.h" +#include #include #include #include @@ -140,6 +141,11 @@ static int _inp_rl_send_to_editor(int count, int key); void create_input_window(void) { + /* MB_CUR_MAX is evaluated at runtime depending on the current + * locale, therefore we check that our own version is big enough + * and bail out if it isn't. + */ + assert(MB_CUR_MAX <= PROF_MB_CUR_MAX); #ifdef NCURSES_REENTRANT set_escdelay(25); #else @@ -331,7 +337,7 @@ _inp_write(char* line, int offset) for (size_t i = 0; line[i] != '\0'; i++) { char* c = &line[i]; - char retc[MB_CUR_MAX]; + char retc[PROF_MB_CUR_MAX] = { 0 }; size_t ch_len = mbrlen(c, MB_CUR_MAX, NULL); if ((ch_len == (size_t)-2) || (ch_len == (size_t)-1)) { From d8eea87f6001ef6ba1b2b4c127a6b090ed00226e Mon Sep 17 00:00:00 2001 From: Steffen Jaeckel Date: Thu, 11 May 2023 12:00:15 +0200 Subject: [PATCH 6/6] Fix `-Werror=maybe-uninitialized` When compiling with `CFLAGS="-O2 -fexceptions -Wp,-D_FORTIFY_SOURCE=2"`, as done per default when creating an AUR package e.g. via `makepkg`, this error is produced. Refactor `stanza_create_mam_iq()` in order to fix said warning-turned-into- an-error. Edit by jubalh: I still think the error message is a false positive. But this commit improves the code a lot. Signed-off-by: Steffen Jaeckel --- src/common.h | 3 + src/xmpp/stanza.c | 157 ++++++++++++++-------------------------------- 2 files changed, 49 insertions(+), 111 deletions(-) diff --git a/src/common.h b/src/common.h index 6f08d959..3987133a 100644 --- a/src/common.h +++ b/src/common.h @@ -47,6 +47,9 @@ #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) +#define PROF_STRINGIFY_(n) #n +#define PROF_STRINGIFY(n) PROF_STRINGIFY_(n) + void auto_free_gchar(gchar** str); #define auto_gchar __attribute__((__cleanup__(auto_free_gchar))) void auto_free_gcharv(gchar*** args); diff --git a/src/xmpp/stanza.c b/src/xmpp/stanza.c index 88a7ab6c..bbc15c13 100644 --- a/src/xmpp/stanza.c +++ b/src/xmpp/stanza.c @@ -2757,6 +2757,19 @@ stanza_attach_correction(xmpp_ctx_t* ctx, xmpp_stanza_t* stanza, const char* con return stanza; } +static xmpp_stanza_t* +_text_stanza(xmpp_ctx_t* ctx, const char* name, const char* text) +{ + xmpp_stanza_t* res = xmpp_stanza_new(ctx); + xmpp_stanza_set_name(res, name); + + xmpp_stanza_t* t = xmpp_stanza_new(ctx); + xmpp_stanza_set_text(t, text); + xmpp_stanza_add_child_ex(res, t, 0); + + return res; +} + xmpp_stanza_t* stanza_create_mam_iq(xmpp_ctx_t* ctx, const char* const jid, const char* const startdate, const char* const enddate, const char* const firstid, const char* const lastid) { @@ -2780,145 +2793,67 @@ stanza_create_mam_iq(xmpp_ctx_t* ctx, const char* const jid, const char* const s xmpp_stanza_set_attribute(field_form_type, STANZA_ATTR_VAR, "FORM_TYPE"); xmpp_stanza_set_type(field_form_type, "hidden"); - xmpp_stanza_t* value_mam = xmpp_stanza_new(ctx); - xmpp_stanza_set_name(value_mam, STANZA_NAME_VALUE); + xmpp_stanza_t* value_mam = _text_stanza(ctx, STANZA_NAME_VALUE, STANZA_NS_MAM2); - xmpp_stanza_t* mam_text = xmpp_stanza_new(ctx); - xmpp_stanza_set_text(mam_text, STANZA_NS_MAM2); - xmpp_stanza_add_child(value_mam, mam_text); - - xmpp_stanza_add_child(field_form_type, value_mam); + xmpp_stanza_add_child_ex(field_form_type, value_mam, 0); // field 'with' xmpp_stanza_t* field_with = xmpp_stanza_new(ctx); xmpp_stanza_set_name(field_with, STANZA_NAME_FIELD); xmpp_stanza_set_attribute(field_with, STANZA_ATTR_VAR, "with"); - xmpp_stanza_t* value_with = xmpp_stanza_new(ctx); - xmpp_stanza_set_name(value_with, STANZA_NAME_VALUE); + xmpp_stanza_t* value_with = _text_stanza(ctx, STANZA_NAME_VALUE, jid); - xmpp_stanza_t* with_text = xmpp_stanza_new(ctx); - xmpp_stanza_set_text(with_text, jid); - xmpp_stanza_add_child(value_with, with_text); - - xmpp_stanza_add_child(field_with, value_with); - - // field 'start' - xmpp_stanza_t *field_start, *value_start, *start_date_text; - if (startdate) { - field_start = xmpp_stanza_new(ctx); - xmpp_stanza_set_name(field_start, STANZA_NAME_FIELD); - xmpp_stanza_set_attribute(field_start, STANZA_ATTR_VAR, "start"); - - value_start = xmpp_stanza_new(ctx); - xmpp_stanza_set_name(value_start, STANZA_NAME_VALUE); - - start_date_text = xmpp_stanza_new(ctx); - xmpp_stanza_set_text(start_date_text, startdate); - xmpp_stanza_add_child(value_start, start_date_text); - - xmpp_stanza_add_child(field_start, value_start); - } - - xmpp_stanza_t *field_end, *value_end, *end_date_text; - if (enddate) { - field_end = xmpp_stanza_new(ctx); - xmpp_stanza_set_name(field_end, STANZA_NAME_FIELD); - xmpp_stanza_set_attribute(field_end, STANZA_ATTR_VAR, "end"); - - value_end = xmpp_stanza_new(ctx); - xmpp_stanza_set_name(value_end, STANZA_NAME_VALUE); - - end_date_text = xmpp_stanza_new(ctx); - xmpp_stanza_set_text(end_date_text, enddate); - xmpp_stanza_add_child(value_end, end_date_text); - - xmpp_stanza_add_child(field_end, value_end); - } + xmpp_stanza_add_child_ex(field_with, value_with, 0); // 4.3.2 set/rsm - xmpp_stanza_t *set, *max, *max_text; - set = xmpp_stanza_new(ctx); + xmpp_stanza_t* set = xmpp_stanza_new(ctx); xmpp_stanza_set_name(set, STANZA_TYPE_SET); xmpp_stanza_set_ns(set, STANZA_NS_RSM); - max = xmpp_stanza_new(ctx); - xmpp_stanza_set_name(max, STANZA_NAME_MAX); + xmpp_stanza_t* max = _text_stanza(ctx, STANZA_NAME_MAX, PROF_STRINGIFY(MESSAGES_TO_RETRIEVE)); + xmpp_stanza_add_child_ex(set, max, 0); - max_text = xmpp_stanza_new(ctx); - auto_gchar gchar* txt = g_strdup_printf("%d", MESSAGES_TO_RETRIEVE); - xmpp_stanza_set_text(max_text, txt); - - xmpp_stanza_add_child(max, max_text); - xmpp_stanza_add_child(set, max); - - xmpp_stanza_t *after, *after_text; if (lastid) { - after = xmpp_stanza_new(ctx); - xmpp_stanza_set_name(after, STANZA_NAME_AFTER); - - after_text = xmpp_stanza_new(ctx); - xmpp_stanza_set_text(after_text, lastid); - - xmpp_stanza_add_child(after, after_text); - xmpp_stanza_add_child(set, after); + xmpp_stanza_t* after = _text_stanza(ctx, STANZA_NAME_AFTER, lastid); + xmpp_stanza_add_child_ex(set, after, 0); } - xmpp_stanza_t *before, *before_text; if (firstid) { - before = xmpp_stanza_new(ctx); - xmpp_stanza_set_name(before, STANZA_NAME_BEFORE); - - before_text = xmpp_stanza_new(ctx); - xmpp_stanza_set_text(before_text, firstid); - - xmpp_stanza_add_child(before, before_text); - xmpp_stanza_add_child(set, before); + xmpp_stanza_t* before = _text_stanza(ctx, STANZA_NAME_BEFORE, firstid); + xmpp_stanza_add_child_ex(set, before, 0); } // add and release - xmpp_stanza_add_child(iq, query); - xmpp_stanza_add_child(query, x); - xmpp_stanza_add_child(x, field_form_type); - xmpp_stanza_add_child(x, field_with); + xmpp_stanza_add_child_ex(iq, query, 0); + xmpp_stanza_add_child_ex(query, x, 0); + xmpp_stanza_add_child_ex(x, field_form_type, 0); + xmpp_stanza_add_child_ex(x, field_with, 0); + // field 'start' if (startdate) { - xmpp_stanza_add_child(x, field_start); - xmpp_stanza_release(field_start); - xmpp_stanza_release(value_start); - xmpp_stanza_release(start_date_text); + xmpp_stanza_t* field_start = xmpp_stanza_new(ctx); + xmpp_stanza_set_name(field_start, STANZA_NAME_FIELD); + xmpp_stanza_set_attribute(field_start, STANZA_ATTR_VAR, "start"); + + xmpp_stanza_t* value_start = _text_stanza(ctx, STANZA_NAME_VALUE, startdate); + + xmpp_stanza_add_child_ex(field_start, value_start, 0); + xmpp_stanza_add_child_ex(x, field_start, 0); } if (enddate) { - xmpp_stanza_add_child(x, field_end); - xmpp_stanza_release(field_end); - xmpp_stanza_release(value_end); - xmpp_stanza_release(end_date_text); + xmpp_stanza_t* field_end = xmpp_stanza_new(ctx); + xmpp_stanza_set_name(field_end, STANZA_NAME_FIELD); + xmpp_stanza_set_attribute(field_end, STANZA_ATTR_VAR, "end"); + + xmpp_stanza_t* value_end = _text_stanza(ctx, STANZA_NAME_VALUE, enddate); + + xmpp_stanza_add_child_ex(field_end, value_end, 0); + xmpp_stanza_add_child_ex(x, field_end, 0); } - xmpp_stanza_add_child(query, set); - xmpp_stanza_release(set); - xmpp_stanza_release(max_text); - xmpp_stanza_release(max); - - if (lastid) { - xmpp_stanza_release(after_text); - xmpp_stanza_release(after); - } - - if (firstid) { - xmpp_stanza_release(before_text); - xmpp_stanza_release(before); - } - - xmpp_stanza_release(mam_text); - xmpp_stanza_release(with_text); - xmpp_stanza_release(value_mam); - xmpp_stanza_release(value_with); - xmpp_stanza_release(field_form_type); - xmpp_stanza_release(field_with); - xmpp_stanza_release(x); - xmpp_stanza_release(query); + xmpp_stanza_add_child_ex(query, set, 0); return iq; }