diff options
| author | Saikari <[email protected]> | 2026-01-28 22:49:00 +0300 |
|---|---|---|
| committer | Saikari <[email protected]> | 2026-01-28 22:49:00 +0300 |
| commit | fdc2242b8aca146cf963ec5c1214d4da17f921cf (patch) | |
| tree | ea33b786ed9089cee0dba1fbdc06711de984429b | |
| parent | a45f1db67258d65543be7f6272e7fe994a3c354c (diff) | |
Enhance os.isexec function to include .exe extension checks and streamline PE header validation for Windows executables
| -rw-r--r-- | tests/modules/io/test.lua | 48 | ||||
| -rw-r--r-- | xmake/core/base/os.lua | 62 |
2 files changed, 50 insertions, 60 deletions
diff --git a/tests/modules/io/test.lua b/tests/modules/io/test.lua index 2b8bad8bf..341908a4e 100644 --- a/tests/modules/io/test.lua +++ b/tests/modules/io/test.lua @@ -160,3 +160,51 @@ function test_convert(t) os.tryrm("temp") end + +function test_parse_pe(t) + local workdir = path.join(os.tmpdir(), "xmake_test_parse_pe") + os.tryrm(workdir) + os.mkdir(workdir) + + -- create a local repository + local repodir = path.join(workdir, "repo") + local pkgdir = path.join(repodir, "packages", "p", "putty_test") + os.mkdir(pkgdir) + + io.writefile(path.join(pkgdir, "xmake.lua"), [[ +package("putty_test") + set_kind("binary") + add_urls("https://the.earth.li/~sgtatham/putty/$(version)/w64/putty.zip") + add_versions("0.83", "9a4376156971c17896fdb80b550b6f1c1dffd7bac40de5d7b16e774bad49cf76") + on_install(function (package) + os.cp("PUTTY.EXE", package:installdir("bin")) + end) +]]) + + -- create a project to install it + local projdir = path.join(workdir, "proj") + os.mkdir(projdir) + io.writefile(path.join(projdir, "xmake.lua"), string.format([[ +add_repositories("myrepo %s") +add_requires("putty_test") +target("test") + set_kind("phony") +]], repodir:gsub("\\", "/"))) + + -- install package using a custom install directory + local installdir = path.join(workdir, "packages") + local envs = {XMAKE_PKG_INSTALLDIR = installdir} + local out, err = os.iorunv("xmake", {"require", "-y", "putty_test"}, {curdir = projdir, envs = envs}) + + -- find the installed executable + local files = os.files(path.join(installdir, "p", "putty_test", "*", "*", "bin", "PUTTY.EXE")) + if #files > 0 then + local file_x64 = files[1] + local info = io.parse_pe(file_x64) + t:are_equal(info.arch, "x64") + else + t:fail("putty_test not installed. output:\n" .. out .. "\n" .. err) + end + + os.tryrm(workdir) +end diff --git a/xmake/core/base/os.lua b/xmake/core/base/os.lua index 28e9ad968..3ea77c9a9 100644 --- a/xmake/core/base/os.lua +++ b/xmake/core/base/os.lua @@ -1158,77 +1158,19 @@ function os.isexec(filepath) if os.isfile(filepath) then if os.host() == "windows" then local ext = path.extension(filepath):lower() - if ext == ".cmd" or ext == ".bat" or ext == ".ps1" then + if ext == ".exe" or ext == ".cmd" or ext == ".bat" or ext == ".ps1" then return true end - -- check for PE header - local peinfo = io.parse_pe(filepath) - if peinfo then - local pe_arch = peinfo.arch - -- x86 - if pe_arch == "x86" and os.is_arch("x86_64", "i686") then - return true - else - return false - end - -- x64 - if pe_arch == "x64" and os.is_arch("x86_64") then - return true - else - return false - end - -- arm64 - if pe_arch == "arm64" and os.is_arch("arm64") then - return true - else - return false - end - -- arm32 - if pe_arch == "arm" and os.is_arch("arm.*") then - return true - else - return false - end - end else return os._access(filepath, "x") end end if os.host() == "windows" then - for _, suffix in ipairs({".cmd", ".bat", ".ps1"}) do + for _, suffix in ipairs({".exe", ".cmd", ".bat", ".ps1"}) do if os.isfile(filepath .. suffix) then return true end end - -- check for PE header - local peinfo = io.parse_pe(filepath .. ".exe") - if peinfo then - local pe_arch = peinfo.arch - -- x86 - if pe_arch == "x86" and os.is_arch("x86_64", "i686") then - return true - else - return false - end - -- x64 - if pe_arch == "x64" and os.is_arch("x86_64") then - return true - else - return false - end - -- arm64 - if pe_arch == "arm64" and os.is_arch("arm64") then - return true - else - return false - end - -- arm32 - if pe_arch == "arm" and os.is_arch("arm.*") then - return true - else - return false - end - end end return false end |
