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