From 99059c57027c3f0927c0800309d910d6c4c86e72 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev <117672381+akleshchev@users.noreply.github.com> Date: Tue, 11 Aug 2026 23:29:11 +0300 Subject: p#648 Fix recursive folder pasting --- indra/newview/llinventorybridge.cpp | 11 +++++++++++ indra/newview/skins/default/xui/en/notifications.xml | 11 +++++++++++ 2 files changed, 22 insertions(+) diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 8e4e70474f..58ca1da032 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -4136,6 +4136,17 @@ void LLFolderBridge::perform_pasteFromClipboard() } else { + // Check that no folder is being pasted into itself or into one of its descendants + for (const LLUUID& item_id : objects) + { + LLInventoryCategory* cat = model->getCategory(item_id); + if (cat && (item_id == mUUID || model->isObjectDescendentOf(mUUID, item_id))) + { + LLNotificationsUtil::add("CannotPasteFolderIntoSelf"); + return; + } + } + // Check that all items can be moved into that folder : for the moment, only stock folder mismatch is checked for (std::vector::const_iterator iter = objects.begin(); iter != objects.end(); ++iter) { diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 42ec875bcd..833a09eab8 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -424,6 +424,17 @@ Initialization with the Marketplace failed because of a system or network error. yestext="OK"/> + + You cannot paste a folder into itself or into one of its subfolders. + fail + + + Date: Wed, 12 Aug 2026 20:03:27 +0300 Subject: #6113 Crash at LLViewerMedia::updateMedia --- indra/newview/llviewermedia.cpp | 51 ++++++++++++----------------------------- 1 file changed, 15 insertions(+), 36 deletions(-) diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index be4961e3c4..28dd62792c 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -560,55 +560,34 @@ LLViewerMedia::impl_list &LLViewerMedia::getPriorityList() // This is the predicate function used to sort sViewerMediaImplList by priority. bool LLViewerMedia::priorityComparitor(const LLViewerMediaImpl* i1, const LLViewerMediaImpl* i2) { - if(i1->isForcedUnloaded() && !i2->isForcedUnloaded()) + // isForcedUnloaded can be pricey, avoid a repeat, + // note that this one is specifically i2, when everything else is i1 + // Consider making isForcedUnloaded cache the value temporarily? + bool i2_forced_unloaded = i2->isForcedUnloaded(); + if (i1->isForcedUnloaded() != i2_forced_unloaded) { // Muted or failed items always go to the end of the list, period. - return false; - } - else if(i2->isForcedUnloaded() && !i1->isForcedUnloaded()) - { - // Muted or failed items always go to the end of the list, period. - return true; - } - else if(i1->hasFocus()) - { - // The item with user focus always comes to the front of the list, period. - return true; + return i2_forced_unloaded; } - else if(i2->hasFocus()) + else if(i1->hasFocus() != i2->hasFocus()) { // The item with user focus always comes to the front of the list, period. - return false; - } - else if(i1->isParcelMedia()) - { - // The parcel media impl sorts above all other inworld media, unless one has focus. - return true; + return i1->hasFocus(); } - else if(i2->isParcelMedia()) + else if(i1->isParcelMedia() != i2->isParcelMedia()) { // The parcel media impl sorts above all other inworld media, unless one has focus. - return false; - } - else if(i1->getUsedInUI() && !i2->getUsedInUI()) - { - // i1 is a UI element, i2 is not. This makes i1 "less than" i2, so it sorts earlier in our list. - return true; + return i1->isParcelMedia(); } - else if(i2->getUsedInUI() && !i1->getUsedInUI()) + else if (i1->getUsedInUI() != i2->getUsedInUI()) { - // i2 is a UI element, i1 is not. This makes i2 "less than" i1, so it sorts earlier in our list. - return false; - } - else if(i1->isPlayable() && !i2->isPlayable()) - { - // Playable items sort above ones that wouldn't play even if they got high enough priority - return true; + // UI elements sort above inworld media. + return i1->getUsedInUI(); } - else if(!i1->isPlayable() && i2->isPlayable()) + else if (i1->isPlayable() != i2->isPlayable()) { // Playable items sort above ones that wouldn't play even if they got high enough priority - return false; + return i1->isPlayable(); } else if(i1->getInterest() == i2->getInterest()) { -- cgit v1.3