From 235ac75861ba9a789c777e98841e307e2040c2be Mon Sep 17 00:00:00 2001
From: Sweet Tea Dorminy <sweettea-kernel@dorminy.me>
Date: Sat, 7 Nov 2026 23:33:07 -0800
Subject: [PATCH] ai/default: Square the city danger in 64 bits

military_advisor_choose_build() squares unsigned city_data->danger into
an int, and this wraps; for some values it wraps negative and the city is
handled as needing no defence at all. The percentage
100 * qdanger / our_def wraps too.

Square into a uint64_t instead and take the percentage there, so a big
stack is gauged rather than clamped. There is no value where qdanger can
be a negative number.

See RM #2467

Signed-off-by: Sweet Tea Dorminy <sweettea-kernel@dorminy.me>
---
 ai/default/daimilitary.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/ai/default/daimilitary.c b/ai/default/daimilitary.c
index 7f96caeb02..c7bb9af845 100644
--- a/ai/default/daimilitary.c
+++ b/ai/default/daimilitary.c
@@ -15,6 +15,7 @@
 #include <fc_config.h>
 #endif
 
+#include <stdint.h>
 #include <string.h>
 
 /* utility */
@@ -1835,9 +1836,10 @@ struct adv_choice *military_advisor_choose_build(struct ai_type *ait,
     int wall_id, danger;
     bool build_walls = TRUE;
     bool def_unit_selected = FALSE;
-    int qdanger = city_data->danger * city_data->danger;
+    /* The square of a 32-bit sum needs 64 bits. */
+    uint64_t qdanger = (uint64_t) city_data->danger * city_data->danger;
 
-    if (qdanger <= 0) {
+    if (qdanger == 0) {
       /* We only need these defenders because of Martial Law value */
       danger = 0;
       build_walls = FALSE; /* Walls don't provide Martial Law */
@@ -1851,10 +1853,10 @@ struct adv_choice *military_advisor_choose_build(struct ai_type *ait,
         } else if (our_def == 0) {
           danger = 200 + urgency;
         } else {
-          danger = MIN(200, 100 * qdanger / our_def) + urgency;
+          danger = MIN(200, (int) (100 * qdanger / our_def)) + urgency;
         }
       } else {
-        danger = 100 * qdanger / our_def;
+        danger = (int) (100 * qdanger / our_def);
       }
 
       if (pcity->surplus[O_SHIELD] <= 0 && our_def != 0) {
-- 
2.55.0

