config_options: Handle ACO arrays correctly in generated XML docs.

There are 3 separate changes here but they are all closely related:

* Only try to set matchfield attributes on 'field' nodes

* We need to adjust how we treat the category pointer based on the
  value of the category_match, to avoid memory corruption. We now
  generate a regex-like string when match types other than
  ACO_WHITELIST and ACO_BLACKLIST are used.

* Switch app_agent_pool from ACO_BLACKLIST_ARRAY to
  ACO_BLACKLIST_EXACT since we only have one category we need to
  ignore, not two.

ASTERISK-29614 #close

Change-Id: I7be7bdb1bb9814f942bc6bb4fdd0a55a7b7efe1e
This commit is contained in:
Sean Bright 2021-08-25 11:21:07 -04:00 committed by Friendly Automation
parent 38cc3160d3
commit 1bd642db7f
2 changed files with 55 additions and 15 deletions

View File

@ -456,17 +456,11 @@ struct agents_cfg {
struct ao2_container *agents;
};
static const char *agent_type_blacklist[] = {
"general",
"agents",
NULL,
};
static struct aco_type agent_type = {
.type = ACO_ITEM,
.name = "agent-id",
.category_match = ACO_BLACKLIST_ARRAY,
.category = (const char *)agent_type_blacklist,
.category_match = ACO_BLACKLIST_EXACT,
.category = "general",
.item_alloc = agent_cfg_alloc,
.item_find = agent_cfg_find,
.item_offset = offsetof(struct agents_cfg, agents),

View File

@ -1037,6 +1037,45 @@ static char *complete_config_option(const char *module, const char *option, cons
return NULL;
}
/*! \internal
* \brief Generate a category match string suitable for display in 'config show help'
*/
static struct ast_str *derive_category_text(enum aco_category_op category_match, const char *category)
{
struct ast_str *s = ast_str_create(128);
if (!s) {
return NULL;
}
switch (category_match) {
case ACO_WHITELIST_ARRAY:
case ACO_BLACKLIST_ARRAY: {
size_t i;
const char **matches = (const char **) category;
ast_str_append(&s, 0, "^(");
for (i = 0; matches[i]; i++) {
ast_str_append(&s, 0, "%s%s",
i ? "|" : "",
matches[i]);
}
ast_str_append(&s, 0, ")$");
break;
}
case ACO_WHITELIST_EXACT:
case ACO_BLACKLIST_EXACT:
ast_str_set(&s, 0, "^%s$", category);
break;
case ACO_WHITELIST:
case ACO_BLACKLIST:
default:
ast_str_set(&s, 0, "%s", category);
break;
}
return s;
}
/* Define as 0 if we want to allow configurations to be registered without
* documentation
*/
@ -1051,6 +1090,7 @@ static int xmldoc_update_config_type(const char *module, const char *name, const
RAII_VAR(struct ast_xml_doc_item *, config_info, ao2_find(xmldocs, module, OBJ_KEY), ao2_cleanup);
struct ast_xml_doc_item *config_type;
struct ast_xml_node *type, *syntax, *matchinfo, *tmp;
struct ast_str *derived_category = NULL;
/* If we already have a syntax element, bail. This isn't an error, since we may unload a module which
* has updated the docs and then load it again. */
@ -1083,7 +1123,12 @@ static int xmldoc_update_config_type(const char *module, const char *name, const
return XMLDOC_STRICT ? -1 : 0;
}
ast_xml_set_text(tmp, category);
derived_category = derive_category_text(category_match, category);
if (derived_category) {
ast_xml_set_text(tmp, ast_str_buffer(derived_category));
ast_free(derived_category);
}
switch (category_match) {
case ACO_WHITELIST:
case ACO_WHITELIST_EXACT:
@ -1097,14 +1142,15 @@ static int xmldoc_update_config_type(const char *module, const char *name, const
break;
}
if (!ast_strlen_zero(matchfield) && !(tmp = ast_xml_new_child(matchinfo, "field"))) {
ast_log(LOG_WARNING, "Could not add %s attribute for type '%s' in module '%s'\n", matchfield, name, module);
return XMLDOC_STRICT ? -1 : 0;
if (!ast_strlen_zero(matchfield)) {
if (!(tmp = ast_xml_new_child(matchinfo, "field"))) {
ast_log(LOG_WARNING, "Could not add %s attribute for type '%s' in module '%s'\n", matchfield, name, module);
return XMLDOC_STRICT ? -1 : 0;
}
ast_xml_set_attribute(tmp, "name", matchfield);
ast_xml_set_text(tmp, matchvalue);
}
ast_xml_set_attribute(tmp, "name", matchfield);
ast_xml_set_text(tmp, matchvalue);
if (!config_info || !(config_type = find_xmldoc_type(config_info, name))) {
ast_log(LOG_WARNING, "Could not obtain XML documentation item for config type %s\n", name);
return XMLDOC_STRICT ? -1 : 0;