From 0f817847d6d06d7caa1f4642ba271420f4bf0c2d Mon Sep 17 00:00:00 2001 From: vaisest <4550061+vaisest@users.noreply.github.com> Date: Fri, 14 Aug 2026 19:36:37 +0300 Subject: [PATCH 1/2] Restrict Wine PlatformOpenURL() path to ver 8.16 --- engine/system/sys_main.h | 2 +- engine/system/win/sys_main.cpp | 49 ++++++++++++++++++++++++--------- engine/system/win/sys_video.cpp | 2 +- 3 files changed, 38 insertions(+), 15 deletions(-) diff --git a/engine/system/sys_main.h b/engine/system/sys_main.h index 5d83fc78..e2ffb447 100644 --- a/engine/system/sys_main.h +++ b/engine/system/sys_main.h @@ -50,7 +50,7 @@ class find_c { std::filesystem::directory_iterator iter; }; -std::string GetWineHostVersion(); +std::tuple GetWineHostVersion(); // ========== // Interfaces diff --git a/engine/system/win/sys_main.cpp b/engine/system/win/sys_main.cpp index 3078e0d8..d91f0cde 100644 --- a/engine/system/win/sys_main.cpp +++ b/engine/system/win/sys_main.cpp @@ -434,23 +434,39 @@ void sys_main_c::SpawnProcess(std::filesystem::path cmdName, const char* argList #endif } -std::string GetWineHostVersion() +// get wine host OS type and x.y.z format version of wine +std::tuple GetWineHostVersion() { #ifdef _WIN32 using WineHostVersionFun = void(const char** /*sysname*/, const char** /*release*/); + using WineVersionFun = char *(); HMODULE mod = GetModuleHandleA("ntdll.dll"); if (!mod) - return ""; + return {"", ""}; auto ptr = GetProcAddress(mod, "wine_get_host_version"); if (!ptr) - return ""; + return {"", ""}; + auto verPtr = GetProcAddress(mod, "wine_get_version"); + if (!verPtr) + return {"", ""}; auto fun = (WineHostVersionFun*)ptr; const char* sysname{}; const char* release{}; fun(&sysname, &release); - return sysname ? sysname : ""; + + auto verFun = (WineVersionFun *)verPtr; + // version in x.y.z format + const char *version = verFun(); + if (sysname && version) + { + return {sysname, version}; + } + else + { + return {"", ""}; + } #else - return ""; + return {"", ""}; #endif } @@ -458,14 +474,21 @@ std::string GetWineHostVersion() const char* PlatformOpenURL(const char* url) { #ifdef _WIN32 - const std::string wineHost = GetWineHostVersion(); - /* - Wine has some loosely determined maximum length on how long of an URL - can be, so we pick a "safe" maximum and refuse to open anything longer. - */ - if ((wineHost == "Linux" || wineHost == "Darwin") && strlen(url) > 1500) - return AllocString("Did not open URL, length likely too long for the OS."); - ShellExecuteA(NULL, "open", url, NULL, NULL, SW_SHOWDEFAULT); + auto [wineHost, wineVersion] = GetWineHostVersion(); + int major = INT_MAX; + int minor = INT_MAX; + auto match = RE2::PartialMatch(wineVersion, "^(\\d+)\\.(\\d+)", &major, &minor); + // work around a pre-8.17 wine bug where long urls may cause a stack corruption and overflow + bool invalidVersion = (major < 8) || (major == 8 && minor < 17); + if ((wineHost == "Linux" || wineHost == "Darwin") && strlen(url) > 1500 && invalidVersion) + { + return AllocString("Did not open URL, length likely too long for pre-8.17 Wine versions."); + } + auto retVal = (INT_PTR)ShellExecuteA(NULL, "open", url, NULL, NULL, SW_SHOWDEFAULT); + if (retVal) + { + return AllocString("Opening URL failed."); + } return nullptr; #else #warning LV: URL opening not implemented on this OS. diff --git a/engine/system/win/sys_video.cpp b/engine/system/win/sys_video.cpp index 6f61bffb..f8963d11 100644 --- a/engine/system/win/sys_video.cpp +++ b/engine/system/win/sys_video.cpp @@ -108,7 +108,7 @@ sys_video_c::sys_video_c(sys_IMain* sysHnd) int platformType = GLFW_ANGLE_PLATFORM_TYPE_NONE; #ifdef _WIN32 - const std::string wineHost = GetWineHostVersion(); + auto [wineHost, _] = GetWineHostVersion(); if (wineHost == "Linux") platformType = GLFW_ANGLE_PLATFORM_TYPE_OPENGL; else if (wineHost == "Darwin") From 5c4578433c83ffe6300b2deee745743e7ec88122 Mon Sep 17 00:00:00 2001 From: vaisest <4550061+vaisest@users.noreply.github.com> Date: Sat, 15 Aug 2026 08:49:05 +0300 Subject: [PATCH 2/2] Fix shellexecute value handling --- engine/system/win/sys_main.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/engine/system/win/sys_main.cpp b/engine/system/win/sys_main.cpp index d91f0cde..67600e1d 100644 --- a/engine/system/win/sys_main.cpp +++ b/engine/system/win/sys_main.cpp @@ -485,7 +485,8 @@ const char* PlatformOpenURL(const char* url) return AllocString("Did not open URL, length likely too long for pre-8.17 Wine versions."); } auto retVal = (INT_PTR)ShellExecuteA(NULL, "open", url, NULL, NULL, SW_SHOWDEFAULT); - if (retVal) + // "If the function succeeds, it returns a value greater than 32" + if (retVal <= 32) { return AllocString("Opening URL failed."); }