From c157ee62f666a83d883a11cbb7cb684ed2d2320f Mon Sep 17 00:00:00 2001 From: Naveen Albert Date: Wed, 9 Aug 2023 22:30:53 +0000 Subject: [PATCH] config.c: Make ast_variable_retrieve return last match. ast_variable_retrieve currently returns the first match for a variable, as opposed to the last one. This is problematic because modules that load config settings by explicitly calling ast_variable_retrieve on a variable name (as opposed to iterating through all the directives as specified) will end up taking the first specified value, such as the default value from the template rather than the actual effective value in an individual config section, leading to the wrong config. This fixes this by making ast_variable_retrieve return the last match, or the most recently overridden one, as the effective setting. This is similar to what the -1 index in the AST_CONFIG function does. There is another function, ast_variable_find_last_in_list, that does something similar. However, it's a slightly different API, and it sees virtually no usage in Asterisk. ast_variable_retrieve is what most things use so this is currently the relevant point of breakage. In practice, this is unlikely to cause any breakage, since there would be no logical reason to use an inherited value rather than an explicitly overridden value when loading a config. ASTERISK-30370 #close Resolves: #244 UpgradeNote: Config variables retrieved explicitly by name now return the most recently overriding value as opposed to the base value (e.g. from a template). This is equivalent to retrieving a config setting using the -1 index to the AST_CONFIG function. The major implication of this is that modules processing configs by explicitly retrieving variables by name will now get the effective value of a variable as overridden in a config rather than the first-set value (from a template), which is consistent with how other modules load config settings. --- main/config.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/main/config.c b/main/config.c index 18ab549969..4f575046ee 100644 --- a/main/config.c +++ b/main/config.c @@ -784,11 +784,19 @@ const char *ast_config_option(struct ast_config *cfg, const char *cat, const cha const char *ast_variable_retrieve(struct ast_config *config, const char *category, const char *variable) { struct ast_variable *v; + const char *match = NULL; + + /* We can't return as soon as we find a match, because if a config section overrides + * something specified in a template, then the actual effective value is the last + * one encountered, not the first one. + * (This is like using the -1 index for the AST_CONFIG function.) + * Also see ast_variable_find_last_in_list + */ if (category) { for (v = ast_variable_browse(config, category); v; v = v->next) { if (!strcasecmp(variable, v->name)) { - return v->value; + match = v->value; } } } else { @@ -797,13 +805,13 @@ const char *ast_variable_retrieve(struct ast_config *config, const char *categor for (cat = config->root; cat; cat = cat->next) { for (v = cat->root; v; v = v->next) { if (!strcasecmp(variable, v->name)) { - return v->value; + match = v->value; } } } } - return NULL; + return match; } const char *ast_variable_retrieve_filtered(struct ast_config *config,