From acb737237710cfa45f6286c3cbedfc89fd3454f6 Mon Sep 17 00:00:00 2001
From: Sweet Tea Dorminy <sweettea-kernel@dorminy.me>
Date: Mon, 2 Nov 2026 07:52:15 -0800
Subject: [PATCH] ai/default: Clean up on every early return from
 cityresult_fill()

cityresult_fill() switches the player's government to the goal
government and, for a virtual city, gives the center tile to the
player for the duration of the evaluation. The restore lives only at
the end of the function, and three early returns skipped it: the
missing city center check leaked the result and the virtual city and
left the government and the tile owner changed, the "all tiles worked"
return left the government changed, and the final sanity checks leaked
the result. Every return now restores and frees what the normal path
does.

See RM #TBD

Signed-off-by: Sweet Tea Dorminy <sweettea-kernel@dorminy.me>
---
 ai/default/daisettler.c | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/ai/default/daisettler.c b/ai/default/daisettler.c
index 3ac6646ed4..4caca72142 100644
--- a/ai/default/daisettler.c
+++ b/ai/default/daisettler.c
@@ -399,6 +399,13 @@ static struct cityresult *cityresult_fill(struct ai_type *ait,
   if (result->city_center.tdc == nullptr) {
     fc_assert(result->city_center.tdc != nullptr);
 
+    pplayer->government = curr_govt;
+    if (virtual_city) {
+      destroy_city_virtual(pcity);
+      tile_set_owner(result->tile, saved_owner, saved_claimer);
+    }
+    cityresult_destroy(result);
+
     return nullptr;
   }
 
@@ -414,6 +421,8 @@ static struct cityresult *cityresult_fill(struct ai_type *ait,
   } else {
     /* There is no available tile in this city. All is worked. */
     result->total = 0;
+    pplayer->government = curr_govt;
+
     return result;
   }
 
@@ -458,8 +467,13 @@ static struct cityresult *cityresult_fill(struct ai_type *ait,
     tile_set_owner(result->tile, saved_owner, saved_claimer);
   }
 
-  fc_assert_ret_val(result->city_center.tdc->sum >= 0, nullptr);
-  fc_assert_ret_val(result->remaining >= 0, nullptr);
+  if (result->city_center.tdc->sum < 0 || result->remaining < 0) {
+    fc_assert(result->city_center.tdc->sum >= 0);
+    fc_assert(result->remaining >= 0);
+    cityresult_destroy(result);
+
+    return nullptr;
+  }
 
   return result;
 }
-- 
2.55.0

