Triage Issue #49 Better inspection of data urls in media

master
Andrey Kleshchev 2024-02-09 23:06:55 +02:00 committed by Andrey Kleshchev
parent c8ee05a271
commit b8952923ac
5 changed files with 107 additions and 22 deletions

View File

@ -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;
}

View File

@ -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

View File

@ -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;
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)
{
url = impl->getCurrentMediaURL();
}
}
std::string url = getSelectedUrl();
if (!url.empty())
{
LLClipboard::instance().copyToClipboard(utf8str_to_wstring(url), 0, url.size());
}
}
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)
{
pos += encoding_specifier.size();
std::string res = LLBase64::decodeAsString(url.substr(pos));
LLClipboard::instance().copyToClipboard(utf8str_to_wstring(res), 0, res.size());
}
else
{
url = LLURI::unescape(url);
LLClipboard::instance().copyToClipboard(utf8str_to_wstring(url), 0, url.size());
}
}
}
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)
{
// 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;
}

View File

@ -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;

View File

@ -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>