From a771a3edd4b9794a1afea4317250ad0b2c95642a Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sat, 8 Oct 2016 18:36:34 +0300 Subject: [PATCH] Fixed potential crash caused by A_Warp() ACSF_Warp case was refactored to express its intention clearly http://forum.zdoom.org/viewtopic.php?f=2&t=53734 --- src/p_acs.cpp | 79 +++++++++++++++++++++++++++++---------------------- 1 file changed, 45 insertions(+), 34 deletions(-) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 0a2ccddace..71ef65f22b 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -5821,43 +5821,54 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound) // [ZK] A_Warp in ACS case ACSF_Warp: { - int tid_dest = args[0]; - int xofs = args[1]; - int yofs = args[2]; - int zofs = args[3]; - int angle = args[4]; - int flags = args[5]; - const char *statename = argCount > 6 ? FBehavior::StaticLookupString(args[6]) : ""; - bool exact = argCount > 7 ? !!args[7] : false; - int heightoffset = argCount > 8 ? args[8] : 0; - int radiusoffset = argCount > 9 ? args[9] : 0; - int pitch = argCount > 10 ? args[10] : 0; - - FState *state = argCount > 6 ? activator->GetClass()->FindStateByString(statename, exact) : 0; - - AActor *reference; - if((flags & WARPF_USEPTR) && tid_dest != AAPTR_DEFAULT) + if (nullptr == activator) { - reference = COPY_AAPTR(activator, tid_dest); - } - else - { - reference = SingleActorFromTID(tid_dest, activator); - } - - // If there is no activator or actor to warp to, fail. - if (activator == NULL || !reference) return false; - - if (P_Thing_Warp(activator, reference, ACSToDouble(xofs), ACSToDouble(yofs), ACSToDouble(zofs), ACSToAngle(angle), flags, ACSToDouble(heightoffset), ACSToDouble(radiusoffset), ACSToAngle(pitch))) - { - if (state && argCount > 6) - { - activator->SetState(state); - } - return true; } - return false; + + const int dest = args[0]; + const int flags = args[5]; + + AActor* const reference = ((flags & WARPF_USEPTR) && (AAPTR_DEFAULT != dest)) + ? COPY_AAPTR(activator, dest) + : SingleActorFromTID(dest, activator); + + if (nullptr == reference) + { + // there is no actor to warp to + return false; + } + + const double xofs = ACSToDouble(args[1]); + const double yofs = ACSToDouble(args[2]); + const double zofs = ACSToDouble(args[3]); + const DAngle angle = ACSToAngle(args[4]); + const double heightoffset = argCount > 8 ? ACSToDouble(args[8]) : 0.0; + const double radiusoffset = argCount > 9 ? ACSToDouble(args[9]) : 0.0; + const DAngle pitch = ACSToAngle(argCount > 10 ? args[10] : 0); + + if (!P_Thing_Warp(activator, reference, xofs, yofs, zofs, angle, flags, heightoffset, radiusoffset, pitch)) + { + return false; + } + + if (argCount > 6) + { + const char* const statename = FBehavior::StaticLookupString(args[6]); + + if (nullptr != statename) + { + const bool exact = argCount > 7 && !!args[7]; + FState* const state = activator->GetClass()->FindStateByString(statename, exact); + + if (nullptr != state) + { + activator->SetState(state); + } + } + } + + return true; } case ACSF_GetMaxInventory: actor = SingleActorFromTID(args[0], activator);