From 35b4ed60cbe3104fab3c4e821286ef72ee45f3a1 Mon Sep 17 00:00:00 2001
From: Rye Mutt <rye@alchemyviewer.org>
Date: Sun, 15 Mar 2020 02:04:44 -0400
Subject: [PATCH] Fix leak of menu in LLScrollListCtrl

---
 indra/llui/llscrolllistctrl.cpp | 30 +++++++++++++++++++++---------
 indra/llui/llscrolllistctrl.h   |  2 +-
 2 files changed, 22 insertions(+), 10 deletions(-)

diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index 6c8fde580f6..924573b4d35 100644
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -174,7 +174,6 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p)
 	mHighlightedItem(-1),
 	mBorder(NULL),
 	mSortCallback(NULL),
-	mPopupMenu(NULL),
 	mCommentTextView(NULL),
 	mNumDynamicWidthColumns(0),
 	mTotalStaticColumnWidth(0),
@@ -319,12 +318,19 @@ bool LLScrollListCtrl::preProcessChildNode(LLXMLNodePtr child)
 LLScrollListCtrl::~LLScrollListCtrl()
 {
 	delete mSortCallback;
+	delete mIsFriendSignal;
 
 	std::for_each(mItemList.begin(), mItemList.end(), DeletePointer());
 	mItemList.clear();
 	std::for_each(mColumns.begin(), mColumns.end(), DeletePairedPointer());
 	mColumns.clear();
-	delete mIsFriendSignal;
+	auto menu = mPopupMenuHandle.get();
+	if (menu)
+	{
+		menu->die();
+		mPopupMenuHandle.markDead();
+	}
+
 }
 
 
@@ -1846,17 +1852,23 @@ BOOL LLScrollListCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
 
 			// create the context menu from the XUI file and display it
 			std::string menu_name = is_group ? "menu_url_group.xml" : "menu_url_agent.xml";
-			delete mPopupMenu;
+			auto menu = mPopupMenuHandle.get();
+			if (menu)
+			{
+				menu->die();
+				mPopupMenuHandle.markDead();
+			}
 			llassert(LLMenuGL::sMenuContainer != NULL);
-			mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>(
+			menu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>(
 				menu_name, LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instance());
-			if (mPopupMenu)
+			if (menu)
 			{
+				mPopupMenuHandle = menu->getHandle();
 				if (mIsFriendSignal)
 				{
 					bool isFriend = *(*mIsFriendSignal)(uuid);
-					LLView* addFriendButton = mPopupMenu->getChild<LLView>("add_friend");
-					LLView* removeFriendButton = mPopupMenu->getChild<LLView>("remove_friend");
+					LLView* addFriendButton = menu->getChild<LLView>("add_friend");
+					LLView* removeFriendButton = menu->getChild<LLView>("remove_friend");
 
 					if (addFriendButton && removeFriendButton)
 					{
@@ -1865,8 +1877,8 @@ BOOL LLScrollListCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
 					}
 				}
 
-				mPopupMenu->show(x, y);
-				LLMenuGL::showPopup(this, mPopupMenu, x, y);
+				menu->show(x, y);
+				LLMenuGL::showPopup(this, menu, x, y);
 				return TRUE;
 			}
 		}
diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h
index d7572d9fcf6..92396f5c41c 100644
--- a/indra/llui/llscrolllistctrl.h
+++ b/indra/llui/llscrolllistctrl.h
@@ -490,7 +490,7 @@ class LLScrollListCtrl : public LLUICtrl, public LLEditMenuHandler,
 
 	S32				mHighlightedItem;
 	class LLViewBorder*	mBorder;
-	LLContextMenu	*mPopupMenu;
+	LLHandle<LLContextMenu>	mPopupMenuHandle;
 	
 	LLView			*mCommentTextView;
 
-- 
GitLab