From 37de840ce047cf2536e9dc10208a2049363a3450 Mon Sep 17 00:00:00 2001
From: Marko Lindqvist <cazfi74@gmail.com>
Date: Sat, 21 Jan 2023 05:12:57 +0200
Subject: [PATCH 16/16] Retire unit_activity_text()

As not re-entrant, it caused client crashes.

- Convert all callers to use re-entrant unit_activity_astr()
- Remove the function

See osdn #46559

Signed-off-by: Marko Lindqvist <cazfi74@gmail.com>
---
 client/gui-qt/dialogs.cpp | 13 +++++++++----
 client/gui-sdl2/citydlg.c |  6 +++++-
 client/gui-sdl2/dialogs.c | 21 +++++++++++++++++----
 client/gui-sdl2/mapview.c |  5 ++++-
 client/text.c             |  7 +++++--
 common/unit.c             | 16 ----------------
 common/unit.h             |  1 -
 7 files changed, 40 insertions(+), 29 deletions(-)

diff --git a/client/gui-qt/dialogs.cpp b/client/gui-qt/dialogs.cpp
index 2122387e4d..d2ccafc390 100644
--- a/client/gui-qt/dialogs.cpp
+++ b/client/gui-qt/dialogs.cpp
@@ -4544,11 +4544,16 @@ void units_select::paint(QPainter *painter, QPaintEvent *event)
     f_size = &point_size;
   }
   if (highligh_num != -1 && highligh_num < unit_list.count()) {
+    struct astring addition = ASTRING_INIT;
+
     punit = unit_list.at(highligh_num);
-    /* TRANS: HP - hit points */
-    str2 = QString(_("%1 HP:%2/%3")).arg(QString(unit_activity_text(punit)),
-                                      QString::number(punit->hp),
-                                      QString::number(unit_type_get(punit)->hp));
+    unit_activity_astr(punit, &addition);
+
+    // TRANS: HP - hit points
+    str2 = QString(_("%1 HP:%2/%3")).arg(QString(astr_str(&addition)),
+                                         QString::number(punit->hp),
+                                         QString::number(unit_type_get(punit)->hp));
+    astr_free(&addition);
   }
   str = QString(PL_("%1 unit", "%1 units",
                     unit_list_size(utile->units)))
diff --git a/client/gui-sdl2/citydlg.c b/client/gui-sdl2/citydlg.c
index eb96289961..00023316b2 100644
--- a/client/gui-sdl2/citydlg.c
+++ b/client/gui-sdl2/citydlg.c
@@ -31,6 +31,7 @@
 #endif /* SDL2_PLAIN_INCLUDE */
 
 /* utility */
+#include "astring.h"
 #include "bitvector.h"
 #include "fcintl.h"
 #include "log.h"
@@ -723,10 +724,12 @@ static void create_present_supported_units_widget_list(struct unit_list *units)
 
   unit_list_iterate(units, punit) {
     const char *vetname;
+    struct astring addition = ASTRING_INIT;
 
     putype = unit_type_get(punit);
     vetname = utype_veteran_name_translation(putype, punit->veteran);
     home_city = game_city_by_number(punit->homecity);
+    unit_activity_astr(punit, &addition);
     fc_snprintf(cbuf, sizeof(cbuf), "%s (%d,%d,%s)%s%s\n%s\n(%d/%d)\n%s",
                 utype_name_translation(putype),
                 putype->attack_strength,
@@ -734,9 +737,10 @@ static void create_present_supported_units_widget_list(struct unit_list *units)
                 move_points_text(putype->move_rate, FALSE),
                 (vetname != NULL ? "\n" : ""),
                 (vetname != NULL ? vetname : ""),
-                unit_activity_text(punit),
+                astr_str(&addition),
                 punit->hp, putype->hp,
                 home_city ? home_city->name : Q_("?homecity:None"));
+    astr_free(&addition);
 
     if (pcity_dlg->page == SUPPORTED_UNITS_PAGE) {
       int city_near_dist;
diff --git a/client/gui-sdl2/dialogs.c b/client/gui-sdl2/dialogs.c
index 15df9d0a41..21e26b7d13 100644
--- a/client/gui-sdl2/dialogs.c
+++ b/client/gui-sdl2/dialogs.c
@@ -31,6 +31,7 @@
 #endif /* SDL2_PLAIN_INCLUDE */
 
 /* utility */
+#include "astring.h"
 #include "bitvector.h"
 #include "fcintl.h"
 #include "log.h"
@@ -1135,6 +1136,9 @@ void unit_select_dialog_popup(struct tile *ptile)
     vetname = utype_veteran_name_translation(punittype, punit->veteran);
 
     if (unit_owner(punit) == client.conn.playing) {
+      struct astring addition = ASTRING_INIT;
+
+      unit_activity_astr(punit, &addition);
       fc_snprintf(cbuf , sizeof(cbuf), _("Contact %s (%d / %d) %s(%d,%d,%s) %s"),
                   (vetname != NULL ? vetname : ""),
                   punit->hp, punittype->hp,
@@ -1142,7 +1146,8 @@ void unit_select_dialog_popup(struct tile *ptile)
                   punittype->attack_strength,
                   punittype->defense_strength,
                   move_points_text(punittype->move_rate, FALSE),
-                  unit_activity_text(punit));
+                  astr_str(&addition));
+      astr_free(&addition);
     } else {
       int att_chance, def_chance;
 
@@ -1912,6 +1917,9 @@ void popup_advanced_terrain_dialog(struct tile *ptile, Uint16 pos_x, Uint16 pos_
         vetname = utype_veteran_name_translation(punittype, punit->veteran);
 
         if (unit_owner(punit) == client.conn.playing) {
+          struct astring addition = ASTRING_INIT;
+
+          unit_activity_astr(punit, &addition);
           fc_snprintf(cbuf, sizeof(cbuf),
                       _("Activate %s (%d / %d) %s (%d,%d,%s) %s"),
                       (vetname != NULL ? vetname : ""),
@@ -1920,8 +1928,9 @@ void popup_advanced_terrain_dialog(struct tile *ptile, Uint16 pos_x, Uint16 pos_
                       punittype->attack_strength,
                       punittype->defense_strength,
                       move_points_text(punittype->move_rate, FALSE),
-                      unit_activity_text(punit));
-    
+                      astr_str(&addition));
+          astr_free(&addition);
+
           create_active_iconlabel(buf, pwindow->dst, pstr,
                                   cbuf, adv_unit_select_callback);
           buf->data.unit = punit;
@@ -2024,6 +2033,9 @@ void popup_advanced_terrain_dialog(struct tile *ptile, Uint16 pos_x, Uint16 pos_
         vetname = utype_veteran_name_translation(punittype, punit->veteran);
         if ((pcity && city_owner(pcity) == client.conn.playing)
             || (unit_owner(punit) == client.conn.playing)) {
+          struct astring addition = ASTRING_INIT;
+
+          unit_activity_astr(punit, &addition);
           fc_snprintf(cbuf, sizeof(cbuf),
                       _("Activate %s (%d / %d) %s (%d,%d,%s) %s"),
                       (vetname != NULL ? vetname : ""),
@@ -2032,7 +2044,8 @@ void popup_advanced_terrain_dialog(struct tile *ptile, Uint16 pos_x, Uint16 pos_
                       punittype->attack_strength,
                       punittype->defense_strength,
                       move_points_text(punittype->move_rate, FALSE),
-                      unit_activity_text(punit));
+                      astr_str(&addition));
+          astr_free(&addition);
 
           create_active_iconlabel(buf, pwindow->dst, pstr,
                                   cbuf, adv_unit_select_callback);
diff --git a/client/gui-sdl2/mapview.c b/client/gui-sdl2/mapview.c
index c0aa89b10d..00f68baf2e 100644
--- a/client/gui-sdl2/mapview.c
+++ b/client/gui-sdl2/mapview.c
@@ -807,6 +807,7 @@ void redraw_unit_info_label(struct unit_list *punitlist)
 
         unit_list_iterate(ptile->units, aunit) {
           SDL_Surface *tmp_surf;
+          struct astring addition = ASTRING_INIT;
 
           if (aunit == punit) {
             continue;
@@ -815,6 +816,7 @@ void redraw_unit_info_label(struct unit_list *punitlist)
           putype = unit_type_get(aunit);
           vetname = utype_veteran_name_translation(putype, aunit->veteran);
           home_city = game_city_by_number(aunit->homecity);
+          unit_activity_astr(aunit, &addition);
           fc_snprintf(buffer, sizeof(buffer),
                       "%s (%d,%d,%s)%s%s\n%s\n(%d/%d)\n%s",
                       utype_name_translation(putype),
@@ -823,9 +825,10 @@ void redraw_unit_info_label(struct unit_list *punitlist)
                       move_points_text(putype->move_rate, FALSE),
                       (vetname != NULL ? "\n" : ""),
                       (vetname != NULL ? vetname : ""),
-                      unit_activity_text(aunit),
+                      astr_str(&addition),
                       aunit->hp, putype->hp,
                       home_city ? city_name_get(home_city) : Q_("?homecity:None"));
+          astr_free(&addition);
 
           buf_surf = create_surf(tileset_full_tile_width(tileset),
                                  tileset_full_tile_height(tileset),
diff --git a/client/text.c b/client/text.c
index c0c40cf253..4a30171fb6 100644
--- a/client/text.c
+++ b/client/text.c
@@ -1116,8 +1116,11 @@ const char *get_unit_info_label_text2(struct unit_list *punits, int linebreaks)
       astr_add_line(&str, _("Turns to target: %d to %d"), min, max);
     }
   } else if (count == 1) {
-    astr_add_line(&str, "%s",
-		  unit_activity_text(unit_list_get(punits, 0)));
+    struct astring addition = ASTRING_INIT;
+
+    unit_activity_astr(unit_list_get(punits, 0), &addition);
+    astr_add_line(&str, "%s", astr_str(&addition));
+    astr_free(&addition);
   } else if (count > 1) {
     astr_add_line(&str, PL_("%d unit selected",
 			    "%d units selected",
diff --git a/common/unit.c b/common/unit.c
index d683212eb6..b3f67f1928 100644
--- a/common/unit.c
+++ b/common/unit.c
@@ -1154,22 +1154,6 @@ bv_extras get_unit_tile_pillage_set(const struct tile *ptile)
   return tgt_ret;
 }
 
-/**********************************************************************//**
-  Return text describing the unit's current activity as a static string.
-
-  FIXME: Convert all callers of this function to unit_activity_astr()
-  because this function is not re-entrant.
-**************************************************************************/
-const char *unit_activity_text(const struct unit *punit)
-{
-  static struct astring str = ASTRING_INIT;
-
-  astr_clear(&str);
-  unit_activity_astr(punit, &str);
-
-  return astr_str(&str);
-}
-
 /**********************************************************************//**
   Append text describing the unit's current activity to the given astring.
 **************************************************************************/
diff --git a/common/unit.h b/common/unit.h
index a6f17e752a..78071b9287 100644
--- a/common/unit.h
+++ b/common/unit.h
@@ -373,7 +373,6 @@ bool kills_citizen_after_attack(const struct unit *punit);
 struct astring; /* Forward declaration. */
 void unit_activity_astr(const struct unit *punit, struct astring *astr);
 void unit_upkeep_astr(const struct unit *punit, struct astring *astr);
-const char *unit_activity_text(const struct unit *punit);
 
 int get_transporter_capacity(const struct unit *punit);
 
-- 
2.39.0