diff options
author | Lauri Kasanen <curaga@operamail.com> | 2016-10-27 16:51:29 +0300 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2016-11-10 17:09:45 -0500 |
commit | 0d364173f61feb4d089eaa95ace9c1cc13681339 (patch) | |
tree | 8112d5a5cbda5877088b6272d002250794173b9a /gtk/gtkrecentmanager.c | |
parent | 3c27774a5d7251df9adc6c4d80071ac6f1153e17 (diff) | |
download | gtk+-0d364173f61feb4d089eaa95ace9c1cc13681339.tar.gz |
recent-manager: Add a limit to the list's size
This fixes a DOS where any app can cause all running gtk apps
to use arbitrary amounts of memory.
Originally reported against mate-panel, where running a big slideshow
in eye-of-mate caused increasing RAM usage in mate-panel.
v2: Hardcode the value
Signed-off-by: Lauri Kasanen <curaga@operamail.com>
https://bugzilla.gnome.org/show_bug.cgi?id=773587
Diffstat (limited to 'gtk/gtkrecentmanager.c')
-rw-r--r-- | gtk/gtkrecentmanager.c | 43 |
1 files changed, 40 insertions, 3 deletions
diff --git a/gtk/gtkrecentmanager.c b/gtk/gtkrecentmanager.c index 1157eec3ea..fe5f03f2ba 100644 --- a/gtk/gtkrecentmanager.c +++ b/gtk/gtkrecentmanager.c @@ -113,6 +113,9 @@ /* return all items by default */ #define DEFAULT_LIMIT -1 +/* limit the size of the list */ +#define MAX_LIST_SIZE 1000 + /* keep in sync with xdgmime */ #define GTK_RECENT_DEFAULT_MIME "application/octet-stream" @@ -211,6 +214,9 @@ static void gtk_recent_manager_set_filename (GtkRecentManager *manag const gchar *filename); static void gtk_recent_manager_clamp_to_age (GtkRecentManager *manager, gint age); +static void gtk_recent_manager_clamp_to_size (GtkRecentManager *manager, + const gint size); + static void gtk_recent_manager_enabled_changed (GtkRecentManager *manager); @@ -462,6 +468,7 @@ gtk_recent_manager_real_changed (GtkRecentManager *manager) { GtkSettings *settings; gint age; + gint max_size = MAX_LIST_SIZE; gboolean enabled; settings = gtk_settings_get_default (); @@ -476,14 +483,19 @@ gtk_recent_manager_real_changed (GtkRecentManager *manager) enabled = TRUE; } - if (age == 0 || !enabled) + if (age == 0 || max_size == 0 || !enabled) { g_bookmark_file_free (priv->recent_items); priv->recent_items = g_bookmark_file_new (); priv->size = 0; } - else if (age > 0) - gtk_recent_manager_clamp_to_age (manager, age); + else + { + if (age > 0) + gtk_recent_manager_clamp_to_age (manager, age); + if (max_size > 0) + gtk_recent_manager_clamp_to_size (manager, max_size); + } } if (priv->filename != NULL) @@ -1455,6 +1467,31 @@ gtk_recent_manager_clamp_to_age (GtkRecentManager *manager, g_strfreev (uris); } +static void +gtk_recent_manager_clamp_to_size (GtkRecentManager *manager, + const gint size) +{ + GtkRecentManagerPrivate *priv = manager->priv; + gchar **uris; + gsize n_uris, i; + + if (G_UNLIKELY (!priv->recent_items) || G_UNLIKELY (size < 0)) + return; + + uris = g_bookmark_file_get_uris (priv->recent_items, &n_uris); + + if (n_uris < size) + return; + + for (i = 0; i < n_uris - size; i++) + { + const gchar *uri = uris[i]; + g_bookmark_file_remove_item (priv->recent_items, uri, NULL); + } + + g_strfreev (uris); +} + /***************** * GtkRecentInfo * *****************/ |