From b5451a4bdad9ba517706dc0bf97222f3ced4fe4b Mon Sep 17 00:00:00 2001
From: Marko Lindqvist <cazfi74@gmail.com>
Date: Tue, 5 Jul 2022 21:53:55 +0300
Subject: [PATCH 35/35] gtk: Fix NULL dereference in diplodlg with no available
 cities

See osdn #44833

Signed-off-by: Marko Lindqvist <cazfi74@gmail.com>
---
 client/gui-gtk-3.0/diplodlg.c  | 56 ++++++++++++++++++----------------
 client/gui-gtk-3.22/diplodlg.c | 54 +++++++++++++++++---------------
 client/gui-gtk-4.0/diplodlg.c  | 52 ++++++++++++++++---------------
 3 files changed, 87 insertions(+), 75 deletions(-)

diff --git a/client/gui-gtk-3.0/diplodlg.c b/client/gui-gtk-3.0/diplodlg.c
index 32075ce140..2e5f772f97 100644
--- a/client/gui-gtk-3.0/diplodlg.c
+++ b/client/gui-gtk-3.0/diplodlg.c
@@ -340,43 +340,48 @@ static void popup_add_menu(GtkMenuShell *parent, gpointer data)
 
   /****************************************************************
   Creates a sorted list of plr0's cities, excluding the capital and
-  any cities not visible to plr1.  This means that you can only trade 
-  cities visible to requesting player.  
+  any cities not visible to plr1. This means that you can only trade
+  cities visible to requesting player.
 
 			      - Kris Bubendorfer
   *****************************************************************/
   if (game.info.trading_city) {
-    int i = 0, j = 0, n = city_list_size(pgiver->cities);
-    struct city **city_list_ptrs;
+    int i = 0;
+    int n = city_list_size(pgiver->cities);
+
+    menu = gtk_menu_new();
 
     if (n > 0) {
+      struct city **city_list_ptrs;
+
       city_list_ptrs = fc_malloc(sizeof(struct city *) * n);
-    } else {
-      city_list_ptrs = NULL;
-    }
 
-    city_list_iterate(pgiver->cities, pcity) {
-      if (!is_capital(pcity)) {
-	city_list_ptrs[i] = pcity;
-	i++;
-      }
-    } city_list_iterate_end;
+      city_list_iterate(pgiver->cities, pcity) {
+        if (!is_capital(pcity)) {
+          city_list_ptrs[i] = pcity;
+          i++;
+        }
+      } city_list_iterate_end;
 
-    qsort(city_list_ptrs, i, sizeof(struct city *), city_name_compare);
-    
-    menu = gtk_menu_new();
+      if (i > 0) { /* Cities other than capitals */
+        int j;
 
-    for (j = 0; j < i; j++) {
-      item = gtk_menu_item_new_with_label(city_name_get(city_list_ptrs[j]));
+        qsort(city_list_ptrs, i, sizeof(struct city *), city_name_compare);
 
-      gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
-      g_signal_connect(item, "activate",
-		       G_CALLBACK(diplomacy_dialog_city_callback),
-			 GINT_TO_POINTER((player_number(pgiver) << 24) |
-					 (player_number(pother) << 16) |
-					 city_list_ptrs[j]->id));
+        for (j = 0; j < i; j++) {
+          item = gtk_menu_item_new_with_label(city_name_get(city_list_ptrs[j]));
+
+          gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
+          g_signal_connect(item, "activate",
+                           G_CALLBACK(diplomacy_dialog_city_callback),
+                           GINT_TO_POINTER((player_number(pgiver) << 24) |
+                                           (player_number(pother) << 16) |
+                                           city_list_ptrs[j]->id));
+        }
+      }
+
+      free(city_list_ptrs);
     }
-    free(city_list_ptrs);
 
     item = gtk_menu_item_new_with_mnemonic(_("_Cities"));
     gtk_widget_set_sensitive(item, (i > 0));
@@ -385,7 +390,6 @@ static void popup_add_menu(GtkMenuShell *parent, gpointer data)
     gtk_widget_show_all(item);
   }
 
-
   /* Give shared vision. */
   item = gtk_menu_item_new_with_mnemonic(_("_Give shared vision"));
   g_object_set_data(G_OBJECT(item), "plr", pgiver);
diff --git a/client/gui-gtk-3.22/diplodlg.c b/client/gui-gtk-3.22/diplodlg.c
index be9301fa3b..42e65c4362 100644
--- a/client/gui-gtk-3.22/diplodlg.c
+++ b/client/gui-gtk-3.22/diplodlg.c
@@ -340,43 +340,48 @@ static void popup_add_menu(GtkMenuShell *parent, gpointer data)
 
   /****************************************************************
   Creates a sorted list of plr0's cities, excluding the capital and
-  any cities not visible to plr1.  This means that you can only trade 
-  cities visible to requesting player.  
+  any cities not visible to plr1. This means that you can only trade
+  cities visible to requesting player.
 
 			      - Kris Bubendorfer
   *****************************************************************/
   if (game.info.trading_city) {
-    int i = 0, j = 0, n = city_list_size(pgiver->cities);
-    struct city **city_list_ptrs;
+    int i = 0;
+    int n = city_list_size(pgiver->cities);
+
+    menu = gtk_menu_new();
 
     if (n > 0) {
+      struct city **city_list_ptrs;
+
       city_list_ptrs = fc_malloc(sizeof(struct city *) * n);
-    } else {
-      city_list_ptrs = NULL;
-    }
 
-    city_list_iterate(pgiver->cities, pcity) {
-      if (!is_capital(pcity)) {
-        city_list_ptrs[i] = pcity;
-        i++;
-      }
-    } city_list_iterate_end;
+      city_list_iterate(pgiver->cities, pcity) {
+        if (!is_capital(pcity)) {
+          city_list_ptrs[i] = pcity;
+          i++;
+        }
+      } city_list_iterate_end;
 
-    qsort(city_list_ptrs, i, sizeof(struct city *), city_name_compare);
+      if (i > 0) { /* Cities other than capitals */
+        int j;
 
-    menu = gtk_menu_new();
+        qsort(city_list_ptrs, i, sizeof(struct city *), city_name_compare);
 
-    for (j = 0; j < i; j++) {
-      item = gtk_menu_item_new_with_label(city_name_get(city_list_ptrs[j]));
+        for (j = 0; j < i; j++) {
+          item = gtk_menu_item_new_with_label(city_name_get(city_list_ptrs[j]));
 
-      gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
-      g_signal_connect(item, "activate",
-                       G_CALLBACK(diplomacy_dialog_city_callback),
-                       GINT_TO_POINTER((player_number(pgiver) << 24) |
-                                       (player_number(pother) << 16) |
-                                       city_list_ptrs[j]->id));
+          gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
+          g_signal_connect(item, "activate",
+                           G_CALLBACK(diplomacy_dialog_city_callback),
+                           GINT_TO_POINTER((player_number(pgiver) << 24) |
+                                           (player_number(pother) << 16) |
+                                           city_list_ptrs[j]->id));
+        }
+      }
+
+      free(city_list_ptrs);
     }
-    free(city_list_ptrs);
 
     item = gtk_menu_item_new_with_mnemonic(_("_Cities"));
     gtk_widget_set_sensitive(item, (i > 0));
@@ -385,7 +390,6 @@ static void popup_add_menu(GtkMenuShell *parent, gpointer data)
     gtk_widget_show_all(item);
   }
 
-
   /* Give shared vision. */
   item = gtk_menu_item_new_with_mnemonic(_("_Give shared vision"));
   g_object_set_data(G_OBJECT(item), "plr", pgiver);
diff --git a/client/gui-gtk-4.0/diplodlg.c b/client/gui-gtk-4.0/diplodlg.c
index fbc207fc65..5c69e191f6 100644
--- a/client/gui-gtk-4.0/diplodlg.c
+++ b/client/gui-gtk-4.0/diplodlg.c
@@ -345,43 +345,48 @@ static void popup_add_menu(GtkMenuShell *parent, gpointer data)
 
   /****************************************************************
   Creates a sorted list of plr0's cities, excluding the capital and
-  any cities not visible to plr1.  This means that you can only trade
+  any cities not visible to plr1. This means that you can only trade
   cities visible to requesting player.
 
 			      - Kris Bubendorfer
   *****************************************************************/
   if (game.info.trading_city) {
-    int i = 0, j = 0, n = city_list_size(pgiver->cities);
-    struct city **city_list_ptrs;
+    int i = 0;
+    int n = city_list_size(pgiver->cities);
+
+    menu = gtk_menu_button_new();
 
     if (n > 0) {
+      struct city **city_list_ptrs;
+
       city_list_ptrs = fc_malloc(sizeof(struct city *) * n);
-    } else {
-      city_list_ptrs = NULL;
-    }
 
-    city_list_iterate(pgiver->cities, pcity) {
-      if (!is_capital(pcity)) {
-        city_list_ptrs[i] = pcity;
-        i++;
-      }
-    } city_list_iterate_end;
+      city_list_iterate(pgiver->cities, pcity) {
+        if (!is_capital(pcity)) {
+          city_list_ptrs[i] = pcity;
+          i++;
+        }
+      } city_list_iterate_end;
 
-    qsort(city_list_ptrs, i, sizeof(struct city *), city_name_compare);
+      if (i > 0) { /* Cities other than capitals */
+        int j;
 
-    menu = gtk_menu_button_new();
+        qsort(city_list_ptrs, i, sizeof(struct city *), city_name_compare);
 
-    for (j = 0; j < i; j++) {
-      item = gtk_menu_item_new_with_label(city_name_get(city_list_ptrs[j]));
+        for (j = 0; j < i; j++) {
+          item = gtk_menu_item_new_with_label(city_name_get(city_list_ptrs[j]));
 
-      gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
-      g_signal_connect(item, "activate",
-                       G_CALLBACK(diplomacy_dialog_city_callback),
-                       GINT_TO_POINTER((player_number(pgiver) << 24) |
-                                       (player_number(pother) << 16) |
-                                       city_list_ptrs[j]->id));
+          gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
+          g_signal_connect(item, "activate",
+                           G_CALLBACK(diplomacy_dialog_city_callback),
+                           GINT_TO_POINTER((player_number(pgiver) << 24) |
+                                           (player_number(pother) << 16) |
+                                           city_list_ptrs[j]->id));
+        }
+      }
+
+      free(city_list_ptrs);
     }
-    free(city_list_ptrs);
 
     item = gtk_menu_item_new_with_mnemonic(_("_Cities"));
     gtk_widget_set_sensitive(item, (i > 0));
@@ -390,7 +395,6 @@ static void popup_add_menu(GtkMenuShell *parent, gpointer data)
     gtk_widget_show(item);
   }
 
-
   /* Give shared vision. */
   item = gtk_menu_item_new_with_mnemonic(_("_Give shared vision"));
   g_object_set_data(G_OBJECT(item), "plr", pgiver);
-- 
2.35.1