summaryrefslogtreecommitdiff
path: root/main
diff options
context:
space:
mode:
authorJoshua Colp <jcolp@digium.com>2016-01-25 11:35:21 -0400
committerJoshua Colp <jcolp@digium.com>2016-01-26 11:16:55 -0600
commit1dfd104a276459bf5c7ad07c4f9615b4b8c5e2d4 (patch)
tree5fb35d5b40eed0ef40e71ea84fa6c569a3b8f600 /main
parentf8bf72a417bf5e6d6149b657fa806174b82430ce (diff)
config: Allow options to register when documentation is unavailable.
The config options framework is strict in that configuration options must be documented unless XML documentation support is not available. In practice this is useful as it ensures documentation exists however in off-nominal cases this can cause strange problems. If it is expected that a config option has a non-zero or non-empty default value but the config option documentation is unavailable this reasonable expectation will not be met. This can cause obscure crashes and weirdness depending on how the code handles it. This change tweaks the behavior to ensure that the config option is still allowed to register, apply default values, and be set when devmode is not enabled. If devmode is enabled then the option can NOT be set. This also does not remove the initial documentation error message that is output on load when registering the configuration option. ASTERISK-25725 #close Change-Id: Iec42fca6b35f31326c33fcdc25473f6fd7bc8af8
Diffstat (limited to 'main')
-rw-r--r--main/config_options.c27
1 files changed, 20 insertions, 7 deletions
diff --git a/main/config_options.c b/main/config_options.c
index 4ab7a5b9a..abc6eed78 100644
--- a/main/config_options.c
+++ b/main/config_options.c
@@ -71,6 +71,9 @@ struct aco_option {
aco_option_handler handler;
unsigned int flags;
unsigned int no_doc:1;
+#ifdef AST_DEVMODE
+ unsigned int doc_unavailable:1;
+#endif
unsigned char deprecated:1;
size_t argc;
intptr_t args[0];
@@ -183,18 +186,20 @@ static int link_option_to_types(struct aco_info *info, struct aco_type **types,
ast_log(LOG_ERROR, "Attempting to register option using uninitialized type\n");
return -1;
}
- if (!ao2_link(type->internal->opts, opt)
-#ifdef AST_XML_DOCS
- || (!info->hidden &&
- !opt->no_doc &&
- xmldoc_update_config_option(types, info->module, opt->name, type->name, opt->default_val, opt->match_type == ACO_REGEX, opt->type))
-#endif /* AST_XML_DOCS */
- ) {
+ if (!ao2_link(type->internal->opts, opt)) {
do {
ao2_unlink(types[idx - 1]->internal->opts, opt);
} while (--idx);
return -1;
}
+#ifdef AST_XML_DOCS
+ if (!info->hidden && !opt->no_doc &&
+ xmldoc_update_config_option(types, info->module, opt->name, type->name, opt->default_val, opt->match_type == ACO_REGEX, opt->type)) {
+#ifdef AST_DEVMODE
+ opt->doc_unavailable = 1;
+#endif
+#endif
+ }
}
/* The container(s) should hold the only ref to opt */
ao2_ref(opt, -1);
@@ -716,6 +721,14 @@ int aco_process_var(struct aco_type *type, const char *cat, struct ast_variable
ast_log(LOG_ERROR, "BUG! Somehow a config option for %s/%s was created with no handler!\n", cat, var->name);
return -1;
}
+
+#ifdef AST_DEVMODE
+ if (opt->doc_unavailable) {
+ ast_log(LOG_ERROR, "Config option '%s' of type '%s' is not completely documented and can not be set\n", var->name, type->name);
+ return -1;
+ }
+#endif
+
if (opt->handler(opt, var, obj)) {
ast_log(LOG_ERROR, "Error parsing %s=%s at line %d of %s\n", var->name, var->value, var->lineno, var->file);
return -1;