From 3da6bdcd286608c936099460d9415875cd033ec0 Mon Sep 17 00:00:00 2001 From: th0truth Date: Sat, 8 Aug 2026 12:57:20 +0300 Subject: [PATCH 1/4] fix(io): fix an issue with substring collision in str_find_value() --- src/linux/io.c | 76 ++++++++++++++++++++++++++++---------------------- 1 file changed, 43 insertions(+), 33 deletions(-) diff --git a/src/linux/io.c b/src/linux/io.c index a9ab515..b3d9c13 100644 --- a/src/linux/io.c +++ b/src/linux/io.c @@ -1,4 +1,3 @@ -#include "base.h" #include "io.h" char * @@ -8,46 +7,57 @@ str_find_value(const char *source, const char *search, const char *delim) return NULL; } - /* Locate the key in the source string */ - const char *start = strstr(source, search); - if (start == NULL) { - return NULL; - } + size_t search_len = strlen(search); + const char *current = source; - /* Skip past the length of the key itself */ - start += strlen(search); + while ((current = strstr(current, search)) != NULL) { + bool valid_start = (current == source || *(current - 1) == '\n'); - /* Skip leading separators and whitespaces to reach the start of the value */ - while (*start != '\0' && (isspace((unsigned char)*start) || *start == ':')) { - ++start; - } + if (valid_start) { + const char *next = current + search_len; + + if (*next == '\0' || *next == ':' || *next == '=' || isspace((unsigned char)*next)) { + const char *start = next; - /* Find the end of the value based on the provided delimiters */ - const char *end = start; - while (*end != '\0' && strchr(delim, *end) == NULL) { - ++end; - } + /* Skip past the length of the key itself */ + start += strlen(search); - /* Backtrack to trim any trailing whitespace */ - while (end > start && isspace((unsigned char)*(end - 1))) { - --end; - } + /* Skip leading separators and whitespaces to reach the start of the value */ + while (*start != '\0' && (isspace((unsigned char)*start) || *start == ':')) { + ++start; + } - uint64_t len = end - start; - if (len == 0) { - return NULL; - } + /* Find the end of the value based on the provided delimiters */ + const char *end = start; + while (*end != '\0' && strchr(delim, *end) == NULL) { + ++end; + } - /* Allocate memory and copy the resulting value */ - char *value = malloc(len + 1); - if (value == NULL) { - return NULL; - } + while (end > start && isspace((unsigned char)*(end - 1))) { + --end; + } + + uint64_t len = end - start; + if (len == 0) { + return NULL; + } - memcpy(value, start, len); - value[len] = '\0'; + /* Allocate memory and copy the resulting value */ + char *value = malloc(len + 1); + if (value == NULL) { + return NULL; + } + + memcpy(value, start, len); + value[len] = '\0'; + + return value; + } + } + current += 1; + } - return value; + return NULL; } double From e973f48672beea3aec9ca8201210b090ce78d633 Mon Sep 17 00:00:00 2001 From: th0truth Date: Sat, 8 Aug 2026 13:09:11 +0300 Subject: [PATCH 2/4] fix: str_find_value and cpu_get_total_cores --- src/linux/hardware/cpu.c | 18 +++++++++--- src/linux/io.c | 60 ++++++++++++++++++---------------------- 2 files changed, 41 insertions(+), 37 deletions(-) diff --git a/src/linux/hardware/cpu.c b/src/linux/hardware/cpu.c index b1a9509..bf5ccd6 100644 --- a/src/linux/hardware/cpu.c +++ b/src/linux/hardware/cpu.c @@ -1,6 +1,7 @@ #include "base.h" #include "file.h" #include "io.h" +#include #include "cpu.h" static int16_t @@ -14,10 +15,19 @@ cpu_get_total_cores(void) int start, end; int16_t count = 0; - if (sscanf(online, "%d-%d", &start, &end) == 2) { - count = (end - start) + 1; - } else if (sscanf(online, "%d", &start) == 1) { - count = 1; + char *saveptr = NULL; + char *token = strtok_r(online, ",", &saveptr); + + while (token != NULL) { + if (sscanf(token, "%d-%d", &start, &end) == 2) { + if (end >= start) { + count += (end - start) + 1; + } + } else if (sscanf(token, "%d", &start) == 1) { + count += 1; + } + + token = strtok_r(NULL, ",", &saveptr); } free(online); diff --git a/src/linux/io.c b/src/linux/io.c index b3d9c13..51d021d 100644 --- a/src/linux/io.c +++ b/src/linux/io.c @@ -7,52 +7,46 @@ str_find_value(const char *source, const char *search, const char *delim) return NULL; } - size_t search_len = strlen(search); + size_t search_len = strlen(search); const char *current = source; while ((current = strstr(current, search)) != NULL) { bool valid_start = (current == source || *(current - 1) == '\n'); if (valid_start) { - const char *next = current + search_len; - - if (*next == '\0' || *next == ':' || *next == '=' || isspace((unsigned char)*next)) { - const char *start = next; + const char *start = current + search_len; - /* Skip past the length of the key itself */ - start += strlen(search); - - /* Skip leading separators and whitespaces to reach the start of the value */ - while (*start != '\0' && (isspace((unsigned char)*start) || *start == ':')) { - ++start; - } + /* Skip leading separators and whitespaces to reach the start of the value */ + while (*start != '\0' && (isspace((unsigned char)*start) || *start == ':' || *start == '=')) { + ++start; + } - /* Find the end of the value based on the provided delimiters */ - const char *end = start; - while (*end != '\0' && strchr(delim, *end) == NULL) { - ++end; - } + /* Find the end of the value based on the provided delimiters */ + const char *end = start; + while (*end != '\0' && strchr(delim, *end) == NULL) { + ++end; + } - while (end > start && isspace((unsigned char)*(end - 1))) { - --end; - } + /* Backtrack to trim any trailing whitespace */ + while (end > start && isspace((unsigned char)*(end - 1))) { + --end; + } - uint64_t len = end - start; - if (len == 0) { - return NULL; - } + uint64_t len = end - start; + if (len == 0) { + return NULL; + } - /* Allocate memory and copy the resulting value */ - char *value = malloc(len + 1); - if (value == NULL) { - return NULL; - } + /* Allocate memory and copy the resulting value */ + char *value = malloc(len + 1); + if (value == NULL) { + return NULL; + } - memcpy(value, start, len); - value[len] = '\0'; + memcpy(value, start, len); + value[len] = '\0'; - return value; - } + return value; } current += 1; } From 944ea2acb759c232afc25bb4a58d2cc327fa6423 Mon Sep 17 00:00:00 2001 From: th0truth Date: Sat, 8 Aug 2026 13:22:19 +0300 Subject: [PATCH 3/4] fix(cpu): Return allocated string and make proper integer division --- src/linux/hardware/cpu.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/linux/hardware/cpu.c b/src/linux/hardware/cpu.c index bf5ccd6..06b22f4 100644 --- a/src/linux/hardware/cpu.c +++ b/src/linux/hardware/cpu.c @@ -46,29 +46,31 @@ cpu_get_total_freq_mhz(uint16_t core_id, const char *filename) } int32_t khz = atoi(cpu_freq); + free(cpu_freq); if (khz <= 0) { return -1; } - return khz / 1000; + return khz / 1000.0f; } static char * cpu_get_arch(const char *flags) { if (flags == NULL) { - return "x86"; + return strdup("x86"); } char *flag = str_find_value(flags, "lm", NULL); if (flag == NULL) { - return "x86"; - } else { - free(flag); - return "x86_64"; + return strdup("x86"); } + + free(flag); + + return strdup("x86_64"); } CPU * From 6b7111e5715abf62346f4c347c7925538e02da8f Mon Sep 17 00:00:00 2001 From: th0truth Date: Sat, 8 Aug 2026 13:29:19 +0300 Subject: [PATCH 4/4] fix(hwmonitor): add theme_init(false) to prevent incorrect hardware info display --- src/hwmonitor.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/hwmonitor.c b/src/hwmonitor.c index 41c641b..e5ca375 100644 --- a/src/hwmonitor.c +++ b/src/hwmonitor.c @@ -3,6 +3,7 @@ #include #include "display.h" +#include "theme.h" #include "util.h" #include "api/groq.h" @@ -28,6 +29,9 @@ main(int argc, char **argv) /* Parsed from util.c */ parse_arguments(argc, argv, &config); + /* Initialize theme colors based on TTY check */ + theme_init(false); + if (config.watch_mode) { signal(SIGINT, handle_sigint); }