From 2567b4e41ba9b0f508e34e307b5816045d15e3b4 Mon Sep 17 00:00:00 2001 From: Saikari Date: Fri, 10 Jul 2026 05:01:39 +0300 Subject: fix: avoid stack buffer overflow for long paths in path translation --- core/src/xmake/path/translate.c | 25 ++++++++++++++++++++-- .../private/service/remote_build/filesync.lua | 5 ++++- 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 -- cgit v1.3.1 From fd2a0d87ab99d315c8d7ee9cb38e214d7e1c5ae6 Mon Sep 17 00:00:00 2001 From: Saikari Date: Fri, 10 Jul 2026 05:11:12 +0300 Subject: fix: use lua_newuserdata for dynamic memory allocation in path translation --- core/src/xmake/path/translate.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/core/src/xmake/path/translate.c b/core/src/xmake/path/translate.c index 2b8806b07..cd2f4e51d 100644 --- a/core/src/xmake/path/translate.c +++ b/core/src/xmake/path/translate.c @@ -69,8 +69,7 @@ tb_int_t xm_path_translate(lua_State *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); + data = (tb_char_t *)lua_newuserdata(lua, maxn); } tb_size_t size = tb_path_translate_to(path, (tb_size_t)path_size, data, maxn, normalize); if (size) { @@ -78,8 +77,5 @@ tb_int_t xm_path_translate(lua_State *lua) { } else { lua_pushnil(lua); } - if (data != buff) { - tb_free(data); - } return 1; } -- cgit v1.3.1 From 9d654aa671f8aae9df7f1480221aaebe491e4d65 Mon Sep 17 00:00:00 2001 From: ruki Date: Sat, 11 Jul 2026 00:37:21 +0800 Subject: improve path translate --- core/src/tbox/tbox | 2 +- core/src/xmake/path/translate.c | 23 ++++++++++------------- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/core/src/tbox/tbox b/core/src/tbox/tbox index 38e3a97a3..622da925c 160000 --- a/core/src/tbox/tbox +++ b/core/src/tbox/tbox @@ -1 +1 @@ -Subproject commit 38e3a97a38c4551271639a689e77060369b4746a +Subproject commit 622da925c4c61e15f16d89ab39d840867c42a111 diff --git a/core/src/xmake/path/translate.c b/core/src/xmake/path/translate.c index cd2f4e51d..ce2e83169 100644 --- a/core/src/xmake/path/translate.c +++ b/core/src/xmake/path/translate.c @@ -53,25 +53,22 @@ tb_int_t xm_path_translate(lua_State *lua) { } // do path:translate() - /* 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; - } + tb_size_t size = tb_path_translate_to(path, (tb_size_t)path_size, data, maxn, normalize); + if (!size) { + /* 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. + */ maxn = (tb_size_t)path_size + TB_PATH_MAXN; data = (tb_char_t *)lua_newuserdata(lua, maxn); + size = tb_path_translate_to(path, (tb_size_t)path_size, data, maxn, normalize); } - 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 { -- cgit v1.3.1