diff options
author | Thorbjørn Lindeijer <bjorn@lindeijer.nl> | 2025-07-10 17:11:07 +0200 |
---|---|---|
committer | Thorbjørn Lindeijer <bjorn@lindeijer.nl> | 2025-07-11 20:50:41 +0200 |
commit | e09248620ad430fbbd907dab5e54fe96fd69baa9 (patch) | |
tree | baf1508e7bfa076069311177bd06260d74bfc029 | |
parent | 6b89b661df1a2682edfa491e1bb9a21c4ab0943c (diff) | |
download | mana-master.tar.gz mana-master.tar.bz2 mana-master.tar.xz mana-master.zip |
Some security checks are done because players might also write
"screenshot:" in the chat to create file:// URLs and `SDL_OpenURL` can
be used to open many things. So we disallow ".." and require a ".png"
extension.
-rw-r--r-- | NEWS | 1 | ||||
-rw-r--r-- | src/game.cpp | 10 | ||||
-rw-r--r-- | src/gui/widgets/itemlinkhandler.cpp | 19 | ||||
-rw-r--r-- | src/utils/stringutils.h | 13 |
4 files changed, 40 insertions, 3 deletions
@@ -36,6 +36,7 @@ - Enabled whispers in tabs by default - Made pickup notifications to appear as particle instead of text by default - Made names update immediately when changing "Show gender" option +- Made the screenshot file name a clickable link - Made client config statically typed and save as more structured XML - Custom mouse cursor is now rendered by the system - Limit shop's Max button to available carry weight diff --git a/src/game.cpp b/src/game.cpp index b91df9db..86a943d8 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -325,8 +325,16 @@ static bool saveScreenshot() if (success) { + std::string screenshotLink; +#if SDL_VERSION_ATLEAST(2, 0, 14) + screenshotLink = strprintf("@@screenshot:%s|%s@@", + filenameSuffix.str().c_str(), + filenameSuffix.str().c_str()); +#else + screenshotLink = filenameSuffix.str(); +#endif serverNotice(strprintf(_("Screenshot saved as %s"), - filenameSuffix.str().c_str())); + screenshotLink.c_str())); } else { diff --git a/src/gui/widgets/itemlinkhandler.cpp b/src/gui/widgets/itemlinkhandler.cpp index 81a332ad..d9d6f506 100644 --- a/src/gui/widgets/itemlinkhandler.cpp +++ b/src/gui/widgets/itemlinkhandler.cpp @@ -33,6 +33,7 @@ #include "gui/widgets/itemlinkhandler.h" +#include "client.h" #include "resources/iteminfo.h" #include "resources/itemdb.h" #include "utils/gettext.h" @@ -56,6 +57,24 @@ static bool isUrl(const std::string &link) void ItemLinkHandler::handleLink(const std::string &link) { +#if SDL_VERSION_ATLEAST(2, 0, 14) + // Handle screenshots by constructing full file path + if (startsWith(link, "screenshot:")) + { + std::string filename = link.substr(11); // Remove "screenshot:" prefix + + // Prevent directory traversal attacks or opening malicious files + if (filename.find("..") == std::string::npos && endsWith(filename, ".png")) + { + std::string fileUrl = "file://" + Client::getScreenshotDirectory() + "/" + filename; + if (SDL_OpenURL(fileUrl.c_str()) == -1) + new OkDialog(_("Open URL Failed"), SDL_GetError(), true, mParent); + } + + return; + } +#endif + if (isUrl(link)) { mLink = link; diff --git a/src/utils/stringutils.h b/src/utils/stringutils.h index 8dd4454a..885ddcb8 100644 --- a/src/utils/stringutils.h +++ b/src/utils/stringutils.h @@ -117,9 +117,18 @@ std::string &removeColors(std::string &msg); /** * Returns whether a string starts with a given prefix. */ -inline bool startsWith(const std::string &str, const char *prefix) +inline bool startsWith(std::string_view str, std::string_view prefix) { - return str.rfind(prefix, 0) == 0; + return str.substr(0, prefix.size()) == prefix; +} + +/** + * Returns whether a string ends with a given suffix. + */ +inline bool endsWith(std::string_view str, std::string_view suffix) +{ + return str.size() >= suffix.size() && + str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0; } /** |