From aad64cc06fbde607d0e108a4ac3e7ec5108c63f7 Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Fri, 31 Jul 2015 20:01:55 -0400 Subject: [PATCH] SittingModifier potential null dereference Observed when linking in on DS: if an avatar sits at a sitting mod, that SO is not loaded yet. Boom! --- .../PubUtilLib/plAvatar/plSittingModifier.cpp | 54 ++++++++++--------- 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/Sources/Plasma/PubUtilLib/plAvatar/plSittingModifier.cpp b/Sources/Plasma/PubUtilLib/plAvatar/plSittingModifier.cpp index 318a12a7..b4636d1a 100644 --- a/Sources/Plasma/PubUtilLib/plAvatar/plSittingModifier.cpp +++ b/Sources/Plasma/PubUtilLib/plAvatar/plSittingModifier.cpp @@ -156,30 +156,32 @@ bool plSittingModifier::MsgReceive(plMessage *msg) // own notify messages -- plKey avatarKey = notifyMsg->GetAvatarKey(); plSceneObject * obj = plSceneObject::ConvertNoRef(avatarKey->ObjectIsLoaded()); - const plArmatureMod * avMod = (plArmatureMod*)obj->GetModifierByType(plArmatureMod::Index()); - plAvBrainHuman *brain = (avMod ? plAvBrainHuman::ConvertNoRef(avMod->GetCurrentBrain()) : nil); - if (brain && !brain->IsRunningTask()) - { - plNotifyMsg *notifyEnter = new plNotifyMsg(); // a message to send back when the brain starts - notifyEnter->fState = 1.0f; // it's an "on" event - ISetupNotify(notifyEnter, notifyMsg); // copy events and address to sender - - plNotifyMsg *notifyExit = nil; - if (avatarKey == plNetClientApp::GetInstance()->GetLocalPlayerKey()) + if (obj) { + const plArmatureMod * avMod = (plArmatureMod*)obj->GetModifierByType(plArmatureMod::Index()); + plAvBrainHuman *brain = (avMod ? plAvBrainHuman::ConvertNoRef(avMod->GetCurrentBrain()) : nil); + if (brain && !brain->IsRunningTask()) { - notifyExit = new plNotifyMsg(); // a new message to send back when the brain's done - notifyExit->fState = 0.0f; // it's an "off" event - ISetupNotify(notifyExit, notifyMsg); // copy events and address to sender - notifyExit->AddReceiver(GetKey()); // have this message come back to us as well - - // A player may have joined while we're sitting. We can't update them with the exit notify at - // that point (security hole), so instead the local avatar sends the message out to everybody - // when done. - notifyExit->SetBCastFlag(plMessage::kNetStartCascade, false); - notifyExit->SetBCastFlag(plMessage::kNetPropagate, true); - notifyExit->SetBCastFlag(plMessage::kNetForce, true); + plNotifyMsg *notifyEnter = new plNotifyMsg(); // a message to send back when the brain starts + notifyEnter->fState = 1.0f; // it's an "on" event + ISetupNotify(notifyEnter, notifyMsg); // copy events and address to sender + + plNotifyMsg *notifyExit = nil; + if (avatarKey == plNetClientApp::GetInstance()->GetLocalPlayerKey()) + { + notifyExit = new plNotifyMsg(); // a new message to send back when the brain's done + notifyExit->fState = 0.0f; // it's an "off" event + ISetupNotify(notifyExit, notifyMsg); // copy events and address to sender + notifyExit->AddReceiver(GetKey()); // have this message come back to us as well + + // A player may have joined while we're sitting. We can't update them with the exit notify at + // that point (security hole), so instead the local avatar sends the message out to everybody + // when done. + notifyExit->SetBCastFlag(plMessage::kNetStartCascade, false); + notifyExit->SetBCastFlag(plMessage::kNetPropagate, true); + notifyExit->SetBCastFlag(plMessage::kNetForce, true); + } + Trigger(avMod, notifyEnter, notifyExit); } - Trigger(avMod, notifyEnter, notifyExit); } } // eat the message either way @@ -196,10 +198,12 @@ bool plSittingModifier::MsgReceive(plMessage *msg) { plKey avatarKey = notifyMsg->GetAvatarKey(); plSceneObject * obj = plSceneObject::ConvertNoRef(avatarKey->ObjectIsLoaded()); - plArmatureMod * avMod = (plArmatureMod*)obj->GetModifierByType(plArmatureMod::Index()); + if (obj) { + plArmatureMod * avMod = (plArmatureMod*)obj->GetModifierByType(plArmatureMod::Index()); - uint32_t flags = kBCastToClients | kUseRelevanceRegions | kForceFullSend; - avMod->DirtyPhysicalSynchState(flags); + uint32_t flags = kBCastToClients | kUseRelevanceRegions | kForceFullSend; + avMod->DirtyPhysicalSynchState(flags); + } } } }