From: drjaska <drjaska83@gmail.com>
Date: Fri, 29 Nov 2024 01:31:58 +0000 (+0200)
Subject: Add stack overflow safeguard to defrag_waypointsprites
X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=c32f5682bb51fc3042c1630882f7c7fbbce79689;p=xonotic%2Fxonotic-data.pk3dir.git

Add stack overflow safeguard to defrag_waypointsprites
---

diff --git a/qcsrc/server/race.qc b/qcsrc/server/race.qc
index b2f62e1234..b0cb748939 100644
--- a/qcsrc/server/race.qc
+++ b/qcsrc/server/race.qc
@@ -877,12 +877,27 @@ bool race_waypointsprite_visible_for_player(entity this, entity player, entity v
 		return false;
 }
 
-void defrag_waypointsprites(entity targeted, entity checkpoint)
+void defrag_waypointsprites(entity targeted, entity checkpoint, int recursionlevel)
 {
 	// bones_was_here: spawn a waypoint for every entity with a bmodel
 	// that directly or indirectly targets this checkpoint
 	// (anything a player could touch or shoot to activate this cp)
 
+	// spam a few warnings so that larger link chain loops can be found
+	if (recursionlevel > 400)
+	{
+		LOG_WARNF("df cp wp loop: ^4\"target\" ^3\"%s\"^7, ^4\"targetname\" ^3\"%s\"^7",
+			targeted.classname,
+			targeted.targetname);
+	}
+	// avoid a stack overflow
+	if (recursionlevel > 420)
+	{
+		LOG_WARNF("Aborted creating defrag checkpoint waypointsprites for ^2%s^7 due to a loop",
+			checkpoint.classname);
+		return;
+	}
+
 	entity s = WP_RaceCheckpoint;
 	if (checkpoint.classname == "target_startTimer")
 		s = WP_RaceStart;
@@ -899,7 +914,7 @@ void defrag_waypointsprites(entity targeted, entity checkpoint)
 		}
 
 		if (t.targetname && t != checkpoint)
-			defrag_waypointsprites(t, checkpoint);
+			defrag_waypointsprites(t, checkpoint, ++recursionlevel);
 	}
 }
 
@@ -999,7 +1014,7 @@ void trigger_race_checkpoint_verify(entity this)
 		if (defrag_ents) {
 			IL_EACH(g_race_targets, it.classname == "target_checkpoint" || it.classname == "target_startTimer" || it.classname == "target_stopTimer",
 			{
-				defrag_waypointsprites(it, it);
+				defrag_waypointsprites(it, it, 0);
 
 				if(it.classname == "target_checkpoint") {
 					if(it.race_checkpoint == -2)