From: Jaroslav Kysela Date: Fri, 31 Jul 2026 11:00:44 +0000 (+0200) Subject: alsactl: state - use snd_config_get_llong() in config_integer/config_integer64 X-Git-Url: https://git.alsa-project.org/?a=commitdiff_plain;h=85db8a95f7f4c5bdb353033d50d5e4c14011dd11;p=alsa-utils.git alsactl: state - use snd_config_get_llong() in config_integer/config_integer64 The alsa-lib's configuration parser stores 32-bit integer values to INTEGER type. Change integer parsers in state.c to accept both INTEGER and INTEGER64 types and also strings (converted to integer) using new snd_config_get_llong() function. Buglink: https://lore.kernel.org/alsa-devel/DSSPR12MB999212CD0AF414E51769382046CAF82@DSSPR12MB999212.namprd12.prod.outlook.com/ Signed-off-by: Jaroslav Kysela --- diff --git a/alsactl/state.c b/alsactl/state.c index 79bd309..5540a36 100644 --- a/alsactl/state.c +++ b/alsactl/state.c @@ -25,10 +25,47 @@ #include #include #include +#include #include #include +#include #include "alsactl.h" +#if SND_LIB_VER(1, 2, 16) >= SND_LIB_VERSION +/* compat implementation for alsa-lib versions without snd_config_get_llong() */ +static int snd_config_get_llong(const snd_config_t *config, long long *ptr, int base) +{ + const char *str; + char *endptr; + long lval; + int err; + + switch (snd_config_get_type(config)) { + case SND_CONFIG_TYPE_INTEGER: + err = snd_config_get_integer(config, &lval); + if (err < 0) + return err; + *ptr = lval; + return 0; + case SND_CONFIG_TYPE_INTEGER64: + return snd_config_get_integer64(config, ptr); + case SND_CONFIG_TYPE_STRING: + err = snd_config_get_string(config, &str); + if (err < 0) + return err; + if (str == NULL || *str == '\0') + return -EINVAL; + errno = 0; + *ptr = strtoll(str, &endptr, base); + if (errno != 0 || *endptr != '\0') + return -EINVAL; + return 0; + default: + return -EINVAL; + } +} +#endif + static int linked_cards[16]; static void init_linked_cards(void) @@ -787,19 +824,25 @@ static int config_enumerated(snd_config_t *n, snd_ctl_t *handle, static int config_integer(snd_config_t *n, long *val, int doit) { - int err = snd_config_get_integer(n, val); + long long lval; + int err = snd_config_get_llong(n, &lval, 0); if (err < 0 && force_restore && doit) { if (snd_config_get_type(n) != SND_CONFIG_TYPE_COMPOUND) return err; n = snd_config_iterator_entry(snd_config_iterator_first(n)); return config_integer(n, val, doit); } - return err; + if (err < 0) + return err; + if (lval < INT_MIN || lval > INT_MAX) + return -ERANGE; + *val = lval; + return 0; } static int config_integer64(snd_config_t *n, long long *val, int doit) { - int err = snd_config_get_integer64(n, val); + int err = snd_config_get_llong(n, val, 0); if (err < 0 && force_restore && doit) { if (snd_config_get_type(n) != SND_CONFIG_TYPE_COMPOUND) return err;