commit 3acca60b6efd93f23607754305a9810b56b44efd
parent 40bb4034e4d657f279713f61cd5ca873a90a0489
Author: wwp <subscript@free.fr>
Date: Sun, 6 Sep 2020 11:41:34 +0200
Fix bug 4313 "Recursion stack overflow with rebuilding folder tree" by
limiting the IMAP rebuild-folder-tree recursion depth to 64 (hidden pref).
Diffstat:
3 files changed, 34 insertions(+), 2 deletions(-)
diff --git a/src/imap.c b/src/imap.c
@@ -123,6 +123,8 @@ struct _IMAPSession
gboolean cancelled;
gboolean sens_update_block;
gboolean do_destroy;
+
+ gint scan_tree_recurs_depth;
};
struct _IMAPNameSpace
@@ -278,6 +280,9 @@ static gint imap_auth (IMAPSession *session,
static gint imap_scan_tree_recursive (IMAPSession *session,
FolderItem *item,
gboolean subs_only);
+static gint imap_scan_tree_recursive_dive (IMAPSession *session,
+ FolderItem *item,
+ gboolean subs_only);
static void imap_create_missing_folders (Folder *folder);
static FolderItem *imap_create_special_folder
@@ -2752,6 +2757,14 @@ static gint imap_scan_tree(Folder *folder)
static gint imap_scan_tree_recursive(IMAPSession *session, FolderItem *item, gboolean subs_only)
{
+ /* reset recursion depth counter */
+ session->scan_tree_recurs_depth = 0;
+
+ return imap_scan_tree_recursive_dive(session, item, subs_only);
+}
+
+static gint imap_scan_tree_recursive_dive(IMAPSession *session, FolderItem *item, gboolean subs_only)
+{
Folder *folder;
IMAPFolder *imapfolder;
FolderItem *new_item;
@@ -2768,6 +2781,15 @@ static gint imap_scan_tree_recursive(IMAPSession *session, FolderItem *item, gbo
g_return_val_if_fail(item->folder != NULL, -1);
g_return_val_if_fail(item->no_sub == FALSE, -1);
+ /* recursion depth limiter */
+ if(session->scan_tree_recurs_depth >= prefs_common.imap_scan_tree_recurs_limit) {
+ g_warning("IMAP scan tree recursion limit reached (%d, folder '%s')",
+ prefs_common.imap_scan_tree_recurs_limit, item->folder->name);
+ return -1;
+ }
+ /* entering recursion func: increase depth counter */
+ session->scan_tree_recurs_depth++;
+
folder = item->folder;
imapfolder = IMAP_FOLDER(folder);
@@ -2895,8 +2917,15 @@ static gint imap_scan_tree_recursive(IMAPSession *session, FolderItem *item, gbo
g_free(base);
}
- if (new_item->no_sub == FALSE)
- imap_scan_tree_recursive(session, new_item, subs_only);
+ if (new_item->no_sub == FALSE) {
+ imap_scan_tree_recursive_dive(session, new_item, subs_only);
+
+ /* entering recursion func: increase depth counter */
+ session->scan_tree_recurs_depth--;
+ if (session->scan_tree_recurs_depth < 0)
+ g_error("IMAP scan tree recursion underflow (%d)",
+ session->scan_tree_recurs_depth);
+ }
}
g_slist_free(item_list);
diff --git a/src/prefs_common.c b/src/prefs_common.c
@@ -1163,6 +1163,8 @@ static PrefParam param[] = {
NULL, NULL, NULL},
/* Hidden */
+ {"imap_scan_tree_recurs_limit", "64", &prefs_common.imap_scan_tree_recurs_limit, P_INT,
+ NULL, NULL, NULL},
{"warn_dnd", "1", &prefs_common.warn_dnd, P_INT,
NULL, NULL, NULL},
{"utf8_instead_of_locale_for_broken_mail", "0",
diff --git a/src/prefs_common.h b/src/prefs_common.h
@@ -537,6 +537,7 @@ struct _PrefsCommon
gint news_subscribe_width;
gint news_subscribe_height;
+ gint imap_scan_tree_recurs_limit;
gint warn_dnd;
gint broken_are_utf8;
gint skip_ssl_cert_check;