Browse Source

plugins: use stricter parsing for option values

also: convert the stored int value from 'int' to 's64'

atoi fails silently, returning a zero. instead we use the more robust
strtoll which will allow us fail with an error.

we also make the parsing for bools stricter, only allowing plausibly
boolean values to parse.
travis-debug
lisa neigut 5 years ago
committed by Rusty Russell
parent
commit
cac5a0cd1d
  1. 46
      lightningd/plugin.c
  2. 2
      lightningd/plugin.h

46
lightningd/plugin.c

@ -466,13 +466,37 @@ struct io_plan *plugin_stdout_conn_init(struct io_conn *conn,
char *plugin_opt_set(const char *arg, struct plugin_opt *popt) char *plugin_opt_set(const char *arg, struct plugin_opt *popt)
{ {
char *endp;
long long l;
tal_free(popt->value->as_str); tal_free(popt->value->as_str);
popt->value->as_str = tal_strdup(popt, arg); popt->value->as_str = tal_strdup(popt, arg);
if (streq(popt->type, "int")) if (streq(popt->type, "int")) {
*popt->value->as_int = atoi(arg); errno = 0;
else if (streq(popt->type, "bool")) l = strtoll(arg, &endp, 0);
*popt->value->as_bool = streq(arg, "true") || streq(arg, "True") if (errno || *endp)
|| streq(arg, "1"); return tal_fmt(tmpctx, "%s does not parse as type %s",
popt->value->as_str, popt->type);
*popt->value->as_int = l;
/* Check if the number did not fit in `s64` (in case `long long`
* is a bigger type). */
if (*popt->value->as_int != l)
return tal_fmt(tmpctx, "%s does not parse as type %s (overflowed)",
popt->value->as_str, popt->type);
} else if (streq(popt->type, "bool")) {
/* valid values are 'true', 'True', '1', '0', 'false', 'False', or '' */
if (streq(arg, "true") || streq(arg, "True") || streq(arg, "1")) {
*popt->value->as_bool = true;
} else if (streq(arg, "false") || streq(arg, "False")
|| streq(arg, "0") || streq(arg, "")) {
*popt->value->as_bool = false;
} else
return tal_fmt(tmpctx, "%s does not parse as type %s",
popt->value->as_str, popt->type);
}
return NULL; return NULL;
} }
@ -509,12 +533,12 @@ static bool plugin_opt_add(struct plugin *plugin, const char *buffer,
} }
} else if (json_tok_streq(buffer, typetok, "int")) { } else if (json_tok_streq(buffer, typetok, "int")) {
popt->type = "int"; popt->type = "int";
popt->value->as_int = talz(popt->value, int); popt->value->as_int = talz(popt->value, s64);
if (defaulttok) { if (defaulttok) {
json_to_int(buffer, defaulttok, popt->value->as_int); json_to_s64(buffer, defaulttok, popt->value->as_int);
popt->value->as_str = tal_fmt(popt->value, "%d", *popt->value->as_int); popt->value->as_str = tal_fmt(popt->value, "%"PRIu64, *popt->value->as_int);
popt->description = tal_fmt( popt->description = tal_fmt(
popt, "%.*s (default: %i)", desctok->end - desctok->start, popt, "%.*s (default: %"PRIu64")", desctok->end - desctok->start,
buffer + desctok->start, *popt->value->as_int); buffer + desctok->start, *popt->value->as_int);
} }
} else if (json_tok_streq(buffer, typetok, "bool")) { } else if (json_tok_streq(buffer, typetok, "bool")) {
@ -535,7 +559,7 @@ static bool plugin_opt_add(struct plugin *plugin, const char *buffer,
popt->description = json_strdup(popt, buffer, desctok); popt->description = json_strdup(popt, buffer, desctok);
list_add_tail(&plugin->plugin_opts, &popt->list); list_add_tail(&plugin->plugin_opts, &popt->list);
opt_register_arg(popt->name, plugin_opt_set, NULL, popt, opt_register_arg(popt->name, plugin_opt_set, NULL, popt,
popt->description); popt->description);
return true; return true;
} }
@ -1185,7 +1209,7 @@ void json_add_opt_plugins(struct json_stream *response,
if (opt->value->as_bool) { if (opt->value->as_bool) {
json_add_bool(response, opt_name, opt->value->as_bool); json_add_bool(response, opt_name, opt->value->as_bool);
} else if (opt->value->as_int) { } else if (opt->value->as_int) {
json_add_s32(response, opt_name, *opt->value->as_int); json_add_s64(response, opt_name, *opt->value->as_int);
} else if (opt->value->as_str) { } else if (opt->value->as_str) {
json_add_string(response, opt_name, opt->value->as_str); json_add_string(response, opt_name, opt->value->as_str);
} else { } else {

2
lightningd/plugin.h

@ -114,7 +114,7 @@ struct plugins {
*/ */
struct plugin_opt_value { struct plugin_opt_value {
char *as_str; char *as_str;
int *as_int; s64 *as_int;
bool *as_bool; bool *as_bool;
}; };

Loading…
Cancel
Save