From a2b59ce6f77725c99df2f4d36d2b0463bc28fd9e Mon Sep 17 00:00:00 2001 From: chanayane Date: Mon, 12 May 2025 00:49:25 +0200 Subject: [PATCH] fix potential crashes in AO panel when double-clicking (should fix FIRE-35293) --- indra/newview/ao.cpp | 56 ++++++++++++++++++++++++++++++++------ indra/newview/aoengine.cpp | 27 +++++++++++++----- 2 files changed, 68 insertions(+), 15 deletions(-) diff --git a/indra/newview/ao.cpp b/indra/newview/ao.cpp index f0fb99875f..f3b3e390f7 100644 --- a/indra/newview/ao.cpp +++ b/indra/newview/ao.cpp @@ -871,8 +871,23 @@ void FloaterAO::onAnimationChanged(const LLUUID& animation) if (mCurrentBoldItem) { - ((LLScrollListIcon*)mCurrentBoldItem->getColumn(0))->setValue("FSAO_Animation_Stopped"); - ((LLScrollListText*)mCurrentBoldItem->getColumn(1))->setFontStyle(LLFontGL::NORMAL); +// Safer casts + if (LLScrollListCell* icon_cell = mCurrentBoldItem->getColumn(0)) + { + if (LLScrollListIcon* icon = dynamic_cast(icon_cell)) + { + icon->setValue("FSAO_Animation_Stopped"); + } + } + + if (LLScrollListCell* text_cell = mCurrentBoldItem->getColumn(1)) + { + if (LLScrollListText* text = dynamic_cast(text_cell)) + { + text->setFontStyle(LLFontGL::NORMAL); + } + } +// mCurrentBoldItem = nullptr; } @@ -882,21 +897,46 @@ void FloaterAO::onAnimationChanged(const LLUUID& animation) return; } - // why do we have no LLScrollListCtrl::getItemByUserdata() ? -Zi - for (auto item : mAnimationList->getAllData()) +// Fix potential nullptr + if (!mAnimationList) { - LLUUID* id = (LLUUID*)item->getUserdata(); + LL_WARNS("AO") << "Animation list control is null." << LL_ENDL; + return; + } +// - if (id == &animation) +// Safer casts + // why do we have no LLScrollListCtrl::getItemByUserdata() ? -Zi + for (LLScrollListItem* item : mAnimationList->getAllData()) + { + LLUUID* id = static_cast(item->getUserdata()); + // compares the LLUUID values instead of pointer values + //if (id == &animation) + if (id && *id == animation) + // { mCurrentBoldItem = item; - ((LLScrollListIcon*)mCurrentBoldItem->getColumn(0))->setValue("FSAO_Animation_Playing"); - ((LLScrollListText*)mCurrentBoldItem->getColumn(1))->setFontStyle(LLFontGL::BOLD); + if (LLScrollListCell* icon_cell = mCurrentBoldItem->getColumn(0)) + { + if (LLScrollListIcon* icon = dynamic_cast(icon_cell)) + { + icon->setValue("FSAO_Animation_Playing"); + } + } + + if (LLScrollListCell* text_cell = mCurrentBoldItem->getColumn(1)) + { + if (LLScrollListText* text = dynamic_cast(text_cell)) + { + text->setFontStyle(LLFontGL::BOLD); + } + } return; } } +// } // virtual diff --git a/indra/newview/aoengine.cpp b/indra/newview/aoengine.cpp index 677097427d..19b53d3ba1 100644 --- a/indra/newview/aoengine.cpp +++ b/indra/newview/aoengine.cpp @@ -1014,12 +1014,21 @@ void AOEngine::playAnimation(const LLUUID& animation) // if we can find the original animation already right here, save its asset ID, otherwise this will // be tried again in AOSet::getAnimationForState() and/or AOEngine::cycle() + LLUUID newAnimation; if (item->getLinkedItem()) { - anim.mAssetUUID = item->getAssetUUID(); + newAnimation = item->getAssetUUID(); + //anim.mAssetUUID = item->getAssetUUID(); } - LLUUID newAnimation = anim.mAssetUUID; + if (newAnimation.isNull()) + { + LL_WARNS("AOEngine") << "New animation UUID is null for animation " << animation << LL_ENDL; + return; + } + anim.mAssetUUID = newAnimation; + + //LLUUID newAnimation = anim.mAssetUUID; LLUUID oldAnimation = state->mCurrentAnimationID; // don't do anything if the animation didn't change @@ -1031,7 +1040,7 @@ void AOEngine::playAnimation(const LLUUID& animation) mAnimationChangedSignal(LLUUID::null); // Searches for the index of the animation - U32 idx = -1; + S32 idx = -1; for (U32 i = 0; i < state->mAnimations.size(); i++) { if (state->mAnimations[i].mAssetUUID == newAnimation) @@ -1040,18 +1049,22 @@ void AOEngine::playAnimation(const LLUUID& animation) break; } } - if (idx < 0) + if (idx == -1) { - idx = 0; + LL_WARNS("AOEngine") << "Animation index not found for animation " << animation << LL_ENDL; + return; } - state->mCurrentAnimation = idx; + state->mCurrentAnimation = static_cast(idx); state->mCurrentAnimationID = newAnimation; if (newAnimation.notNull()) { LL_DEBUGS("AOEngine") << "requesting animation start for motion " << gAnimLibrary.animationName(mLastMotion) << ": " << newAnimation << LL_ENDL; gAgent.sendAnimationRequest(newAnimation, ANIM_REQUEST_START); - mAnimationChangedSignal(state->mAnimations[state->mCurrentAnimation].mInventoryUUID); + if (state->mCurrentAnimation < state->mAnimations.size()) + { + mAnimationChangedSignal(state->mAnimations[state->mCurrentAnimation].mInventoryUUID); + } } else {