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.
This commit is contained in:
Daniel Eklöf 2025-08-25 14:26:44 +02:00
parent 72d9a13c0c
commit ed7652db50
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
2 changed files with 20 additions and 7 deletions

View file

@ -70,7 +70,7 @@
### Changed ### Changed
* The label letters are no longer sorted before being assigned to URLs * 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 * Sending SIGUSR1/SIGUSR2 to a `foot --server` process now causes
newly spawned client instances to use the selected theme, instead of newly spawned client instances to use the selected theme, instead of
the original one. the original one.
@ -83,6 +83,11 @@
### Deprecated ### Deprecated
### Removed ### Removed
### Fixed ### Fixed
* Invalid configuration values overriding valid ones in surprising
ways.
### Security ### Security
### Contributors ### Contributors

View file

@ -474,8 +474,12 @@ str_to_ulong(const char *s, int base, unsigned long *res)
errno = 0; errno = 0;
char *end = NULL; char *end = NULL;
*res = strtoul(s, &end, base); unsigned long v = strtoul(s, &end, base);
return errno == 0 && *end == '\0'; if (!(errno == 0 && *end == '\0'))
return false;
*res = v;
return true;
} }
static bool NOINLINE static bool NOINLINE
@ -544,12 +548,13 @@ value_to_float(struct context *ctx, float *res)
errno = 0; errno = 0;
char *end = NULL; char *end = NULL;
*res = strtof(s, &end); float v = strtof(s, &end);
if (!(errno == 0 && *end == '\0')) { if (!(errno == 0 && *end == '\0')) {
LOG_CONTEXTUAL_ERR("invalid decimal value"); LOG_CONTEXTUAL_ERR("invalid decimal value");
return false; return false;
} }
*res = v;
return true; return true;
} }
@ -641,7 +646,6 @@ value_to_enum(struct context *ctx, const char **value_map, int *res)
valid_values[idx - 2] = '\0'; valid_values[idx - 2] = '\0';
LOG_CONTEXTUAL_ERR("not one of %s", valid_values); LOG_CONTEXTUAL_ERR("not one of %s", valid_values);
*res = -1;
return false; return false;
} }
@ -690,14 +694,18 @@ value_to_two_colors(struct context *ctx,
goto out; goto out;
} }
uint32_t a, b;
ctx->value = first_as_str; ctx->value = first_as_str;
if (!value_to_color(ctx, first, allow_alpha)) if (!value_to_color(ctx, &a, allow_alpha))
goto out; goto out;
ctx->value = second_as_str; ctx->value = second_as_str;
if (!value_to_color(ctx, second, allow_alpha)) if (!value_to_color(ctx, &b, allow_alpha))
goto out; goto out;
*first = a;
*second = b;
ret = true; ret = true;
out: out: