From 71c02c7b4c1bc867e4b28d2bd5e1699d4a9a2abe Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 15 Mar 2016 17:07:30 +1030 Subject: [PATCH] daemon: make json_get_param() understand which args are compulsory. So far only one isn't, so this saves us some checks. Signed-off-by: Rusty Russell --- daemon/controlled_time.c | 15 ++++++----- daemon/json.c | 11 +++++++- daemon/json.h | 9 ++++--- daemon/jsonrpc.c | 10 +++----- daemon/peer.c | 54 ++++++++++++++++------------------------ 5 files changed, 51 insertions(+), 48 deletions(-) diff --git a/daemon/controlled_time.c b/daemon/controlled_time.c index 1d8084cda..fbd8d4e0c 100644 --- a/daemon/controlled_time.c +++ b/daemon/controlled_time.c @@ -22,15 +22,18 @@ static void json_mocktime(struct command *cmd, u64 prev_time, mocktime; char mocktimestr[STR_MAX_CHARS(int64_t)]; - json_get_params(buffer, params, - "mocktime", &mocktimetok, - NULL); - - prev_time = controlled_time().ts.tv_sec; - if (!mocktimetok || !json_tok_u64(buffer, mocktimetok, &mocktime)) { + if (!json_get_params(buffer, params, + "mocktime", &mocktimetok, + NULL)) { + command_fail(cmd, "Need mocktime"); + return; + } + if (!json_tok_u64(buffer, mocktimetok, &mocktime)) { command_fail(cmd, "Need valid mocktime"); return; } + + prev_time = controlled_time().ts.tv_sec; mock_time.ts.tv_sec = mocktime; json_object_start(response, NULL); diff --git a/daemon/json.c b/daemon/json.c index 3b5109856..5b6834b7d 100644 --- a/daemon/json.c +++ b/daemon/json.c @@ -195,7 +195,8 @@ const jsmntok_t *json_delve(const char *buffer, return tok; } -void json_get_params(const char *buffer, const jsmntok_t param[], ...) +/* FIXME: Return false if unknown params specified, too! */ +bool json_get_params(const char *buffer, const jsmntok_t param[], ...) { va_list ap; const char *name; @@ -213,6 +214,11 @@ void json_get_params(const char *buffer, const jsmntok_t param[], ...) va_start(ap, param); while ((name = va_arg(ap, const char *)) != NULL) { tokptr = va_arg(ap, const jsmntok_t **); + bool compulsory = true; + if (name[0] == '?') { + name++; + compulsory = false; + } if (param->type == JSMN_ARRAY) { *tokptr = p; if (p) { @@ -229,9 +235,12 @@ void json_get_params(const char *buffer, const jsmntok_t param[], ...) && buffer[(*tokptr)->start] == 'n') { *tokptr = NULL; } + if (compulsory && !*tokptr) + return false; } va_end(ap); + return true; } jsmntok_t *json_parse_input(const char *input, int len, bool *valid) diff --git a/daemon/json.h b/daemon/json.h index 48e6c159f..025d43686 100644 --- a/daemon/json.h +++ b/daemon/json.h @@ -38,11 +38,14 @@ bool json_tok_is_null(const char *buffer, const jsmntok_t *tok); /* Returns next token with same parent. */ const jsmntok_t *json_next(const jsmntok_t *tok); -/* Get the parameters (by position or name). Followed by pairs +/* Get the parameters (by position or name). Followed by triples of * of const char *name, const jsmntok_t **ret_ptr, then NULL. - * *ret_ptr will be set to NULL if it's a literal 'null' or not present. + * + * If name starts with '?' it is optional (and will be set to NULL + * if it's a literal 'null' or not present). + * Otherwise false is returned. */ -void json_get_params(const char *buffer, const jsmntok_t param[], ...); +bool json_get_params(const char *buffer, const jsmntok_t param[], ...); /* Get top-level member. */ const jsmntok_t *json_get_member(const char *buffer, const jsmntok_t tok[], diff --git a/daemon/jsonrpc.c b/daemon/jsonrpc.c index 11c61aebf..196c387df 100644 --- a/daemon/jsonrpc.c +++ b/daemon/jsonrpc.c @@ -154,7 +154,7 @@ static void json_getlog(struct command *cmd, struct log_record *lr = cmd->dstate->log_record; jsmntok_t *level; - json_get_params(buffer, params, "level", &level, NULL); + json_get_params(buffer, params, "?level", &level, NULL); info.num_skipped = 0; @@ -199,11 +199,9 @@ static void json_rhash(struct command *cmd, jsmntok_t *secrettok; struct sha256 secret; - json_get_params(buffer, params, - "secret", &secrettok, - NULL); - - if (!secrettok) { + if (!json_get_params(buffer, params, + "secret", &secrettok, + NULL)) { command_fail(cmd, "Need secret"); return; } diff --git a/daemon/peer.c b/daemon/peer.c index 1dc464b5f..dbb6b385d 100644 --- a/daemon/peer.c +++ b/daemon/peer.c @@ -512,13 +512,11 @@ static void json_connect(struct command *cmd, struct json_connecting *connect; jsmntok_t *host, *port, *satoshis; - json_get_params(buffer, params, - "host", &host, - "port", &port, - "satoshis", &satoshis, - NULL); - - if (!host || !port || !satoshis) { + if (!json_get_params(buffer, params, + "host", &host, + "port", &port, + "satoshis", &satoshis, + NULL)) { command_fail(cmd, "Need host, port and satoshis"); return; } @@ -1395,14 +1393,12 @@ static void json_newhtlc(struct command *cmd, unsigned int expiry; struct newhtlc *newhtlc; - json_get_params(buffer, params, - "peerid", &peeridtok, - "msatoshis", &msatoshistok, - "expiry", &expirytok, - "rhash", &rhashtok, - NULL); - - if (!peeridtok || !msatoshistok || !expirytok || !rhashtok) { + if (!json_get_params(buffer, params, + "peerid", &peeridtok, + "msatoshis", &msatoshistok, + "expiry", &expirytok, + "rhash", &rhashtok, + NULL)) { command_fail(cmd, "Need peerid, msatoshis, expiry and rhash"); return; } @@ -1525,12 +1521,10 @@ static void json_fulfillhtlc(struct command *cmd, struct pubkey peerid; struct fulfillhtlc *fulfillhtlc; - json_get_params(buffer, params, - "peerid", &peeridtok, - "r", &rtok, - NULL); - - if (!peeridtok || !rtok) { + if (!json_get_params(buffer, params, + "peerid", &peeridtok, + "r", &rtok, + NULL)) { command_fail(cmd, "Need peerid and r"); return; } @@ -1615,12 +1609,10 @@ static void json_failhtlc(struct command *cmd, struct pubkey peerid; struct failhtlc *failhtlc; - json_get_params(buffer, params, - "peerid", &peeridtok, - "rhash", &rhashtok, - NULL); - - if (!peeridtok || !rhashtok) { + if (!json_get_params(buffer, params, + "peerid", &peeridtok, + "rhash", &rhashtok, + NULL)) { command_fail(cmd, "Need peerid and rhash"); return; } @@ -1667,11 +1659,9 @@ static void json_close(struct command *cmd, jsmntok_t *peeridtok; struct pubkey peerid; - json_get_params(buffer, params, - "peerid", &peeridtok, - NULL); - - if (!peeridtok) { + if (!json_get_params(buffer, params, + "peerid", &peeridtok, + NULL)) { command_fail(cmd, "Need peerid"); return; }