From e2649dd84f36b9fd76c28e072fcbcb7a0e5e1abd Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 18 Feb 2026 08:58:36 +0000 Subject: [PATCH] Final security improvements based on code review - Add LAYOUT_ABBR_SIZE constant to avoid magic numbers - Track allocated argv entries to properly free on error - Simplify strncat bounds checking using strlen for accuracy - Ensure all allocated memory is freed in error paths Co-authored-by: squassina <8495707+squassina@users.noreply.github.com> --- src/config/parse_config.h | 20 +++----------------- src/dispatch/bind_define.h | 13 ++++++++++--- src/fetch/common.h | 11 +++++++---- 3 files changed, 20 insertions(+), 24 deletions(-) diff --git a/src/config/parse_config.h b/src/config/parse_config.h index 19a30d3e..a94686ee 100644 --- a/src/config/parse_config.h +++ b/src/config/parse_config.h @@ -598,25 +598,11 @@ static char *combine_args_until_empty(char *values[], int count) { } combined[0] = '\0'; - size_t current_len = 0; for (int i = 0; i < first_empty; i++) { - if (i > 0 && current_len < total_len) { - size_t remaining = total_len - current_len; - size_t to_copy = (remaining < 1) ? 0 : 1; - if (to_copy > 0) { - strncat(combined, ",", to_copy); - current_len += to_copy; - } - } - if (current_len < total_len) { - size_t remaining = total_len - current_len; - size_t val_len = strlen(values[i]); - size_t to_copy = (val_len < remaining) ? val_len : remaining; - if (to_copy > 0) { - strncat(combined, values[i], to_copy); - current_len += to_copy; - } + if (i > 0) { + strncat(combined, ",", total_len - strlen(combined)); } + strncat(combined, values[i], total_len - strlen(combined)); } return combined; diff --git a/src/dispatch/bind_define.h b/src/dispatch/bind_define.h index e4463c31..c845b4b9 100644 --- a/src/dispatch/bind_define.h +++ b/src/dispatch/bind_define.h @@ -836,6 +836,7 @@ int32_t spawn(const Arg *arg) { // 2. 解析参数 char *argv[64]; + bool argv_allocated[64] = {false}; // Track which argv entries were allocated int32_t argc = 0; char *token = strtok((char *)arg->v, " "); @@ -846,10 +847,13 @@ int32_t spawn(const Arg *arg) { argv[argc] = strdup(p.we_wordv[0]); wordfree(&p); // Free immediately after copying if (argv[argc] != NULL) { + argv_allocated[argc] = true; argc++; } } else { - argv[argc++] = token; + argv[argc] = token; + argv_allocated[argc] = false; + argc++; } token = strtok(NULL, " "); } @@ -859,8 +863,11 @@ int32_t spawn(const Arg *arg) { execvp(argv[0], argv); // 4. execvp 失败时:清理分配的字符串并打印错误 - // Note: We only need to free strings that were strdup'd from wordexp - // The original tokens from arg->v don't need to be freed + for (int i = 0; i < argc; i++) { + if (argv_allocated[i]) { + free(argv[i]); + } + } wlr_log(WLR_ERROR, "mango: execvp '%s' failed: %s\n", argv[0], strerror(errno)); _exit(EXIT_FAILURE); // 使用 _exit 避免缓冲区刷新等操作 diff --git a/src/fetch/common.h b/src/fetch/common.h index 28645969..072b4e0b 100644 --- a/src/fetch/common.h +++ b/src/fetch/common.h @@ -26,6 +26,9 @@ int32_t isdescprocess(pid_t p, pid_t c) { return (int32_t)c; } +// Buffer size for layout abbreviations (must match kb_layout buffer in dwl-ipc.h) +#define LAYOUT_ABBR_SIZE 32 + void get_layout_abbr(char *abbr, const char *full_name) { // 清空输出缓冲区 abbr[0] = '\0'; @@ -33,8 +36,8 @@ void get_layout_abbr(char *abbr, const char *full_name) { // 1. 尝试在映射表中查找 for (int32_t i = 0; layout_mappings[i].full_name != NULL; i++) { if (strcmp(full_name, layout_mappings[i].full_name) == 0) { - strncpy(abbr, layout_mappings[i].abbr, 31); - abbr[31] = '\0'; + strncpy(abbr, layout_mappings[i].abbr, LAYOUT_ABBR_SIZE - 1); + abbr[LAYOUT_ABBR_SIZE - 1] = '\0'; return; } } @@ -74,8 +77,8 @@ void get_layout_abbr(char *abbr, const char *full_name) { abbr[2] = '\0'; } else { // 5. 最终回退:返回 "xx" - strncpy(abbr, "xx", 31); - abbr[31] = '\0'; + strncpy(abbr, "xx", LAYOUT_ABBR_SIZE - 1); + abbr[LAYOUT_ABBR_SIZE - 1] = '\0'; } }