summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorAndrey Kleshchev <andreykproductengine@lindenlab.com>2024-02-09 23:06:55 +0200
committerAndrey Kleshchev <117672381+akleshchev@users.noreply.github.com>2024-02-10 00:27:28 +0200
commitb8952923ac2564f85b83da6893f89a6a45c952fd (patch)
treec790f920ab9c89b60576a6abb19a094adc54061f /indra
parentc8ee05a2712e56a7cdcb2b9e25c8b092c088d4d4 (diff)
Triage Issue #49 Better inspection of data urls in media
Diffstat (limited to 'indra')
-rw-r--r--indra/llcommon/llbase64.cpp16
-rw-r--r--indra/llcommon/llbase64.h1
-rw-r--r--indra/newview/llpanelnearbymedia.cpp83
-rw-r--r--indra/newview/llpanelnearbymedia.h3
-rw-r--r--indra/newview/skins/default/xui/en/menu_nearby_media.xml14
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>