diff --git a/engine/render/r_texture.cpp b/engine/render/r_texture.cpp index d79b767e..c2ef1839 100644 --- a/engine/render/r_texture.cpp +++ b/engine/render/r_texture.cpp @@ -307,12 +307,12 @@ r_tex_c::r_tex_c(r_ITexManager* manager, std::string_view fileName, int flags) } } -r_tex_c::r_tex_c(r_ITexManager* manager, std::unique_ptr img, int flags) +r_tex_c::r_tex_c(r_ITexManager* manager, std::unique_ptr newImg, int flags) { Init(manager, {}, flags); - // Direct upload - img = BuildMipSet(std::move(img)); + // Direct upload. + img = BuildMipSet(std::move(newImg)); PerformUpload(this); } 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 e35c03c8..b1513c4f 100644 --- a/engine/system/win/sys_main.cpp +++ b/engine/system/win/sys_main.cpp @@ -457,23 +457,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 } @@ -481,14 +497,22 @@ 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 the function succeeds, it returns a value greater than 32" + if (retVal <= 32) + { + 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 39cac5bc..60d125c0 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")