config.c: Fix inconsistent pointer logic in ast_variable_update.

Commit 3cab4e7ab4 introduced a
regression by causing the wrong pointers to be used in certain
(more complex) cases. We now take care to ensure the exact
same pointers are used as before that commit, and simplify
by eliminating the unnecessary second for loop.

Resolves: #1147
This commit is contained in:
Naveen Albert
2025-03-06 20:53:50 -05:00
committed by github-actions[bot]
parent c7db162844
commit f0f220b369

View File

@@ -1645,41 +1645,51 @@ int ast_variable_delete(struct ast_category *category, const char *variable, con
int ast_variable_update(struct ast_category *category, const char *variable,
const char *value, const char *match, unsigned int object)
{
struct ast_variable *cur, *prev=NULL, *newer=NULL, *matchvar = NULL;
struct ast_variable *cur, *prev = NULL, *newer = NULL;
struct ast_variable *matchcur = NULL, *matchprev = NULL;
/* Find the last match. See comments in ast_variable_retrieve,
* but this ensures updating config sections that inherit from
* templates works properly. */
for (cur = category->root; cur; prev = cur, cur = cur->next) {
if (strcasecmp(cur->name, variable) ||
(!ast_strlen_zero(match) && strcasecmp(cur->value, match)))
continue;
matchvar = cur;
}
for (cur = category->root; cur; prev = cur, cur = cur->next) {
if (cur != matchvar) {
if (strcasecmp(cur->name, variable) || (!ast_strlen_zero(match) && strcasecmp(cur->value, match))) {
/* Not the same variable,
* or its value doesn't match. */
continue;
}
if (!(newer = ast_variable_new(variable, value, cur->file)))
return -1;
ast_variable_move(newer, cur);
newer->object = newer->object || object;
/* Replace the old node in the list with the new node. */
newer->next = cur->next;
if (prev)
prev->next = newer;
else
category->root = newer;
if (category->last == cur)
category->last = newer;
ast_variable_destroy(cur);
return 0;
matchprev = prev;
matchcur = cur;
}
/* Could not find variable to update */
return -1;
if (!matchcur) {
/* Could not find variable to update */
return -1;
}
/* Restore pointers from the matching var */
prev = matchprev;
cur = matchcur;
if (!(newer = ast_variable_new(variable, value, cur->file))) {
return -1;
}
ast_variable_move(newer, cur);
newer->object = newer->object || object;
/* Replace the old node in the list with the new node. */
newer->next = cur->next;
if (prev) {
prev->next = newer;
} else {
category->root = newer;
}
if (category->last == cur) {
category->last = newer;
}
ast_variable_destroy(cur);
return 0;
}
struct ast_category *ast_category_delete(struct ast_config *config,