summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSaikari <[email protected]>2026-07-10 05:01:39 +0300
committerSaikari <[email protected]>2026-07-10 05:01:39 +0300
commit2567b4e41ba9b0f508e34e307b5816045d15e3b4 (patch)
treeaa1c2c96907861165faa77d7b2745d1798eb605b
parent3a0b131873815ff3c2d4d133885f1e691823e945 (diff)
fix: avoid stack buffer overflow for long paths in path translation
-rw-r--r--core/src/xmake/path/translate.c25
-rw-r--r--xmake/modules/private/service/remote_build/filesync.lua5
2 files changed, 27 insertions, 3 deletions
diff --git a/core/src/xmake/path/translate.c b/core/src/xmake/path/translate.c
index 0c2b22a1b..2b8806b07 100644
--- a/core/src/xmake/path/translate.c
+++ b/core/src/xmake/path/translate.c
@@ -53,12 +53,33 @@ tb_int_t xm_path_translate(lua_State *lua) {
}
// do path:translate()
- tb_char_t data[TB_PATH_MAXN];
- tb_size_t size = tb_path_translate_to(path, (tb_size_t)path_size, data, sizeof(data), normalize);
+ /* use a larger heap buffer for the long path to avoid stack buffer overflow,
+ * because tb_path_translate_to() does not truncate the output.
+ * https://github.com/xmake-io/xmake/issues/6962
+ *
+ * note: we cannot expand maxn for the `~` prefixed path,
+ * because tbox expands the home directory with an internal TB_PATH_MAXN buffer.
+ */
+ tb_char_t buff[TB_PATH_MAXN];
+ tb_char_t* data = buff;
+ tb_size_t maxn = sizeof(buff);
+ if (path_size + 1 > maxn) {
+ if (path[0] == '~') {
+ lua_pushnil(lua);
+ return 1;
+ }
+ maxn = (tb_size_t)path_size + TB_PATH_MAXN;
+ data = (tb_char_t *)tb_malloc(maxn);
+ tb_check_return_val(data, 0);
+ }
+ tb_size_t size = tb_path_translate_to(path, (tb_size_t)path_size, data, maxn, normalize);
if (size) {
lua_pushlstring(lua, data, (size_t)size);
} else {
lua_pushnil(lua);
}
+ if (data != buff) {
+ tb_free(data);
+ }
return 1;
}
diff --git a/xmake/modules/private/service/remote_build/filesync.lua b/xmake/modules/private/service/remote_build/filesync.lua
index fa9ba1fde..d2c2d6703 100644
--- a/xmake/modules/private/service/remote_build/filesync.lua
+++ b/xmake/modules/private/service/remote_build/filesync.lua
@@ -89,7 +89,10 @@ function filesync:snapshot()
ignorefiles = "|" .. table.concat(ignorefiles, "|")
end
local count = 0
- for _, filepath in ipairs(os.files(path.join(rootdir, "**" .. ignorefiles))) do
+ -- we should not translate the whole pattern with ignorefiles in path.join,
+ -- because the joined pattern string may be very long (> TB_PATH_MAXN)
+ -- https://github.com/xmake-io/xmake/issues/6962
+ for _, filepath in ipairs(os.files(path.join(rootdir, "**") .. ignorefiles)) do
local fileitem = path.relative(filepath, rootdir)
if fileitem then
-- we should always use '/' in path key for supporting linux & windows