lib/config: Return pointer to static buffer from config_get_value()
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");
