diff --git a/src/config/parse_config.h b/src/config/parse_config.h index b7f89d59..5d7cbfae 100644 --- a/src/config/parse_config.h +++ b/src/config/parse_config.h @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -537,10 +538,19 @@ int32_t parse_fold_state(const char *str) { } int64_t parse_color(const char *hex_str) { char *endptr; + errno = 0; int64_t hex_num = strtol(hex_str, &endptr, 16); - if (*endptr != '\0') { + + // Check for conversion errors + if (*endptr != '\0' || errno == ERANGE) { return -1; } + + // Validate range for color values (0x00000000 to 0xFFFFFFFF) + if (hex_num < 0 || hex_num > 0xFFFFFFFF) { + return -1; + } + return hex_num; } @@ -588,11 +598,20 @@ 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) { - strcat(combined, ","); + size_t remaining = total_len - current_len; + if (remaining > 0) { + strncat(combined, ",", remaining); + current_len += 1; + } + } + size_t remaining = total_len - current_len; + if (remaining > 0) { + strncat(combined, values[i], remaining); + current_len += strlen(values[i]); } - strcat(combined, values[i]); } return combined; @@ -626,8 +645,9 @@ uint32_t parse_mod(const char *mod_str) { if (strncmp(token, "code:", 5) == 0) { // 处理 code: 形式 char *endptr; + errno = 0; long keycode = strtol(token + 5, &endptr, 10); - if (endptr != token + 5 && (*endptr == '\0' || *endptr == ' ')) { + if (endptr != token + 5 && (*endptr == '\0' || *endptr == ' ') && errno != ERANGE) { switch (keycode) { case 133: case 134: @@ -777,7 +797,16 @@ KeySymCode parse_key(const char *key_str, bool isbindsym) { // 处理 code: 前缀的情况 if (strncmp(key_str, "code:", 5) == 0) { char *endptr; + errno = 0; xkb_keycode_t keycode = (xkb_keycode_t)strtol(key_str + 5, &endptr, 10); + + // Validate conversion + if (errno == ERANGE || *endptr != '\0') { + kc.type = KEY_TYPE_SYM; + kc.keysym = XKB_KEY_NoSymbol; + return kc; + } + kc.type = KEY_TYPE_CODE; kc.keycode.keycode1 = keycode; // 只设置第一个 kc.keycode.keycode2 = 0; @@ -2283,7 +2312,8 @@ bool parse_option(Config *config, char *key, char *value) { trim_whitespace(arg_value4); trim_whitespace(arg_value5); - strcpy(binding->mode, config->keymode); + strncpy(binding->mode, config->keymode, sizeof(binding->mode) - 1); + binding->mode[sizeof(binding->mode) - 1] = '\0'; if (strcmp(binding->mode, "common") == 0) { binding->iscommonmode = true; binding->isdefaultmode = false; @@ -3474,7 +3504,8 @@ bool parse_config(void) { config.tag_rules = NULL; config.tag_rules_count = 0; config.cursor_theme = NULL; - strcpy(config.keymode, "default"); + strncpy(config.keymode, "default", sizeof(config.keymode) - 1); + config.keymode[sizeof(config.keymode) - 1] = '\0'; create_config_keymap(); diff --git a/src/dispatch/bind_define.h b/src/dispatch/bind_define.h index 0bfab158..c653a7ba 100644 --- a/src/dispatch/bind_define.h +++ b/src/dispatch/bind_define.h @@ -837,11 +837,15 @@ int32_t spawn(const Arg *arg) { // 2. 解析参数 char *argv[64]; int32_t argc = 0; + wordexp_t wordexp_results[63]; // Track all wordexp results for cleanup + int32_t wordexp_count = 0; + char *token = strtok((char *)arg->v, " "); while (token != NULL && argc < 63) { wordexp_t p; if (wordexp(token, &p, 0) == 0) { argv[argc++] = p.we_wordv[0]; + wordexp_results[wordexp_count++] = p; // Store for cleanup } else { argv[argc++] = token; } @@ -852,7 +856,10 @@ int32_t spawn(const Arg *arg) { // 3. 执行命令 execvp(argv[0], argv); - // 4. execvp 失败时:打印错误并直接退出(避免 coredump) + // 4. execvp 失败时:清理并打印错误 + for (int i = 0; i < wordexp_count; i++) { + wordfree(&wordexp_results[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 58e69dc1..de5131a6 100644 --- a/src/fetch/common.h +++ b/src/fetch/common.h @@ -33,7 +33,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) { - strcpy(abbr, layout_mappings[i].abbr); + strncpy(abbr, layout_mappings[i].abbr, 4); + abbr[4] = '\0'; return; } } @@ -73,7 +74,8 @@ void get_layout_abbr(char *abbr, const char *full_name) { abbr[2] = '\0'; } else { // 5. 最终回退:返回 "xx" - strcpy(abbr, "xx"); + strncpy(abbr, "xx", 4); + abbr[4] = '\0'; } }