Author: sveinung
Date: Fri Mar  6 12:16:35 2015
New Revision: 28428

URL: http://svn.gna.org/viewcvs/freeciv?rev=28428&view=rev
Log:
Tolerate if actor or target unit dies in a Lua action_started_* callback.

Lua function like unleash_barbarians() and unit_teleport() may cause a unit
to die. Add a sanity check that the actor unit (and, where relevant, target
unit) is alive to stop a unit killed in a Lua callback from crashing
Freeciv.

See bug #23350

Modified:
    trunk/server/diplomats.c
    trunk/server/unithand.c

Modified: trunk/server/diplomats.c
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/server/diplomats.c?rev=28428&r1=28427&r2=28428&view=diff
==============================================================================
--- trunk/server/diplomats.c    (original)
+++ trunk/server/diplomats.c    Fri Mar  6 12:16:35 2015
@@ -98,7 +98,7 @@
   }
 
   /* Sanity check: The actor still exists. */
-  if (!pplayer || !pdiplomat) {
+  if (!pplayer || !pdiplomat || !unit_alive(pdiplomat->id)) {
     return;
   }
 
@@ -174,7 +174,7 @@
     return;
 
   /* Sanity check: The actor still exists. */
-  if (!pplayer || !pdiplomat) {
+  if (!pplayer || !pdiplomat || !unit_alive(pdiplomat->id)) {
     return;
   }
 
@@ -278,7 +278,7 @@
   }
 
   /* Sanity check: The actor still exists. */
-  if (!pplayer || !pdiplomat) {
+  if (!pplayer || !pdiplomat || !unit_alive(pdiplomat->id)) {
     return;
   }
 
@@ -334,7 +334,7 @@
   struct player *uplayer;
 
   /* Fetch target unit's player.  Sanity checks. */
-  if (!pvictim) {
+  if (!pvictim || !unit_alive(pvictim->id)) {
     return;
   }
 
@@ -344,7 +344,7 @@
   }
 
   /* Sanity check: The actor still exists. */
-  if (!pplayer || !pdiplomat) {
+  if (!pplayer || !pdiplomat || !unit_alive(pdiplomat->id)) {
     return;
   }
 
@@ -428,7 +428,7 @@
   struct city *pcity;
 
   /* Fetch target unit's player.  Sanity checks. */
-  if (!pvictim) {
+  if (!pvictim || !unit_alive(pvictim->id)) {
     return;
   }
   uplayer = unit_owner(pvictim);
@@ -437,7 +437,7 @@
   }
 
   /* Sanity check: The actor still exists. */
-  if (!pplayer || !pdiplomat) {
+  if (!pplayer || !pdiplomat || !unit_alive(pdiplomat->id)) {
     return;
   }
 
@@ -565,7 +565,7 @@
   }
 
   /* Sanity check: The actor still exists. */
-  if (!pplayer || !pdiplomat) {
+  if (!pplayer || !pdiplomat || !unit_alive(pdiplomat->id)) {
     return;
   }
   
@@ -721,7 +721,7 @@
   }
 
   /* Sanity check: The actor still exists. */
-  if (!pplayer || !pdiplomat) {
+  if (!pplayer || !pdiplomat || !unit_alive(pdiplomat->id)) {
     return;
   }
 
@@ -846,7 +846,7 @@
   }
 
   /* Sanity check: The actor still exists. */
-  if (!pplayer || !pdiplomat) {
+  if (!pplayer || !pdiplomat || !unit_alive(pdiplomat->id)) {
     return;
   }
 
@@ -1095,7 +1095,7 @@
   int gold_give;
 
   /* Sanity check: The actor still exists. */
-  if (!act_player || !act_unit) {
+  if (!act_player || !act_unit || !unit_alive(act_unit->id)) {
     return;
   }
 

Modified: trunk/server/unithand.c
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/server/unithand.c?rev=28428&r1=28427&r2=28428&view=diff
==============================================================================
--- trunk/server/unithand.c     (original)
+++ trunk/server/unithand.c     Fri Mar  6 12:16:35 2015
@@ -218,6 +218,11 @@
   struct city *pcity;
   char capturer_link[MAX_LEN_LINK];
   const char *capturer_nation = nation_plural_for_player(pplayer);
+
+  /* Sanity check: The actor is still alive. */
+  if (!unit_alive(punit->id)) {
+    return;
+  }
 
   /* N.B: unit_link() always returns the same pointer. */
   sz_strlcpy(capturer_link, unit_link(punit));
@@ -2315,6 +2320,11 @@
     return;
   }
 
+  /* Sanity check: The actor is still alive. */
+  if (!unit_alive(punit->id)) {
+    return;
+  }
+
   pcity_dest = game_city_by_number(city_id);
 
   /* Sanity check: The target city still exists. */
@@ -2407,6 +2417,11 @@
     /* Probably died or bribed. */
     log_verbose("do_unit_establish_trade() invalid unit %d",
                 unit_id);
+    return FALSE;
+  }
+
+  /* Sanity check: The actor is still alive. */
+  if (!unit_alive(punit->id)) {
     return FALSE;
   }
 


_______________________________________________
Freeciv-commits mailing list
Freeciv-commits@gna.org
https://mail.gna.org/listinfo/freeciv-commits

Reply via email to