From c32f7910cc552f374f2a81169be1159af9cf52f7 Mon Sep 17 00:00:00 2001 From: Mark Beckwith Date: Thu, 23 Aug 2018 16:04:38 -0500 Subject: [PATCH] param: upgraded json_tok_label Added utility function json_tok_is_num so I would avoid using goto. Signed-off-by: Mark Beckwith --- common/json.c | 11 ++++++ common/json.h | 3 ++ lightningd/invoice.c | 85 +++++++++++--------------------------------- 3 files changed, 34 insertions(+), 65 deletions(-) diff --git a/common/json.c b/common/json.c index 23aab5b8b..d1abe52f0 100644 --- a/common/json.c +++ b/common/json.c @@ -119,6 +119,17 @@ bool json_tok_bitcoin_amount(const char *buffer, const jsmntok_t *tok, return true; } +bool json_tok_is_num(const char *buffer, const jsmntok_t *tok) +{ + if (tok->type != JSMN_PRIMITIVE) + return false; + + for (int i = tok->start; i < tok->end; i++) + if (!cisdigit(buffer[i])) + return false; + return true; +} + bool json_tok_is_null(const char *buffer, const jsmntok_t *tok) { if (tok->type != JSMN_PRIMITIVE) diff --git a/common/json.h b/common/json.h index 02ef93058..c5e5b048e 100644 --- a/common/json.h +++ b/common/json.h @@ -39,6 +39,9 @@ bool json_to_double(const char *buffer, const jsmntok_t *tok, double *num); bool json_tok_bitcoin_amount(const char *buffer, const jsmntok_t *tok, uint64_t *satoshi); +/* Is this a number? [0..9]+ */ +bool json_tok_is_num(const char *buffer, const jsmntok_t *tok); + /* Is this the null primitive? */ bool json_tok_is_null(const char *buffer, const jsmntok_t *tok); diff --git a/lightningd/invoice.c b/lightningd/invoice.c index 88994474c..c8ffcb78a 100644 --- a/lightningd/invoice.c +++ b/lightningd/invoice.c @@ -102,27 +102,24 @@ static bool hsm_sign_b11(const u5 *u5bytes, return true; } -/* We allow a string, or a literal number, for labels */ -static struct json_escaped *json_tok_label(const tal_t *ctx, - const char *buffer, - const jsmntok_t *tok) +static bool json_tok_label(struct command *cmd, const char *name, + const char * buffer, const jsmntok_t *tok, + struct json_escaped **label) { - struct json_escaped *label; - label = json_tok_escaped_string(ctx, buffer, tok); - if (label) - return label; + if ((*label = json_tok_escaped_string(cmd, buffer, tok))) + return true; /* Allow literal numbers */ - if (tok->type != JSMN_PRIMITIVE) - return NULL; + if (json_tok_is_num(buffer, tok) && + ((*label = json_escaped_string_(cmd, buffer + tok->start, + tok->end - tok->start)))) + return true; - for (int i = tok->start; i < tok->end; i++) - if (!cisdigit(buffer[i])) - return NULL; - - return json_escaped_string_(ctx, buffer + tok->start, - tok->end - tok->start); + command_fail(cmd, JSONRPC2_INVALID_PARAMS, + "'%s' should be a string or number, not '%.*s'", + name, tok->end - tok->start, buffer + tok->start); + return false; } static bool parse_fallback(struct command *cmd, @@ -154,10 +151,10 @@ static void json_invoice(struct command *cmd, { struct invoice invoice; const struct invoice_details *details; - const jsmntok_t *msatoshi, *label, *desctok, *fallbacks; + const jsmntok_t *msatoshi, *desctok, *fallbacks; const jsmntok_t *preimagetok; u64 *msatoshi_val; - const struct json_escaped *label_val, *desc; + struct json_escaped *label_val, *desc; const char *desc_val; struct json_result *response = new_json_result(cmd); struct wallet *wallet = cmd->ld->wallet; @@ -169,7 +166,7 @@ static void json_invoice(struct command *cmd, if (!param(cmd, buffer, params, p_req("msatoshi", json_tok_tok, &msatoshi), - p_req("label", json_tok_tok, &label), + p_req("label", json_tok_label, &label_val), p_req("description", json_tok_tok, &desctok), p_opt_def("expiry", json_tok_u64, &expiry, 3600), p_opt("fallbacks", json_tok_tok, &fallbacks), @@ -192,14 +189,6 @@ static void json_invoice(struct command *cmd, return; } } - /* label */ - label_val = json_tok_label(cmd, buffer, label); - if (!label_val) { - command_fail(cmd, JSONRPC2_INVALID_PARAMS, - "label '%.*s' not a string or number", - label->end - label->start, buffer + label->start); - return; - } if (wallet_invoice_find_by_label(wallet, &invoice, label_val)) { command_fail(cmd, INVOICE_LABEL_ALREADY_EXISTS, "Duplicate label '%s'", label_val->s); @@ -366,28 +355,13 @@ static void json_add_invoices(struct json_result *response, static void json_listinvoices(struct command *cmd, const char *buffer, const jsmntok_t *params) { - const jsmntok_t *labeltok; struct json_escaped *label; struct json_result *response = new_json_result(cmd); struct wallet *wallet = cmd->ld->wallet; - if (!param(cmd, buffer, params, - p_opt("label", json_tok_tok, &labeltok), + p_opt("label", json_tok_label, &label), NULL)) return; - - if (labeltok) { - label = json_tok_label(cmd, buffer, labeltok); - if (!label) { - command_fail(cmd, JSONRPC2_INVALID_PARAMS, - "label '%.*s' is not a string or number", - labeltok->end - labeltok->start, - buffer + labeltok->start); - return; - } - } else - label = NULL; - json_object_start(response, NULL); json_array_start(response, "invoices"); json_add_invoices(response, wallet, label); @@ -408,26 +382,18 @@ static void json_delinvoice(struct command *cmd, { struct invoice i; const struct invoice_details *details; - const jsmntok_t *labeltok, *statustok; + const jsmntok_t *statustok; struct json_result *response = new_json_result(cmd); const char *status, *actual_status; struct json_escaped *label; struct wallet *wallet = cmd->ld->wallet; if (!param(cmd, buffer, params, - p_req("label", json_tok_tok, &labeltok), + p_req("label", json_tok_label, &label), p_req("status", json_tok_tok, &statustok), NULL)) return; - label = json_tok_label(cmd, buffer, labeltok); - if (!label) { - command_fail(cmd, JSONRPC2_INVALID_PARAMS, - "label '%.*s' is not a string or number", - labeltok->end - labeltok->start, - buffer + labeltok->start); - return; - } if (!wallet_invoice_find_by_label(wallet, &i, label)) { command_fail(cmd, LIGHTNINGD, "Unknown invoice"); return; @@ -564,24 +530,13 @@ static void json_waitinvoice(struct command *cmd, struct invoice i; const struct invoice_details *details; struct wallet *wallet = cmd->ld->wallet; - const jsmntok_t *labeltok; struct json_escaped *label; if (!param(cmd, buffer, params, - p_req("label", json_tok_tok, &labeltok), + p_req("label", json_tok_label, &label), NULL)) return; - /* Search for invoice */ - label = json_tok_label(cmd, buffer, labeltok); - if (!label) { - command_fail(cmd, JSONRPC2_INVALID_PARAMS, - "label '%.*s' is not a string or number", - labeltok->end - labeltok->start, - buffer + labeltok->start); - return; - } - if (!wallet_invoice_find_by_label(wallet, &i, label)) { command_fail(cmd, LIGHTNINGD, "Label not found"); return;