From: Vsevolod Stakhov Date: Mon, 6 Oct 2025 09:36:49 +0000 (+0100) Subject: [Fix] Correct Lua stack cleanup in lua_task_get_rcpt_esmtp_args by removing temporary... X-Git-Tag: 3.14.0~89^2~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7c75b63a8e46d1118fcb15fe11f62eb1cee6ce58;p=thirdparty%2Frspamd.git [Fix] Correct Lua stack cleanup in lua_task_get_rcpt_esmtp_args by removing temporary tables in descending order to avoid index shifts and crashes --- diff --git a/src/lua/lua_task.c b/src/lua/lua_task.c index ffeabc4212..a42b1aba00 100644 --- a/src/lua/lua_task.c +++ b/src/lua/lua_task.c @@ -4600,10 +4600,36 @@ lua_task_get_rcpt_esmtp_args(lua_State *L) } /* Clean up temporary tables */ - g_hash_table_iter_init(&iter, rcpt_args_by_idx); - while (g_hash_table_iter_next(&iter, &key, &value)) { - int table_idx = GPOINTER_TO_INT(value); - lua_remove(L, table_idx); + { + /* Collect indices first */ + GHashTableIter iter2; + gpointer key2, value2; + GArray *to_remove = g_array_new(FALSE, FALSE, sizeof(int)); + + g_hash_table_iter_init(&iter2, rcpt_args_by_idx); + while (g_hash_table_iter_next(&iter2, &key2, &value2)) { + int table_idx = GPOINTER_TO_INT(value2); + g_array_append_val(to_remove, table_idx); + } + + /* Remove in descending order to avoid index shifts */ + while (to_remove->len > 0) { + guint max_pos = 0; + int max_idx = g_array_index(to_remove, int, 0); + + for (guint j = 1; j < to_remove->len; j++) { + int v = g_array_index(to_remove, int, j); + if (v > max_idx) { + max_idx = v; + max_pos = j; + } + } + + lua_remove(L, max_idx); + g_array_remove_index_fast(to_remove, max_pos); + } + + g_array_free(to_remove, TRUE); } } else {