From 6b2b8a198f04d2aaf7c335f5eb736e40768f0667 Mon Sep 17 00:00:00 2001 From: Rachael Alexanderson Date: Fri, 6 Jun 2025 08:49:08 -0400 Subject: [PATCH] - implement limits for state loops to prevent infinite state freezes --- src/playsim/p_mobj.cpp | 8 ++++++++ src/playsim/p_pspr.cpp | 10 ++++++++++ 2 files changed, 18 insertions(+) diff --git a/src/playsim/p_mobj.cpp b/src/playsim/p_mobj.cpp index 8b0ac17f4..24aec14e9 100644 --- a/src/playsim/p_mobj.cpp +++ b/src/playsim/p_mobj.cpp @@ -874,9 +874,17 @@ bool AActor::SetState (FState *newstate, bool nofunction) if (debugfile && player && (player->cheats & CF_PREDICTING)) fprintf (debugfile, "for pl %d: SetState while predicting!\n", Level->PlayerNum(player)); + int statelooplimit = 300000; auto oldstate = state; do { + if (!(--statelooplimit)) + { + Printf(TEXTCOLOR_RED "Infinite state loop in Actor '%s' state '%s'\n", GetClass()->TypeName.GetChars(), FState::StaticGetStateName(state).GetChars()); + state = nullptr; + Destroy(); + return false; + } if (newstate == NULL) { state = NULL; diff --git a/src/playsim/p_pspr.cpp b/src/playsim/p_pspr.cpp index 54ae4b6cf..d56e1868c 100644 --- a/src/playsim/p_pspr.cpp +++ b/src/playsim/p_pspr.cpp @@ -488,10 +488,20 @@ void DPSprite::SetState(FState *newstate, bool pending) WF_USER1OK | WF_USER2OK | WF_USER3OK | WF_USER4OK); } + int statelooplimit = 300000; + processPending = pending; do { + if (!(--statelooplimit)) + { + Printf(TEXTCOLOR_RED "Infinite state loop in weapon state '%s'\n", FState::StaticGetStateName(State).GetChars()); + State = nullptr; + Destroy(); + return; + } + if (newstate == nullptr) { // Object removed itself. Destroy();