diff options
author | Andrey Kleshchev <andreykproductengine@lindenlab.com> | 2024-02-09 23:06:55 +0200 |
---|---|---|
committer | Andrey Kleshchev <117672381+akleshchev@users.noreply.github.com> | 2024-02-10 00:27:28 +0200 |
commit | b8952923ac2564f85b83da6893f89a6a45c952fd (patch) | |
tree | c790f920ab9c89b60576a6abb19a094adc54061f /indra | |
parent | c8ee05a2712e56a7cdcb2b9e25c8b092c088d4d4 (diff) |
Triage Issue #49 Better inspection of data urls in media
Diffstat (limited to 'indra')
-rw-r--r-- | indra/llcommon/llbase64.cpp | 16 | ||||
-rw-r--r-- | indra/llcommon/llbase64.h | 1 | ||||
-rw-r--r-- | indra/newview/llpanelnearbymedia.cpp | 83 | ||||
-rw-r--r-- | indra/newview/llpanelnearbymedia.h | 3 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/menu_nearby_media.xml | 14 |
5 files changed, 101 insertions, 16 deletions
diff --git a/indra/llcommon/llbase64.cpp b/indra/llcommon/llbase64.cpp index bb85fe32a3..6591e9b49a 100644 --- a/indra/llcommon/llbase64.cpp +++ b/indra/llcommon/llbase64.cpp @@ -59,3 +59,19 @@ std::string LLBase64::encode(const U8* input, size_t input_size) return output; } +std::string LLBase64::decodeAsString(const std::string &input) +{ + int b64_buffer_length = apr_base64_decode_len(input.c_str()); + char* b64_buffer = new char[b64_buffer_length]; + + // This is faster than apr_base64_encode() if you know + // you're not on an EBCDIC machine. Also, the output is + // null terminated, even though the documentation doesn't + // specify. See apr_base64.c for details. JC + b64_buffer_length = apr_base64_decode(b64_buffer, input.c_str()); + std::string res; + res.assign(b64_buffer); + delete[] b64_buffer; + return res; +} + diff --git a/indra/llcommon/llbase64.h b/indra/llcommon/llbase64.h index 16d2c217d0..b985963fc4 100644 --- a/indra/llcommon/llbase64.h +++ b/indra/llcommon/llbase64.h @@ -32,6 +32,7 @@ class LL_COMMON_API LLBase64 { public: static std::string encode(const U8* input, size_t input_size); + static std::string decodeAsString(const std::string& input); }; #endif diff --git a/indra/newview/llpanelnearbymedia.cpp b/indra/newview/llpanelnearbymedia.cpp index c911f102a1..83f0fca1be 100644 --- a/indra/newview/llpanelnearbymedia.cpp +++ b/indra/newview/llpanelnearbymedia.cpp @@ -29,6 +29,7 @@ #include "llpanelnearbymedia.h" #include "llaudioengine.h" +#include "llbase64.h" #include "llcheckboxctrl.h" #include "llclipboard.h" #include "llcombobox.h" @@ -107,6 +108,11 @@ LLPanelNearByMedia::LLPanelNearByMedia() { onMenuAction(data); }); + mEnableCallbackRegistrar.add("SelectedMediaCtrl.Visible", + [this](LLUICtrl* ctrl, const LLSD& data) + { + return onMenuVisible(data); + }); buildFromFile( "panel_nearby_media.xml"); } @@ -270,6 +276,16 @@ BOOL LLPanelNearByMedia::handleRightMouseDown(S32 x, S32 y, MASK mask) return LLPanelPulldown::handleRightMouseDown(x, y, mask); } + +void LLPanelNearByMedia::onVisibilityChange(BOOL new_visibility) +{ + if (!new_visibility && mContextMenu->getVisible()) + { + gMenuHolder->hideMenus(); + } + LLPanelPulldown::onVisibilityChange(new_visibility); +} + bool LLPanelNearByMedia::getParcelAudioAutoStart() { return mParcelAudioAutoStart; @@ -1213,34 +1229,49 @@ void LLPanelNearByMedia::onClickSelectedMediaUnzoom() void LLPanelNearByMedia::onMenuAction(const LLSD& userdata) { const std::string command_name = userdata.asString(); - if ("copy" == command_name) + if ("copy_url" == command_name) { LLClipboard::instance().reset(); - LLUUID selected_media_id = mMediaList->getValue().asUUID(); - std::string url; + std::string url = getSelectedUrl(); - if (selected_media_id == PARCEL_AUDIO_LIST_ITEM_UUID) + if (!url.empty()) { - url = LLViewerMedia::getInstance()->getParcelAudioURL(); + LLClipboard::instance().copyToClipboard(utf8str_to_wstring(url), 0, url.size()); } - else if (selected_media_id == PARCEL_MEDIA_LIST_ITEM_UUID) + } + else if ("copy_data" == command_name) + { + LLClipboard::instance().reset(); + std::string url = getSelectedUrl(); + static const std::string encoding_specifier = "base64,"; + size_t pos = url.find(encoding_specifier); + if (pos != std::string::npos) { - url = LLViewerParcelMedia::getInstance()->getURL(); + pos += encoding_specifier.size(); + std::string res = LLBase64::decodeAsString(url.substr(pos)); + LLClipboard::instance().copyToClipboard(utf8str_to_wstring(res), 0, res.size()); } else { - LLViewerMediaImpl* impl = LLViewerMedia::getInstance()->getMediaImplFromTextureID(selected_media_id); - if (NULL != impl) - { - url = impl->getCurrentMediaURL(); - } + url = LLURI::unescape(url); + LLClipboard::instance().copyToClipboard(utf8str_to_wstring(url), 0, url.size()); } + } +} - if (!url.empty()) +bool LLPanelNearByMedia::onMenuVisible(const LLSD& userdata) +{ + const std::string command_name = userdata.asString(); + if ("copy_data" == command_name) + { + std::string url = getSelectedUrl(); + if (url.rfind("data:", 0) == 0) { - LLClipboard::instance().copyToClipboard(utf8str_to_wstring(url), 0, url.size()); + // might be a a good idea to permit text/html only + return true; } } + return false; } // static @@ -1268,3 +1299,27 @@ void LLPanelNearByMedia::getNameAndUrlHelper(LLViewerMediaImpl* impl, std::strin } } +std::string LLPanelNearByMedia::getSelectedUrl() +{ + std::string url; + LLUUID selected_media_id = mMediaList->getValue().asUUID(); + if (selected_media_id == PARCEL_AUDIO_LIST_ITEM_UUID) + { + url = LLViewerMedia::getInstance()->getParcelAudioURL(); + } + else if (selected_media_id == PARCEL_MEDIA_LIST_ITEM_UUID) + { + url = LLViewerParcelMedia::getInstance()->getURL(); + } + else + { + LLViewerMediaImpl* impl = LLViewerMedia::getInstance()->getMediaImplFromTextureID(selected_media_id); + if (NULL != impl) + { + std::string name; + getNameAndUrlHelper(impl, name, url, mEmptyNameString); + } + } + return url; +} + diff --git a/indra/newview/llpanelnearbymedia.h b/indra/newview/llpanelnearbymedia.h index 7239a80043..5e04ad4d86 100644 --- a/indra/newview/llpanelnearbymedia.h +++ b/indra/newview/llpanelnearbymedia.h @@ -49,6 +49,7 @@ public: void reshape(S32 width, S32 height, BOOL called_from_parent) override; BOOL handleHover(S32 x, S32 y, MASK mask) override; BOOL handleRightMouseDown(S32 x, S32 y, MASK mask) override; + void onVisibilityChange(BOOL new_visibility) override; // this is part of the nearby media *dialog* so we can track whether // the user *implicitly* wants audio on or off via their *explicit* @@ -123,6 +124,7 @@ private: bool setDisabled(const LLUUID &id, bool disabled); static void getNameAndUrlHelper(LLViewerMediaImpl* impl, std::string& name, std::string & url, const std::string &defaultName); + std::string getSelectedUrl(); void updateColumns(); @@ -141,6 +143,7 @@ private: void onClickSelectedMediaZoom(); void onClickSelectedMediaUnzoom(); void onMenuAction(const LLSD& userdata); + bool onMenuVisible(const LLSD& userdata); LLUICtrl* mNearbyMediaPanel; LLScrollListCtrl* mMediaList; diff --git a/indra/newview/skins/default/xui/en/menu_nearby_media.xml b/indra/newview/skins/default/xui/en/menu_nearby_media.xml index 11a5dfa5fa..7c91241a19 100644 --- a/indra/newview/skins/default/xui/en/menu_nearby_media.xml +++ b/indra/newview/skins/default/xui/en/menu_nearby_media.xml @@ -7,9 +7,19 @@ mouse_opaque="false"> <menu_item_call label="Copy Url" - name="copy"> + name="copy_url"> <menu_item_call.on_click function="SelectedMediaCtrl.Action" - parameter="copy" /> + parameter="copy_url" /> + </menu_item_call> + <menu_item_call + label="Copy Data" + name="copy_data"> + <menu_item_call.on_click + function="SelectedMediaCtrl.Action" + parameter="copy_data" /> + <menu_item_call.on_visible + function="SelectedMediaCtrl.Visible" + parameter="copy_data" /> </menu_item_call> </toggleable_menu> |