confmgt: when an int/enum value is invalid, say which values are ok.

Part of 33460.
This commit is contained in:
Nick Mathewson 2020-02-26 12:40:53 -05:00
parent 7b42502869
commit b133325a3e
2 changed files with 36 additions and 14 deletions

View file

@ -121,8 +121,9 @@ int_parse(void *target, const char *value, char **errmsg, const void *params)
int ok=0;
*p = (int)tor_parse_long(value, 10, pp->minval, pp->maxval, &ok, NULL);
if (!ok) {
tor_asprintf(errmsg, "Integer %s is malformed or out of bounds.",
value);
tor_asprintf(errmsg, "Integer %s is malformed or out of bounds. "
"Allowed values are between %d and %d.",
value, pp->minval, pp->maxval);
return -1;
}
return 0;
@ -348,11 +349,17 @@ typedef struct enumeration_table_t {
int value;
} enumeration_table_t;
typedef struct enumeration_params_t {
const char *allowed_val_string;
const enumeration_table_t *table;
} enumeration_params_t;
static int
enum_parse(void *target, const char *value, char **errmsg,
const void *params)
const void *params_)
{
const enumeration_table_t *table = params;
const enumeration_params_t *params = params_;
const enumeration_table_t *table = params->table;
int *p = (int *)target;
for (; table->name; ++table) {
if (!strcasecmp(value, table->name)) {
@ -360,15 +367,17 @@ enum_parse(void *target, const char *value, char **errmsg,
return 0;
}
}
tor_asprintf(errmsg, "Unrecognized value %s.", value);
tor_asprintf(errmsg, "Unrecognized value %s. %s",
value, params->allowed_val_string);
return -1;
}
static char *
enum_encode(const void *value, const void *params)
enum_encode(const void *value, const void *params_)
{
int v = *(const int*)value;
const enumeration_table_t *table = params;
const enumeration_params_t *params = params_;
const enumeration_table_t *table = params->table;
for (; table->name; ++table) {
if (v == table->value)
return tor_strdup(table->name);
@ -377,19 +386,21 @@ enum_encode(const void *value, const void *params)
}
static void
enum_clear(void *value, const void *params)
enum_clear(void *value, const void *params_)
{
int *p = (int*)value;
const enumeration_table_t *table = params;
const enumeration_params_t *params = params_;
const enumeration_table_t *table = params->table;
tor_assert(table->name);
*p = table->value;
}
static bool
enum_ok(const void *value, const void *params)
enum_ok(const void *value, const void *params_)
{
int v = *(const int*)value;
const enumeration_table_t *table = params;
const enumeration_params_t *params = params_;
const enumeration_table_t *table = params->table;
for (; table->name; ++table) {
if (v == table->value)
return true;
@ -403,6 +414,11 @@ static const enumeration_table_t enum_table_bool[] = {
{ NULL, 0 },
};
static const enumeration_params_t enum_params_bool = {
"Allowed values are 0 and 1.",
enum_table_bool
};
static const enumeration_table_t enum_table_autobool[] = {
{ "0", 0 },
{ "1", 1 },
@ -410,6 +426,11 @@ static const enumeration_table_t enum_table_autobool[] = {
{ NULL, 0 },
};
static const enumeration_params_t enum_params_autobool = {
"Allowed values are 0, 1, and auto.",
enum_table_autobool
};
static const var_type_fns_t enum_fns = {
.parse = enum_parse,
.encode = enum_encode,
@ -740,10 +761,10 @@ const var_type_def_t DOUBLE_type_defn = {
.name="Float", .fns=&double_fns, };
const var_type_def_t BOOL_type_defn = {
.name="Boolean", .fns=&enum_fns,
.params=&enum_table_bool };
.params=&enum_params_bool };
const var_type_def_t AUTOBOOL_type_defn = {
.name="Boolean+Auto", .fns=&enum_fns,
.params=&enum_table_autobool };
.params=&enum_params_autobool };
const var_type_def_t ISOTIME_type_defn = {
.name="Time", .fns=&time_fns, };
const var_type_def_t CSV_type_defn = {

View file

@ -4276,7 +4276,8 @@ test_options_trial_assign(void *arg)
tt_int_op(r, OP_EQ, 0);
v = options_trial_assign(lines, 0, &msg);
tt_int_op(v, OP_EQ, SETOPT_ERR_PARSE);
tt_str_op(msg, OP_EQ, "Unrecognized value ambidextrous.");
tt_str_op(msg, OP_EQ,
"Unrecognized value ambidextrous. Allowed values are 0 and 1.");
tor_free(msg);
config_free_lines(lines);