Blob Blame History Raw
From 8f01a166ec2097f913f4e69379954a96a38d0d84 Mon Sep 17 00:00:00 2001
From: Michael Catanzaro <mcatanzaro@gnome.org>
Date: Wed, 6 May 2020 10:57:41 -0500
Subject: [PATCH 4/4] appchooserdialog: improve safety of ensure_default
 function

We can calculate the bounds ourselves, instead of passing them in. This
way we don't need to rely on the caller to avoid buffer overflow. This
would have prevented #302.

(cherry picked from commit 1f30f6c730cef5152e09ded897ec0d6e54e87820)
---
 src/appchooserdialog.c | 20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/src/appchooserdialog.c b/src/appchooserdialog.c
index c0eb4ca..eb7181a 100644
--- a/src/appchooserdialog.c
+++ b/src/appchooserdialog.c
@@ -316,22 +316,26 @@ shorten_location (const char *location)
 }
 
 static void
-ensure_default_is_below (const char **choices,
-                         const char  *default_id,
-                         int          num)
+ensure_default_in_initial_list (const char **choices,
+                                const char  *default_id)
 {
   int i;
+  guint n_choices;
 
   if (default_id == NULL)
     return;
 
-  for (i = 0; i < num && choices[i]; i++)
+  n_choices = g_strv_length ((char **)choices);
+  if (n_choices <= INITIAL_LIST_SIZE)
+    return;
+
+  for (i = 0; i < INITIAL_LIST_SIZE; i++)
     {
       if (strcmp (choices[i], default_id) == 0)
         return;
     }
 
-  for (i = num; choices[i]; i++)
+  for (i = INITIAL_LIST_SIZE; i < n_choices; i++)
     {
       if (strcmp (choices[i], default_id) == 0)
         {
@@ -386,11 +390,11 @@ app_chooser_dialog_new (const char **choices,
       gtk_label_set_label (GTK_LABEL (dialog->heading), _("Choose an application."));
     }
 
-  dialog->choices = g_strdupv ((char **)choices);
-  n_choices = g_strv_length ((char **)choices);
+  ensure_default_in_initial_list (choices, default_id);
 
-  ensure_default_is_below (dialog->choices, default_id, MIN (n_choices, INITIAL_LIST_SIZE));
+  dialog->choices = g_strdupv ((char **)choices);
 
+  n_choices = g_strv_length ((char **)choices);
   if (n_choices == 0)
     {
       gtk_widget_show (dialog->empty_box);
-- 
2.26.2