From 2f031e131426fa7b11adc322caaa63eac05fbb20 Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Wed, 27 Mar 2024 14:06:16 +0200 Subject: [PATCH 01/11] Post-merge cleanup (settings.xml) --- indra/newview/app_settings/settings.xml | 66 ------------------------- 1 file changed, 66 deletions(-) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 12ddc274ac..af3b33d722 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -2325,28 +2325,6 @@ Value Male Shape & Outfit - DefaultUploadCost - - Comment - Default sound/image/file upload cost(in case economy data is not available). - Persist - 1 - Type - U32 - Value - 10 - - DefaultObjectTexture - - Comment - Texture used as 'Default' in texture picker. (UUID texture reference) - Persist - 1 - Type - String - Value - 89556747-24cb-43ed-920b-47caed15465f - DestinationGuideURL Comment @@ -11624,50 +11602,6 @@ Value 5748decc-f629-461c-9a36-a35a221fe21f - StartUpChannelUUID - - Comment - - Persist - 0 - Type - String - Value - B56AF90D-6684-48E4-B1E4-722D3DEB2CB6 - - NearByChatChannelUUID - - Comment - - Persist - 0 - Type - String - Value - E1158BD6-661C-4981-9DAD-4DCBFF062502 - - NotificationChannelUUID - - Comment - - Persist - 0 - Type - String - Value - AEED3193-8709-4693-8558-7452CCA97AE5 - - AlertChannelUUID - - Comment - - Persist - 0 - Type - String - Value - F3E07BC8-A973-476D-8C7F-F3B7293975D1 - UILineEditorCursorThickness Comment From 977168eda4a3ae22cdd8e50e682dd31c466f306a Mon Sep 17 00:00:00 2001 From: Alexander Gavriliuk Date: Wed, 27 Mar 2024 18:49:18 +0100 Subject: [PATCH 02/11] secondlife/viewer#944 Display should be consistent between llDialog text and llDialog buttons --- indra/llui/lltextbase.cpp | 3 ++ indra/llui/lltextbase.h | 13 ++++--- indra/newview/lltoastnotifypanel.cpp | 36 ++++++++----------- indra/newview/lltoastnotifypanel.h | 22 ++++++------ .../default/xui/en/panel_notification.xml | 16 --------- 5 files changed, 38 insertions(+), 52 deletions(-) diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index feac3400c7..a24f5e830c 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -168,6 +168,7 @@ LLTextBase::Params::Params() trusted_content("trusted_content", true), always_show_icons("always_show_icons", false), use_ellipses("use_ellipses", false), + use_emoji("use_emoji", true), use_color("use_color", true), parse_urls("parse_urls", false), force_urls_external("force_urls_external", false), @@ -227,6 +228,7 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p) mPlainText ( p.plain_text ), mWordWrap(p.wrap), mUseEllipses( p.use_ellipses ), + mUseEmoji(p.use_emoji), mUseColor(p.use_color), mParseHTML(p.parse_urls), mForceUrlsExternal(p.force_urls_external), @@ -903,6 +905,7 @@ S32 LLTextBase::insertStringNoUndo(S32 pos, const LLWString &wstr, LLTextBase::s } // Insert special segments where necessary (insertSegment takes care of splitting normal text segments around them for us) + if (mUseEmoji) { LLStyleSP emoji_style; LLEmojiDictionary* ed = LLEmojiDictionary::instanceExists() ? LLEmojiDictionary::getInstance() : NULL; diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index d65e3bfd7c..dc2e3e7a83 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -328,6 +328,7 @@ public: plain_text, wrap, use_ellipses, + use_emoji, use_color, parse_urls, force_urls_external, @@ -407,12 +408,15 @@ public: virtual void onSpellCheckPerformed(){} // used by LLTextSegment layout code - bool getWordWrap() { return mWordWrap; } - bool getUseEllipses() { return mUseEllipses; } - bool getUseColor() { return mUseColor; } + bool getWordWrap() const { return mWordWrap; } + bool getUseEllipses() const { return mUseEllipses; } + bool getUseEmoji() const { return mUseEmoji; } + void setUseEmoji(bool value) { mUseEmoji = value; } + bool getUseColor() const { return mUseColor; } + void setUseColor(bool value) { mUseColor = value; } bool truncate(); // returns true of truncation occurred - bool isContentTrusted() {return mTrustedContent;} + bool isContentTrusted() const { return mTrustedContent; } void setContentTrusted(bool trusted_content) { mTrustedContent = trusted_content; } // TODO: move into LLTextSegment? @@ -715,6 +719,7 @@ protected: bool mParseHighlights; // highlight user-defined keywords bool mWordWrap; bool mUseEllipses; + bool mUseEmoji; bool mUseColor; bool mTrackEnd; // if true, keeps scroll position at end of document during resize bool mReadOnly; diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp index bf3f4c1e88..9db4bc4d3f 100644 --- a/indra/newview/lltoastnotifypanel.cpp +++ b/indra/newview/lltoastnotifypanel.cpp @@ -50,8 +50,8 @@ S32 BUTTON_WIDTH = 90; //static -const LLFontGL* LLToastNotifyPanel::sFont = NULL; -const LLFontGL* LLToastNotifyPanel::sFontSmall = NULL; +const std::string LLToastNotifyPanel::sFontDefault("Emoji"); +const std::string LLToastNotifyPanel::sFontScript("SansSerif"); LLToastNotifyPanel::button_click_signal_t LLToastNotifyPanel::sButtonClickSignal; @@ -85,11 +85,15 @@ LLButton* LLToastNotifyPanel::createButton(const LLSD& form_element, BOOL is_opt mBtnCallbackData.push_back(userdata); LLButton::Params p; - bool make_small_btn = form_element["index"].asInteger() == -1 || form_element["index"].asInteger() == -2; - const LLFontGL* font = make_small_btn ? sFontSmall: sFont; // for block and ignore buttons in script dialog - p.name = form_element["name"].asString(); - p.label = form_element["text"].asString(); - p.tool_tip = form_element["text"].asString(); + S32 index = form_element["index"].asInteger(); + std::string name = form_element["name"].asString(); + std::string text = form_element["text"].asString(); + bool make_small_btn = index == -1 || index == -2; // for block and ignore buttons in script dialog + const LLFontGL* font = LLFontGL::getFont(LLFontDescriptor( + mIsScriptDialog ? sFontScript : sFontDefault, make_small_btn ? "Small" : "Medium", 0)); + p.name = name; + p.label = text; + p.tool_tip = text; p.font = font; p.rect.height = BTN_HEIGHT; p.click_callback.function(boost::bind(&LLToastNotifyPanel::onClickButton, userdata)); @@ -256,19 +260,12 @@ void LLToastNotifyPanel::init( LLRect rect, bool show_images ) { deleteAllChildren(); - mTextBox = NULL; - mInfoPanel = NULL; - mControlPanel = NULL; - mNumOptions = 0; - mNumButtons = 0; - mAddedDefaultBtn = false; - LLRect current_rect = getRect(); setXMLFilename(""); buildFromFile("panel_notification.xml"); - if(rect != LLRect::null) + if (rect != LLRect::null) { this->setShape(rect); } @@ -295,12 +292,6 @@ void LLToastNotifyPanel::init( LLRect rect, bool show_images ) // setup parameters // get a notification message mMessage = mNotification->getMessage(); - // init font variables - if (!sFont) - { - sFont = LLFontGL::getFontSansSerif(); - sFontSmall = LLFontGL::getFontSansSerifSmall(); - } // initialize setFocusRoot(!mIsTip); // get a form for the notification @@ -318,15 +309,18 @@ void LLToastNotifyPanel::init( LLRect rect, bool show_images ) if (mIsCaution && !mIsTip) { mTextBox = getChild("caution_text_box"); + mTextBox->setFont(LLFontGL::getFont(LLFontDescriptor(mIsScriptDialog ? sFontScript : sFontDefault, "Medium", LLFontGL::BOLD))); } else { mTextBox = getChild("text_editor_box"); + mTextBox->setFont(LLFontGL::getFont(LLFontDescriptor(mIsScriptDialog ? sFontScript : sFontDefault, "Medium", 0))); } mTextBox->setMaxTextLength(LLToastPanel::MAX_TEXT_LENGTH); mTextBox->setVisible(TRUE); mTextBox->setPlainText(!show_images); + mTextBox->setUseEmoji(!mIsScriptDialog); mTextBox->setContentTrusted(is_content_trusted); mTextBox->setValue(mNotification->getMessage()); mTextBox->setIsFriendCallback(LLAvatarActions::isFriend); diff --git a/indra/newview/lltoastnotifypanel.h b/indra/newview/lltoastnotifypanel.h index a5a637c6fa..4a6c2ada8a 100644 --- a/indra/newview/lltoastnotifypanel.h +++ b/indra/newview/lltoastnotifypanel.h @@ -102,9 +102,9 @@ protected: //std::vector mButtons; // panel elements - LLTextBase* mTextBox; - LLPanel* mInfoPanel; // a panel, that contains an information - LLPanel* mControlPanel; // a panel, that contains buttons (if present) + LLTextBase* mTextBox { nullptr }; + LLPanel* mInfoPanel { nullptr }; // panel for text information + LLPanel* mControlPanel { nullptr }; // panel for buttons (if present) // internal handler for button being clicked static void onClickButton(void* data); @@ -124,17 +124,17 @@ protected: */ //void disableRespondedOptions(const LLNotificationPtr& notification); - bool mIsTip; - bool mAddedDefaultBtn; - bool mIsScriptDialog; - bool mIsCaution; + bool mIsTip { false }; + bool mAddedDefaultBtn { false }; + bool mIsScriptDialog { false }; + bool mIsCaution { false }; std::string mMessage; - S32 mNumOptions; - S32 mNumButtons; + S32 mNumOptions { 0 }; + S32 mNumButtons { 0 }; - static const LLFontGL* sFont; - static const LLFontGL* sFontSmall; + static const std::string sFontDefault; + static const std::string sFontScript; }; class LLIMToastNotifyPanel : public LLToastNotifyPanel diff --git a/indra/newview/skins/default/xui/en/panel_notification.xml b/indra/newview/skins/default/xui/en/panel_notification.xml index e962c1449a..3ddf525d16 100644 --- a/indra/newview/skins/default/xui/en/panel_notification.xml +++ b/indra/newview/skins/default/xui/en/panel_notification.xml @@ -32,21 +32,6 @@ - Date: Wed, 27 Mar 2024 22:49:56 +0200 Subject: [PATCH 03/11] viewer#1069 Crash after getting list of notification files --- indra/llui/llnotifications.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index 25062f2cad..1ccd664022 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -1547,6 +1547,11 @@ bool LLNotifications::loadTemplates() // specific skin. std::vector search_paths = gDirUtilp->findSkinnedFilenames(LLDir::XUI, "notifications.xml", LLDir::ALL_SKINS); + if (search_paths.empty()) + { + LLError::LLUserWarningMsg::show(LLTrans::getString("MBMissingFile")); + LL_ERRS() << "Problem finding notifications.xml" << LL_ENDL; + } std::string base_filename = search_paths.front(); LLXMLNodePtr root; From 50a70fe2f831c6d34a6f518ae040e52ac2f9f924 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 28 Mar 2024 00:45:38 +0200 Subject: [PATCH 04/11] viewer#1073 crash at loadSkeleton looks like file that was being parced got corrupted 'in progress' --- indra/llcommon/llsys.cpp | 4 ++++ indra/newview/llinventorymodel.cpp | 13 ++++++++++++- indra/newview/llstartup.cpp | 4 +++- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp index 938685bae6..352628f129 100644 --- a/indra/llcommon/llsys.cpp +++ b/indra/llcommon/llsys.cpp @@ -1352,6 +1352,10 @@ BOOL gunzip_file(const std::string& srcfile, const std::string& dstfile) } while(gzeof(src) == 0); fclose(dst); dst = NULL; +#if LL_WINDOWS + // Rename in windows needs the dstfile to not exist. + LLFile::remove(dstfile, ENOENT); +#endif if (LLFile::rename(tmpfile, dstfile) == -1) goto err; /* Flawfinder: ignore */ retval = TRUE; err: diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index eebc79c1c6..10feb16346 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -2705,6 +2705,17 @@ bool LLInventoryModel::loadSkeleton( gzip_filename.append(".gz"); LLFILE* fp = LLFile::fopen(gzip_filename, "rb"); bool remove_inventory_file = false; + if (LLAppViewer::instance()->isSecondInstance()) + { + // Safeguard viewer against trying to unpack file twice + // ex: user logs into two accounts simultaneously, so two + // viewers are trying to unpack library into same file + // + // Would be better to do it in gunzip_file, but it doesn't + // have access to llfilesystem + inventory_filename = gDirUtilp->getTempFilename(); + remove_inventory_file = true; + } if(fp) { fclose(fp); @@ -2913,7 +2924,7 @@ bool LLInventoryModel::loadSkeleton( // clean up the gunzipped file. LLFile::remove(inventory_filename); } - if(is_cache_obsolete) + if(is_cache_obsolete && !LLAppViewer::instance()->isSecondInstance()) { // If out of date, remove the gzipped file too. LL_WARNS(LOG_INV) << "Inv cache out of date, removing" << LL_ENDL; diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index f30810fb81..6799f8cfdd 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -2951,7 +2951,9 @@ std::string LLStartUp::startupStateToString(EStartupState state) RTNENUM( STATE_AGENT_SEND ); RTNENUM( STATE_AGENT_WAIT ); RTNENUM( STATE_INVENTORY_SEND ); - RTNENUM(STATE_INVENTORY_CALLBACKS ); + RTNENUM( STATE_INVENTORY_CALLBACKS ); + RTNENUM( STATE_INVENTORY_SKEL ); + RTNENUM( STATE_INVENTORY_SEND2 ); RTNENUM( STATE_MISC ); RTNENUM( STATE_PRECACHE ); RTNENUM( STATE_WEARABLES_WAIT ); From 2b1e372f760c8dd7510418e1c2362804b7c854b3 Mon Sep 17 00:00:00 2001 From: Bennett Goble Date: Sat, 30 Mar 2024 21:21:55 -0700 Subject: [PATCH 05/11] Remove BuildParams This file is no longer used. --- BuildParams | 73 ----------------------------------------------------- build.sh | 3 --- 2 files changed, 76 deletions(-) delete mode 100644 BuildParams diff --git a/BuildParams b/BuildParams deleted file mode 100644 index dda25e3e63..0000000000 --- a/BuildParams +++ /dev/null @@ -1,73 +0,0 @@ -# BuildParams -# -# Please refer to: -# https://wiki.secondlife.com/wiki/Automated_Build_System - -# Variants (NOTE: 'Release' must be last for uploads to work correctly) -variants = "RelWithDebInfo Release" - -# Use Public Upload Locations -public_build = true -build_docs = true - -# enable Doxygen building on Linux for TeamCity (it can be done manually on any platform) -build_Linux_Doxygen = true - -# Need viewer-build-variables as well as other shared repositories -buildscripts_shared_more_NAMEs="build_secrets build_variables git_hooks" - -# Python 3 / SL-15742 -BUILDSCRIPTS_PY3 = "true" - -################################################################ -#### Examples of how to set the viewer_channel #### -# -# To build a Release or Release candidate in build bingo: -# bingo.viewer_channel = "Second Life Release" -# -# To build a Beta for the 'Bingo' project in build bingo: -# bingo.viewer_channel = "Second Life Beta Bingo" -# -# To build a Project viewer for the 'Bingo' project in build bingo: -# bingo.viewer_channel = "Second Life Project Bingo" -# -# If left unset, viewer_channel defaults to 'Second Life Test', -# which is appropriate for individual developer builds. -# -# All Linden Lab builds (and only Linden Lab builds) -# should use a viewer_channel that begins with "Second Life" -################################################################ -viewer_channel = "Second Life Test" - - -################################################################ -# Special packaging parameters. -# These parameters can be used to create additional packages -# which identify themselves in a distinct way with either -# a sourceid (sent to web services) or a channel name (sent to login) -# the default sourceid should always be a null string: -sourceid = "" -# the additional_packages variable is a blank separated list of package prefixes: -# additional_packages = "" -# to set the special values for a package, create variables using each prefix: -# additional_packages = "Foo Bar" -# Foo_sourceid = "bingo" -# Foo_viewer_channel_suffix = "Foo" -# Bar_sourceid = "bongo" -# Bar_viewer_channel_suffix = "Bar" -# the viewer_channel_suffix is prefixed by a blank and then appended to the viewer_channel -# for the package in a setting that overrides the compiled-in value -################################################################ -additional_packages = "EDU" -Linux.additional_packages = "" - -# The EDU package allows us to create a separate release channel whose expirations -# are synchronized as much as possible with the academic year -EDU_sourceid = "" -EDU_viewer_channel_suffix = "edu" - -# Notifications - to configure email notices use the TeamCity parameter -# setting screen for your project or build configuration to set the -# environment variable 'email' to a space-separated list of email addresses -email="" - diff --git a/build.sh b/build.sh index f7b3632ee8..fe795a24ee 100755 --- a/build.sh +++ b/build.sh @@ -6,9 +6,6 @@ # it relies on the environment that sets up, functions it provides, and # the build result post-processing it does. # -# The shared buildscript build.sh invokes this because it is named 'build.sh', -# which is the default custom build script name in buildscripts/hg/BuildParams -# # PLEASE NOTE: # # * This script is interpreted on three platforms, including windows and cygwin From 4c7a139e0970b15557bd1347477d572c3b5da7e9 Mon Sep 17 00:00:00 2001 From: Henri Beauchamp Date: Mon, 26 Feb 2024 11:34:56 +0100 Subject: [PATCH 06/11] Fix the bogus, zero cloud scroll rate in default EE sky settings. Obvioulsy, there has been a typo done when copying WL default sky parameters to EE ones. This causes "static" and quite unrealistic clouds when this default setting is used as a base for a new sky setting, and we see this bad static sky resurfacing now with PBR and its "adjusted" (more like hacked, but this is another story) mid-day sky setting. Let's fix this typo once and for all in LL's code base (most TPVs have it fixed already, and this ever since EEP got released). @LL: please also fix the cloud scroll rate in the PBR mid-day inventory setting accordingly. --- indra/llinventory/llsettingssky.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/llinventory/llsettingssky.cpp b/indra/llinventory/llsettingssky.cpp index c3cd7262fb..f606709558 100644 --- a/indra/llinventory/llsettingssky.cpp +++ b/indra/llinventory/llsettingssky.cpp @@ -729,7 +729,7 @@ LLSD LLSettingsSky::defaults(const LLSettingsBase::TrackPosition& position) dfltsetting[SETTING_CLOUD_POS_DENSITY1] = LLColor4(1.0000, 0.5260, 1.0000, 0.0).getValue(); dfltsetting[SETTING_CLOUD_POS_DENSITY2] = LLColor4(1.0000, 0.5260, 1.0000, 0.0).getValue(); dfltsetting[SETTING_CLOUD_SCALE] = LLSD::Real(0.4199); - dfltsetting[SETTING_CLOUD_SCROLL_RATE] = llsd::array(0.0f, 0.0f); + dfltsetting[SETTING_CLOUD_SCROLL_RATE] = llsd::array(0.2, 0.01); dfltsetting[SETTING_CLOUD_SHADOW] = LLSD::Real(0.2699); dfltsetting[SETTING_CLOUD_VARIANCE] = LLSD::Real(0.0); From 1ad53b9707438e1676446b26e06bca77cff2e5ad Mon Sep 17 00:00:00 2001 From: Alexander Gavriliuk Date: Tue, 2 Apr 2024 04:23:54 +0200 Subject: [PATCH 07/11] secondlife/viewer#925 Missing simple :smile emoji --- indra/newview/llfloateremojipicker.cpp | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/indra/newview/llfloateremojipicker.cpp b/indra/newview/llfloateremojipicker.cpp index 1fc5740532..51b31a72ca 100644 --- a/indra/newview/llfloateremojipicker.cpp +++ b/indra/newview/llfloateremojipicker.cpp @@ -489,10 +489,12 @@ void LLFloaterEmojiPicker::fillCategoryRecentlyUsed(std::mapsecond->ShortCodes.empty()) { - const std::string shortcode(e2d->second->ShortCodes.front()); - if (LLEmojiDictionary::searchInShortCode(begin, end, shortcode, mFilterPattern)) + for (const std::string& shortcode : e2d->second->ShortCodes) { - emojis.emplace_back(emoji, shortcode, begin, end); + if (LLEmojiDictionary::searchInShortCode(begin, end, shortcode, mFilterPattern)) + { + emojis.emplace_back(emoji, shortcode, begin, end); + } } } } @@ -521,10 +523,12 @@ void LLFloaterEmojiPicker::fillCategoryFrequentlyUsed(std::mapsecond->ShortCodes.empty()) { - const std::string shortcode(e2d->second->ShortCodes.front()); - if (LLEmojiDictionary::searchInShortCode(begin, end, shortcode, mFilterPattern)) + for (const std::string& shortcode : e2d->second->ShortCodes) { - emojis.emplace_back(emoji.first, shortcode, begin, end); + if (LLEmojiDictionary::searchInShortCode(begin, end, shortcode, mFilterPattern)) + { + emojis.emplace_back(emoji.first, shortcode, begin, end); + } } } } @@ -557,10 +561,12 @@ void LLFloaterEmojiPicker::fillGroupEmojis(std::mapShortCodes.empty()) { - const std::string shortcode(descr->ShortCodes.front()); - if (LLEmojiDictionary::searchInShortCode(begin, end, shortcode, mFilterPattern)) + for (const std::string& shortcode : descr->ShortCodes) { - emojis.emplace_back(descr->Character, shortcode, begin, end); + if (LLEmojiDictionary::searchInShortCode(begin, end, shortcode, mFilterPattern)) + { + emojis.emplace_back(descr->Character, shortcode, begin, end); + } } } } From 00e09ddcad8ec2c33ecbcdd0da09bd7819bc3509 Mon Sep 17 00:00:00 2001 From: Salad Dais Date: Thu, 9 Nov 2023 15:41:08 +0000 Subject: [PATCH 08/11] Fix BUG-225288: Detaching stops unrelated animations This is to do with misunderstandings related to how .find() works with multimaps. .find() will, in fact, return an iterator to the first iterator it finds, and will iterate through all elements in the multimap when incremented, not just items with the same key. Change code working with animation sources to be aware of this fact, so unrelated animation sources do not have their animations stopped. --- indra/newview/llviewermessage.cpp | 6 ++++++ indra/newview/llvoavatarself.cpp | 6 +++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 0ee5b8f454..b41d1d9712 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -4166,6 +4166,12 @@ void process_avatar_animation(LLMessageSystem *mesgsys, void **user_data) LLVOAvatar::AnimSourceIterator anim_it = avatarp->mAnimationSources.find(object_id); for (;anim_it != avatarp->mAnimationSources.end(); ++anim_it) { + if (anim_it->first != object_id) + { + // elements with the same key are always contiguous, bail if we went past the + // end of this object's animations + break; + } if (anim_it->second == animation_id) { anim_found = TRUE; diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 7b24b9ee02..f12fc3babc 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -834,7 +834,11 @@ void LLVOAvatarSelf::stopMotionFromSource(const LLUUID& source_id) for (AnimSourceIterator motion_it = mAnimationSources.find(source_id); motion_it != mAnimationSources.end(); ) { gAgent.sendAnimationRequest(motion_it->second, ANIM_REQUEST_STOP); - mAnimationSources.erase(motion_it++); + mAnimationSources.erase(motion_it); + // Must find() after each erase() to deal with potential iterator invalidation + // This also ensures that we don't go past the end of this source's animations + // into those of another source. + motion_it = mAnimationSources.find(source_id); } From 72d46037bd03dfcdf7f3804bb70a8cff86107a2a Mon Sep 17 00:00:00 2001 From: Bennett Goble Date: Wed, 10 Apr 2024 21:21:09 -0700 Subject: [PATCH 09/11] Remove unused fix-incredibuild.py --- indra/fix-incredibuild.py | 61 --------------------------------------- 1 file changed, 61 deletions(-) delete mode 100755 indra/fix-incredibuild.py diff --git a/indra/fix-incredibuild.py b/indra/fix-incredibuild.py deleted file mode 100755 index 678ee4329e..0000000000 --- a/indra/fix-incredibuild.py +++ /dev/null @@ -1,61 +0,0 @@ -#!/usr/bin/env python3 -## -## $LicenseInfo:firstyear=2011&license=viewerlgpl$ -## Second Life Viewer Source Code -## Copyright (C) 2011, Linden Research, Inc. -## -## This library is free software; you can redistribute it and/or -## modify it under the terms of the GNU Lesser General Public -## License as published by the Free Software Foundation; -## version 2.1 of the License only. -## -## This library is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public -## License along with this library; if not, write to the Free Software -## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -## -## Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA -## $/LicenseInfo$ - -import sys -import os -import glob - -def delete_file_types(path, filetypes): - if os.path.exists(path): - print('Cleaning: ' + path) - orig_dir = os.getcwd(); - os.chdir(path) - filelist = [] - for type in filetypes: - filelist.extend(glob.glob(type)) - for file in filelist: - os.remove(file) - os.chdir(orig_dir) - -def main(): - build_types = ['*.exp','*.exe','*.pdb','*.idb', - '*.ilk','*.lib','*.obj','*.ib_pdb_index'] - pch_types = ['*.pch'] - delete_file_types("build-vc80/newview/Release", build_types) - delete_file_types("build-vc80/newview/secondlife-bin.dir/Release/", - pch_types) - delete_file_types("build-vc80/newview/RelWithDebInfo", build_types) - delete_file_types("build-vc80/newview/secondlife-bin.dir/RelWithDebInfo/", - pch_types) - delete_file_types("build-vc80/newview/Debug", build_types) - delete_file_types("build-vc80/newview/secondlife-bin.dir/Debug/", - pch_types) - - - delete_file_types("build-vc80/test/RelWithDebInfo", build_types) - delete_file_types("build-vc80/test/test.dir/RelWithDebInfo/", - pch_types) - - -if __name__ == "__main__": - main() From 7fa24d636e42c19baf8a9a6fc4bf9b554dca0e3a Mon Sep 17 00:00:00 2001 From: Bennett Goble Date: Thu, 11 Apr 2024 00:16:17 -0700 Subject: [PATCH 10/11] CI: Remove python-version from matrix Drop python version from matrix configuration as it's always 3.11. --- .github/workflows/build.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index ddb0f44150..f18b31ef0f 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -13,7 +13,6 @@ jobs: matrix: runner: [windows-large, macos-12-xl] configuration: [Release, ReleaseOS] - python-version: ["3.11"] include: - runner: macos-12-xl developer_dir: "/Applications/Xcode_14.0.1.app/Contents/Developer" @@ -67,7 +66,7 @@ jobs: - name: Setup python uses: actions/setup-python@v5 with: - python-version: ${{ matrix.python-version }} + python-version: "3.11" - name: Checkout build variables uses: actions/checkout@v4 From f5a7fba76a24a96f906abcbd928f37e4eabfa76c Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 12 Apr 2024 02:03:49 +0300 Subject: [PATCH 11/11] viewer-private#226 Unhandled PngError throws application into a loop png_read_info triggered a PngError, LLAppViewer::frame() handled it instead of LLPngWrapper::readPng, and since status didn't change viewer tried to decode image again and again and again. --- indra/llimage/llimagepng.cpp | 56 +++++++---- indra/llimage/llpngwrapper.cpp | 7 ++ indra/newview/llfloaterimagepreview.cpp | 96 ++++++++++--------- indra/newview/llviewertexturelist.cpp | 122 +++++++++++++----------- indra/newview/llviewertexturelist.h | 2 +- 5 files changed, 161 insertions(+), 122 deletions(-) diff --git a/indra/llimage/llimagepng.cpp b/indra/llimage/llimagepng.cpp index c4b98d8260..19c160e402 100644 --- a/indra/llimage/llimagepng.cpp +++ b/indra/llimage/llimagepng.cpp @@ -27,6 +27,7 @@ #include "linden_common.h" #include "stdtypes.h" #include "llerror.h" +#include "llexception.h" #include "llimage.h" #include "llpngwrapper.h" @@ -51,29 +52,44 @@ bool LLImagePNG::updateData() { resetLastError(); - // Check to make sure that this instance has been initialized with data - if (!getData() || (0 == getDataSize())) + try { - setLastError("Uninitialized instance of LLImagePNG"); + // Check to make sure that this instance has been initialized with data + if (!getData() || (0 == getDataSize())) + { + setLastError("Uninitialized instance of LLImagePNG"); + return false; + } + + // Decode the PNG data and extract sizing information + LLPngWrapper pngWrapper; + if (!pngWrapper.isValidPng(getData())) + { + setLastError("LLImagePNG data does not have a valid PNG header!"); + return false; + } + + LLPngWrapper::ImageInfo infop; + if (!pngWrapper.readPng(getData(), getDataSize(), NULL, &infop)) + { + setLastError(pngWrapper.getErrorMessage()); + return false; + } + + setSize(infop.mWidth, infop.mHeight, infop.mComponents); + } + catch (const LLContinueError& msg) + { + setLastError(msg.what()); + LOG_UNHANDLED_EXCEPTION(""); + return false; + } + catch (...) + { + setLastError("LLImagePNG"); + LOG_UNHANDLED_EXCEPTION(""); return false; } - - // Decode the PNG data and extract sizing information - LLPngWrapper pngWrapper; - if (!pngWrapper.isValidPng(getData())) - { - setLastError("LLImagePNG data does not have a valid PNG header!"); - return false; - } - - LLPngWrapper::ImageInfo infop; - if (! pngWrapper.readPng(getData(), getDataSize(), NULL, &infop)) - { - setLastError(pngWrapper.getErrorMessage()); - return false; - } - - setSize(infop.mWidth, infop.mHeight, infop.mComponents); return true; } diff --git a/indra/llimage/llpngwrapper.cpp b/indra/llimage/llpngwrapper.cpp index cad7c00042..55d867728f 100644 --- a/indra/llimage/llpngwrapper.cpp +++ b/indra/llimage/llpngwrapper.cpp @@ -216,6 +216,13 @@ BOOL LLPngWrapper::readPng(U8* src, S32 dataSize, LLImageRaw* rawImage, ImageInf releaseResources(); return (FALSE); } + catch (...) + { + mErrorMessage = "LLPngWrapper"; + releaseResources(); + LOG_UNHANDLED_EXCEPTION(""); + return (FALSE); + } // Clean up and return releaseResources(); diff --git a/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp index ba0f97e2e1..6da1481c7e 100644 --- a/indra/newview/llfloaterimagepreview.cpp +++ b/indra/newview/llfloaterimagepreview.cpp @@ -332,54 +332,62 @@ void LLFloaterImagePreview::draw() //----------------------------------------------------------------------------- bool LLFloaterImagePreview::loadImage(const std::string& src_filename) { - std::string exten = gDirUtilp->getExtension(src_filename); - U32 codec = LLImageBase::getCodecFromExtension(exten); + try + { + std::string exten = gDirUtilp->getExtension(src_filename); + U32 codec = LLImageBase::getCodecFromExtension(exten); - LLImageDimensionsInfo image_info; - if (!image_info.load(src_filename,codec)) - { - mImageLoadError = image_info.getLastError(); - return false; - } + LLImageDimensionsInfo image_info; + if (!image_info.load(src_filename, codec)) + { + mImageLoadError = image_info.getLastError(); + return false; + } - S32 max_width = gSavedSettings.getS32("max_texture_dimension_X"); - S32 max_height = gSavedSettings.getS32("max_texture_dimension_Y"); + S32 max_width = gSavedSettings.getS32("max_texture_dimension_X"); + S32 max_height = gSavedSettings.getS32("max_texture_dimension_Y"); - if ((image_info.getWidth() > max_width) || (image_info.getHeight() > max_height)) - { - LLStringUtil::format_map_t args; - args["WIDTH"] = llformat("%d", max_width); - args["HEIGHT"] = llformat("%d", max_height); + if ((image_info.getWidth() > max_width) || (image_info.getHeight() > max_height)) + { + LLStringUtil::format_map_t args; + args["WIDTH"] = llformat("%d", max_width); + args["HEIGHT"] = llformat("%d", max_height); - mImageLoadError = LLTrans::getString("texture_load_dimensions_error", args); - return false; - } - - // Load the image - LLPointer image = LLImageFormatted::createFromType(codec); - if (image.isNull()) - { - return false; - } - if (!image->load(src_filename)) - { - return false; - } - // Decompress or expand it in a raw image structure - LLPointer raw_image = new LLImageRaw; - if (!image->decode(raw_image, 0.0f)) - { - return false; - } - // Check the image constraints - if ((image->getComponents() != 3) && (image->getComponents() != 4)) - { - image->setLastError("Image files with less than 3 or more than 4 components are not supported."); - return false; - } - - raw_image->biasedScaleToPowerOfTwo(1024); - mRawImagep = raw_image; + mImageLoadError = LLTrans::getString("texture_load_dimensions_error", args); + return false; + } + + // Load the image + LLPointer image = LLImageFormatted::createFromType(codec); + if (image.isNull()) + { + return false; + } + if (!image->load(src_filename)) + { + return false; + } + // Decompress or expand it in a raw image structure + LLPointer raw_image = new LLImageRaw; + if (!image->decode(raw_image, 0.0f)) + { + return false; + } + // Check the image constraints + if ((image->getComponents() != 3) && (image->getComponents() != 4)) + { + image->setLastError("Image files with less than 3 or more than 4 components are not supported."); + return false; + } + + raw_image->biasedScaleToPowerOfTwo(1024); + mRawImagep = raw_image; + } + catch (...) + { + LOG_UNHANDLED_EXCEPTION(""); + return false; + } return true; } diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 971d3c4363..ccfaad2b15 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -1297,7 +1297,7 @@ bool LLViewerTextureList::createUploadFile(LLPointer raw_image, return true; } -BOOL LLViewerTextureList::createUploadFile(const std::string& filename, +bool LLViewerTextureList::createUploadFile(const std::string& filename, const std::string& out_filename, const U8 codec, const S32 max_image_dimentions, @@ -1305,64 +1305,72 @@ BOOL LLViewerTextureList::createUploadFile(const std::string& filename, bool force_square) { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; - // Load the image - LLPointer image = LLImageFormatted::createFromType(codec); - if (image.isNull()) - { - LL_WARNS() << "Couldn't open the image to be uploaded." << LL_ENDL; - return FALSE; - } - if (!image->load(filename)) - { - image->setLastError("Couldn't load the image to be uploaded."); - return FALSE; - } - // Decompress or expand it in a raw image structure - LLPointer raw_image = new LLImageRaw; - if (!image->decode(raw_image, 0.0f)) - { - image->setLastError("Couldn't decode the image to be uploaded."); - return FALSE; - } - // Check the image constraints - if ((image->getComponents() != 3) && (image->getComponents() != 4)) - { - image->setLastError("Image files with less than 3 or more than 4 components are not supported."); - return FALSE; - } - if (image->getWidth() < min_image_dimentions || image->getHeight() < min_image_dimentions) + try { - std::string reason = llformat("Images below %d x %d pixels are not allowed. Actual size: %d x %dpx", - min_image_dimentions, - min_image_dimentions, - image->getWidth(), - image->getHeight()); - image->setLastError(reason); - return FALSE; + // Load the image + LLPointer image = LLImageFormatted::createFromType(codec); + if (image.isNull()) + { + LL_WARNS() << "Couldn't open the image to be uploaded." << LL_ENDL; + return false; + } + if (!image->load(filename)) + { + image->setLastError("Couldn't load the image to be uploaded."); + return false; + } + // Decompress or expand it in a raw image structure + LLPointer raw_image = new LLImageRaw; + if (!image->decode(raw_image, 0.0f)) + { + image->setLastError("Couldn't decode the image to be uploaded."); + return false; + } + // Check the image constraints + if ((image->getComponents() != 3) && (image->getComponents() != 4)) + { + image->setLastError("Image files with less than 3 or more than 4 components are not supported."); + return false; + } + if (image->getWidth() < min_image_dimentions || image->getHeight() < min_image_dimentions) + { + std::string reason = llformat("Images below %d x %d pixels are not allowed. Actual size: %d x %dpx", + min_image_dimentions, + min_image_dimentions, + image->getWidth(), + image->getHeight()); + image->setLastError(reason); + return false; + } + // Convert to j2c (JPEG2000) and save the file locally + LLPointer compressedImage = convertToUploadFile(raw_image, max_image_dimentions, force_square); + if (compressedImage.isNull()) + { + image->setLastError("Couldn't convert the image to jpeg2000."); + LL_INFOS() << "Couldn't convert to j2c, file : " << filename << LL_ENDL; + return false; + } + if (!compressedImage->save(out_filename)) + { + image->setLastError("Couldn't create the jpeg2000 image for upload."); + LL_INFOS() << "Couldn't create output file : " << out_filename << LL_ENDL; + return false; + } + // Test to see if the encode and save worked + LLPointer integrity_test = new LLImageJ2C; + if (!integrity_test->loadAndValidate(out_filename)) + { + image->setLastError("The created jpeg2000 image is corrupt."); + LL_INFOS() << "Image file : " << out_filename << " is corrupt" << LL_ENDL; + return false; + } } - // Convert to j2c (JPEG2000) and save the file locally - LLPointer compressedImage = convertToUploadFile(raw_image, max_image_dimentions, force_square); - if (compressedImage.isNull()) - { - image->setLastError("Couldn't convert the image to jpeg2000."); - LL_INFOS() << "Couldn't convert to j2c, file : " << filename << LL_ENDL; - return FALSE; - } - if (!compressedImage->save(out_filename)) - { - image->setLastError("Couldn't create the jpeg2000 image for upload."); - LL_INFOS() << "Couldn't create output file : " << out_filename << LL_ENDL; - return FALSE; - } - // Test to see if the encode and save worked - LLPointer integrity_test = new LLImageJ2C; - if (!integrity_test->loadAndValidate( out_filename )) - { - image->setLastError("The created jpeg2000 image is corrupt."); - LL_INFOS() << "Image file : " << out_filename << " is corrupt" << LL_ENDL; - return FALSE; - } - return TRUE; + catch (...) + { + LOG_UNHANDLED_EXCEPTION(""); + return false; + } + return true; } // note: modifies the argument raw_image!!!! diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h index 10a2cfa32a..04d3309f86 100644 --- a/indra/newview/llviewertexturelist.h +++ b/indra/newview/llviewertexturelist.h @@ -96,7 +96,7 @@ public: const std::string& out_filename, const S32 max_image_dimentions = LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT, const S32 min_image_dimentions = 0); - static BOOL createUploadFile(const std::string& filename, + static bool createUploadFile(const std::string& filename, const std::string& out_filename, const U8 codec, const S32 max_image_dimentions = LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT,