Skip to content

Commit b95f1cc

Browse files
authored
Merge pull request #70 from zao/fix/check-url-length
fix: refuse to open overly long URLs
2 parents 47d7686 + 00e0bef commit b95f1cc

File tree

6 files changed

+50
-30
lines changed

6 files changed

+50
-30
lines changed

engine/system/sys_main.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ class find_c {
5050
std::filesystem::directory_iterator iter;
5151
};
5252

53+
std::string GetWineHostVersion();
54+
5355
// ==========
5456
// Interfaces
5557
// ==========
@@ -75,7 +77,7 @@ class sys_IMain {
7577
virtual char* ClipboardPaste() = 0;
7678
virtual bool SetWorkDir(std::filesystem::path const& newCwd = {}) = 0;
7779
virtual void SpawnProcess(std::filesystem::path cmdName, const char* argList) = 0;
78-
virtual void OpenURL(const char* url) = 0;
80+
virtual std::optional<std::string> OpenURL(const char* url) = 0;
7981
virtual void Error(const char* fmt, ...) = 0;
8082
virtual void Exit(const char* msg = NULL) = 0;
8183
virtual void Restart() = 0;

engine/system/win/sys_local.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ class sys_main_c: public sys_IMain {
3737
char* ClipboardPaste();
3838
bool SetWorkDir(std::filesystem::path const& newCwd = {});
3939
void SpawnProcess(std::filesystem::path cmdName, const char* argList);
40-
void OpenURL(const char* url);
40+
std::optional<std::string> OpenURL(const char* url); // return value has failure reason
4141
void Error(const char* fmt, ...);
4242
void Exit(const char* msg = NULL);
4343
void Restart();

engine/system/win/sys_macos.mm

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@
22
#include <CoreFoundation/CFBundle.h>
33
#include <ApplicationServices/ApplicationServices.h>
44

5-
void PlatformOpenURL(const char* textUrl)
5+
const char* PlatformOpenURL(const char* textUrl)
66
{
77
std::string_view urlView = textUrl;
88
CFURLRef url = CFURLCreateWithBytes(nullptr, (const UInt8*)urlView.data(), urlView.size(), kCFStringEncodingUTF8, nullptr);
99
LSOpenCFURLRef(url, nullptr);
1010
CFRelease(url);
11+
return nullptr;
1112
}

engine/system/win/sys_main.cpp

+39-4
Original file line numberDiff line numberDiff line change
@@ -434,23 +434,58 @@ void sys_main_c::SpawnProcess(std::filesystem::path cmdName, const char* argList
434434
#endif
435435
}
436436

437+
std::string GetWineHostVersion()
438+
{
439+
#ifdef _WIN32
440+
using WineHostVersionFun = void(const char** /*sysname*/, const char** /*release*/);
441+
HMODULE mod = GetModuleHandleA("ntdll.dll");
442+
if (!mod)
443+
return "";
444+
auto ptr = GetProcAddress(mod, "wine_get_host_version");
445+
if (!ptr)
446+
return "";
447+
auto fun = (WineHostVersionFun*)ptr;
448+
const char* sysname{};
449+
const char* release{};
450+
fun(&sysname, &release);
451+
return sysname ? sysname : "";
452+
#else
453+
return "";
454+
#endif
455+
}
456+
437457
#if _WIN32 || __linux__
438-
void PlatformOpenURL(const char* url)
458+
const char* PlatformOpenURL(const char* url)
439459
{
440460
#ifdef _WIN32
461+
const std::string wineHost = GetWineHostVersion();
462+
/*
463+
Wine has some loosely determined maximum length on how long of an URL
464+
can be, so we pick a "safe" maximum and refuse to open anything longer.
465+
*/
466+
if ((wineHost == "Linux" || wineHost == "Darwin") && strlen(url) > 1500)
467+
return AllocString("Did not open URL, length likely too long for the OS.");
441468
ShellExecuteA(NULL, "open", url, NULL, NULL, SW_SHOWDEFAULT);
469+
return nullptr;
442470
#else
443471
#warning LV: URL opening not implemented on this OS.
444472
// TODO(LV): Implement URL opening for other OSes.
473+
return AllocString("URL opening not implemented on this OS.");
445474
#endif
446475
}
447476
#else
448-
void PlatformOpenURL(const char* url);
477+
const char* PlatformOpenURL(const char* url);
449478
#endif
450479

451-
void sys_main_c::OpenURL(const char* url)
480+
std::optional<std::string> sys_main_c::OpenURL(const char* url)
452481
{
453-
PlatformOpenURL(url);
482+
if (auto err = PlatformOpenURL(url))
483+
{
484+
std::string ret = err;
485+
FreeString(err);
486+
return ret;
487+
}
488+
return {};
454489
}
455490

456491
// ==============================

engine/system/win/sys_video.cpp

-21
Original file line numberDiff line numberDiff line change
@@ -98,27 +98,6 @@ void sys_IVideo::FreeHandle(sys_IVideo* hnd)
9898
delete (sys_video_c*)hnd;
9999
}
100100

101-
102-
static std::string GetWineHostVersion()
103-
{
104-
#ifdef _WIN32
105-
using WineHostVersionFun = void (const char** /*sysname*/, const char** /*release*/);
106-
HMODULE mod = GetModuleHandleA("ntdll.dll");
107-
if (!mod)
108-
return "";
109-
auto ptr = GetProcAddress(mod, "wine_get_host_version");
110-
if (!ptr)
111-
return "";
112-
auto fun = (WineHostVersionFun*)ptr;
113-
const char* sysname{};
114-
const char* release{};
115-
fun(&sysname, &release);
116-
return sysname ? sysname : "";
117-
#else
118-
return "";
119-
#endif
120-
}
121-
122101
sys_video_c::sys_video_c(sys_IMain* sysHnd)
123102
: sys((sys_main_c*)sysHnd)
124103
{

ui_api.cpp

+5-2
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@
100100
** ConPrintTable(table[, noRecurse])
101101
** ConExecute("<cmd>")
102102
** SpawnProcess("<cmdName>"[, "<args>"])
103-
** OpenURL("<url>")
103+
** err = OpenURL("<url>")
104104
** SetProfiling(isEnabled)
105105
** Restart()
106106
** Exit(["<message>"])
@@ -1906,7 +1906,10 @@ static int l_OpenURL(lua_State* L)
19061906
int n = lua_gettop(L);
19071907
ui->LAssert(L, n >= 1, "Usage: OpenURL(url)");
19081908
ui->LAssert(L, lua_isstring(L, 1), "OpenURL() argument 1: expected string, got %s", luaL_typename(L, 1));
1909-
ui->sys->OpenURL(lua_tostring(L, 1));
1909+
if (auto errMsg = ui->sys->OpenURL(lua_tostring(L, 1))) {
1910+
lua_pushstring(L, errMsg->c_str());
1911+
return 1;
1912+
}
19101913
return 0;
19111914
}
19121915

0 commit comments

Comments
 (0)