From 486987026712eef891e0d3f23326352443d006a3 Mon Sep 17 00:00:00 2001 From: Leonid Pospelov Date: Sat, 4 May 2024 00:15:15 +0500 Subject: [PATCH] fix(skyrim-platform): fix potential magicEffectApply crash (#1951) --- .../dev/sp-fix-magicEffectApply-crash.md | 1 + .../skyrim_platform/EventHandler.cpp | 38 ++++++++++++++----- 2 files changed, 30 insertions(+), 9 deletions(-) create mode 100644 docs/release/dev/sp-fix-magicEffectApply-crash.md diff --git a/docs/release/dev/sp-fix-magicEffectApply-crash.md b/docs/release/dev/sp-fix-magicEffectApply-crash.md new file mode 100644 index 0000000000..ff53e0ef9f --- /dev/null +++ b/docs/release/dev/sp-fix-magicEffectApply-crash.md @@ -0,0 +1 @@ +Fixed potential crash when loading a save with at least one active `magicEffectApply` listener. diff --git a/skyrim-platform/src/platform_se/skyrim_platform/EventHandler.cpp b/skyrim-platform/src/platform_se/skyrim_platform/EventHandler.cpp index 27023716c1..249f5018f6 100644 --- a/skyrim-platform/src/platform_se/skyrim_platform/EventHandler.cpp +++ b/skyrim-platform/src/platform_se/skyrim_platform/EventHandler.cpp @@ -616,19 +616,39 @@ EventResult EventHandler::ProcessEvent( return EventResult::kContinue; } - auto e = CopyEventPtr(event); + uint32_t casterId = + event->caster.get() ? event->caster.get()->GetFormID() : 0; + uint32_t targetId = + event->target.get() ? event->target.get()->GetFormID() : 0; + uint32_t effectId = event->magicEffect; - SkyrimPlatform::GetSingleton()->AddUpdateTask([e] { - auto obj = JsValue::Object(); + SkyrimPlatform::GetSingleton()->AddUpdateTask( + [casterId, targetId, effectId] { + auto obj = JsValue::Object(); - auto effect = RE::TESForm::LookupByID(e->magicEffect); + auto effect = RE::TESForm::LookupByID(effectId); - AddObjProperty(&obj, "effect", effect, "MagicEffect"); - AddObjProperty(&obj, "caster", e->caster.get(), "ObjectReference"); - AddObjProperty(&obj, "target", e->target.get(), "ObjectReference"); + auto casterRefr = RE::TESForm::LookupByID(casterId); + auto targetRefr = RE::TESForm::LookupByID(targetId); - SendEvent("magicEffectApply", obj); - }); + if (!effect) { + return; + } + + if (!casterRefr && casterId != 0) { + return; + } + + if (!targetRefr && targetId != 0) { + return; + } + + AddObjProperty(&obj, "effect", effect, "MagicEffect"); + AddObjProperty(&obj, "caster", casterRefr, "ObjectReference"); + AddObjProperty(&obj, "target", targetRefr, "ObjectReference"); + + SendEvent("magicEffectApply", obj); + }); return EventResult::kContinue; }