From 4d5bfa6af2b157b3525dc1d7043071eb02e938e8 Mon Sep 17 00:00:00 2001 From: Mintsuki Date: Thu, 25 Dec 2025 18:56:09 +0100 Subject: [PATCH] lib/config: Return pointer to static buffer from config_get_value() --- common/lib/config.c | 44 +++++++++++++++++++++++++++++++++---------- common/lib/gterm.c | 1 - common/menu.c | 46 ++++++++++++++++++++++++++++++++------------- 3 files changed, 67 insertions(+), 24 deletions(-) diff --git a/common/lib/config.c b/common/lib/config.c index 87cc5d1a..8e525391 100644 --- a/common/lib/config.c +++ b/common/lib/config.c @@ -19,6 +19,7 @@ const char *config_b2sum = CONFIG_B2SUM_SIGNATURE CONFIG_B2SUM_EMPTY; static bool config_get_entry_name(char *ret, size_t index, size_t limit); static char *config_get_entry(size_t *size, size_t index); +static char *copy_config_value(const char *src); #define SEPARATOR '\n' @@ -283,7 +284,7 @@ static struct menu_entry *create_menu_tree(struct menu_entry *parent, char *comment = config_get_value(entry->body, 0, "COMMENT"); if (comment != NULL) { - entry->comment = comment; + entry->comment = copy_config_value(comment); } if (prev != NULL) @@ -597,25 +598,40 @@ cont: static const char *lastkey; +static char *copy_config_value(const char *src) { + if (src == NULL) { + return NULL; + } + size_t len = strlen(src) + 1; + char *dst = ext_mem_alloc(len); + memcpy(dst, src, len); + return dst; +} + struct conf_tuple config_get_tuple(const char *config, size_t index, const char *key1, const char *key2) { struct conf_tuple conf_tuple; - conf_tuple.value1 = config_get_value(config, index, key1); - if (conf_tuple.value1 == NULL) { + char *tmp = config_get_value(config, index, key1); + if (tmp == NULL) { return (struct conf_tuple){0}; } - - conf_tuple.value2 = config_get_value(lastkey, 0, key2); + conf_tuple.value1 = copy_config_value(tmp); const char *lk1 = lastkey; - const char *next_value1 = config_get_value(config, index + 1, key1); + tmp = config_get_value(lk1, 0, key2); + conf_tuple.value2 = copy_config_value(tmp); const char *lk2 = lastkey; + const char *next_value1 = config_get_value(config, index + 1, key1); + + const char *lk3 = lastkey; + if (conf_tuple.value2 != NULL && next_value1 != NULL) { - if ((uintptr_t)lk1 > (uintptr_t)lk2) { + if ((uintptr_t)lk2 > (uintptr_t)lk3) { + pmm_free(conf_tuple.value2, strlen(conf_tuple.value2) + 1); conf_tuple.value2 = NULL; } } @@ -623,6 +639,11 @@ struct conf_tuple config_get_tuple(const char *config, size_t index, return conf_tuple; } +// Static buffer for config_get_value return values. +// Callers must copy the result if they need persistence across calls. +#define CONFIG_VALUE_BUF_SIZE 4096 +static char config_value_buf[CONFIG_VALUE_BUF_SIZE]; + char *config_get_value(const char *config, size_t index, const char *key) { if (!key || !config_ready) return NULL; @@ -646,10 +667,13 @@ char *config_get_value(const char *config, size_t index, const char *key) { for (value_len = 0; config[i + value_len] != SEPARATOR && config[i + value_len]; value_len++); - char *buf = ext_mem_alloc(value_len + 1); - memcpy(buf, config + i, value_len); + if (value_len >= CONFIG_VALUE_BUF_SIZE) { + value_len = CONFIG_VALUE_BUF_SIZE - 1; + } + memcpy(config_value_buf, config + i, value_len); + config_value_buf[value_len] = '\0'; lastkey = config + i; - return buf; + return config_value_buf; } } diff --git a/common/lib/gterm.c b/common/lib/gterm.c index fae0612c..ad260b33 100644 --- a/common/lib/gterm.c +++ b/common/lib/gterm.c @@ -534,7 +534,6 @@ bool gterm_init(struct fb_info **_fbs, size_t *_fbs_count, case 180: fb_rotation = FLANTERM_FB_ROTATE_180; break; case 270: fb_rotation = FLANTERM_FB_ROTATE_270; break; } - pmm_free(rotation_str, strlen(rotation_str) + 1); } uint32_t ansi_colours[8]; diff --git a/common/menu.c b/common/menu.c index f094ea54..3e29e052 100644 --- a/common/menu.c +++ b/common/menu.c @@ -827,10 +827,16 @@ noreturn void _menu(bool first_run) { if (interface_help_colour_str != NULL) { interface_help_colour[3] = interface_help_colour_str[0]; interface_help_colour_bright[3] = interface_help_colour_str[0]; - pmm_free(interface_help_colour_str, strlen(interface_help_colour_str) + 1); } - menu_branding = config_get_value(NULL, 0, "INTERFACE_BRANDING"); + { + char *tmp = config_get_value(NULL, 0, "INTERFACE_BRANDING"); + if (tmp != NULL) { + size_t len = strlen(tmp) + 1; + menu_branding = ext_mem_alloc(len); + memcpy(menu_branding, tmp, len); + } + } if (menu_branding == NULL) { #if defined (BIOS) { @@ -867,11 +873,18 @@ noreturn void _menu(bool first_run) { #endif } - menu_branding_colour = config_get_value(NULL, 0, "INTERFACE_BRANDING_COLOUR"); - if (menu_branding_colour == NULL) - menu_branding_colour = config_get_value(NULL, 0, "INTERFACE_BRANDING_COLOR"); - if (menu_branding_colour == NULL) - menu_branding_colour = "6"; + { + char *tmp = config_get_value(NULL, 0, "INTERFACE_BRANDING_COLOUR"); + if (tmp == NULL) + tmp = config_get_value(NULL, 0, "INTERFACE_BRANDING_COLOR"); + if (tmp != NULL) { + size_t len = strlen(tmp) + 1; + menu_branding_colour = ext_mem_alloc(len); + memcpy(menu_branding_colour, tmp, len); + } else { + menu_branding_colour = "6"; + } + } bool skip_timeout = false; struct menu_entry *selected_menu_entry = NULL; @@ -1209,12 +1222,19 @@ noreturn void boot(char *config) { init_riscv(config); #endif - char *cmdline = config_get_value(config, 0, "KERNEL_CMDLINE"); - if (!cmdline) { - cmdline = config_get_value(config, 0, "CMDLINE"); - } - if (!cmdline) { - cmdline = ""; + char *cmdline; + { + char *tmp = config_get_value(config, 0, "KERNEL_CMDLINE"); + if (!tmp) { + tmp = config_get_value(config, 0, "CMDLINE"); + } + if (tmp) { + size_t len = strlen(tmp) + 1; + cmdline = ext_mem_alloc(len); + memcpy(cmdline, tmp, len); + } else { + cmdline = ""; + } } char *proto = config_get_value(config, 0, "PROTOCOL");