From ed7652db5056c3658afbc11c04e164e77da18650 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Mon, 25 Aug 2025 14:26:44 +0200 Subject: [PATCH] config: value_to_*(): don't overwrite result variable on error Some of the value_to_*() functions wrote directly to the output variable, even when the value was invalid. This often resulted in the an actual configuration option (i.e. a member in the config struct) to be overwritten by an invalid value. For example, -o initial-color-theme=0 would set conf->initial_color_theme to -1, resulting in a crash later, when initializing a terminal instance. --- CHANGELOG.md | 7 ++++++- config.c | 20 ++++++++++++++------ 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dd5730a1..2a2e3347 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -70,7 +70,7 @@ ### Changed * The label letters are no longer sorted before being assigned to URLs - ([#2140]2140[]). + ([#2140][2140]). * Sending SIGUSR1/SIGUSR2 to a `foot --server` process now causes newly spawned client instances to use the selected theme, instead of the original one. @@ -83,6 +83,11 @@ ### Deprecated ### Removed ### Fixed + +* Invalid configuration values overriding valid ones in surprising + ways. + + ### Security ### Contributors diff --git a/config.c b/config.c index 77dc3a73..1d539bcb 100644 --- a/config.c +++ b/config.c @@ -474,8 +474,12 @@ str_to_ulong(const char *s, int base, unsigned long *res) errno = 0; char *end = NULL; - *res = strtoul(s, &end, base); - return errno == 0 && *end == '\0'; + unsigned long v = strtoul(s, &end, base); + if (!(errno == 0 && *end == '\0')) + return false; + + *res = v; + return true; } static bool NOINLINE @@ -544,12 +548,13 @@ value_to_float(struct context *ctx, float *res) errno = 0; char *end = NULL; - *res = strtof(s, &end); + float v = strtof(s, &end); if (!(errno == 0 && *end == '\0')) { LOG_CONTEXTUAL_ERR("invalid decimal value"); return false; } + *res = v; return true; } @@ -641,7 +646,6 @@ value_to_enum(struct context *ctx, const char **value_map, int *res) valid_values[idx - 2] = '\0'; LOG_CONTEXTUAL_ERR("not one of %s", valid_values); - *res = -1; return false; } @@ -690,14 +694,18 @@ value_to_two_colors(struct context *ctx, goto out; } + uint32_t a, b; + ctx->value = first_as_str; - if (!value_to_color(ctx, first, allow_alpha)) + if (!value_to_color(ctx, &a, allow_alpha)) goto out; ctx->value = second_as_str; - if (!value_to_color(ctx, second, allow_alpha)) + if (!value_to_color(ctx, &b, allow_alpha)) goto out; + *first = a; + *second = b; ret = true; out: