Browse Source

param: upgraded json_tok_label

Added utility function json_tok_is_num so I would avoid using goto.

Signed-off-by: Mark Beckwith <wythe@intrig.com>
ppa-0.6.1
Mark Beckwith 7 years ago
committed by Rusty Russell
parent
commit
c32f7910cc
  1. 11
      common/json.c
  2. 3
      common/json.h
  3. 87
      lightningd/invoice.c

11
common/json.c

@ -119,6 +119,17 @@ bool json_tok_bitcoin_amount(const char *buffer, const jsmntok_t *tok,
return true; 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) bool json_tok_is_null(const char *buffer, const jsmntok_t *tok)
{ {
if (tok->type != JSMN_PRIMITIVE) if (tok->type != JSMN_PRIMITIVE)

3
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, bool json_tok_bitcoin_amount(const char *buffer, const jsmntok_t *tok,
uint64_t *satoshi); 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? */ /* Is this the null primitive? */
bool json_tok_is_null(const char *buffer, const jsmntok_t *tok); bool json_tok_is_null(const char *buffer, const jsmntok_t *tok);

87
lightningd/invoice.c

@ -102,27 +102,24 @@ static bool hsm_sign_b11(const u5 *u5bytes,
return true; return true;
} }
/* We allow a string, or a literal number, for labels */ static bool json_tok_label(struct command *cmd, const char *name,
static struct json_escaped *json_tok_label(const tal_t *ctx, const char * buffer, const jsmntok_t *tok,
const char *buffer, struct json_escaped **label)
const jsmntok_t *tok)
{ {
struct json_escaped *label;
label = json_tok_escaped_string(ctx, buffer, tok); if ((*label = json_tok_escaped_string(cmd, buffer, tok)))
if (label) return true;
return label;
/* Allow literal numbers */ /* Allow literal numbers */
if (tok->type != JSMN_PRIMITIVE) if (json_tok_is_num(buffer, tok) &&
return NULL; ((*label = json_escaped_string_(cmd, buffer + tok->start,
tok->end - tok->start))))
for (int i = tok->start; i < tok->end; i++) return true;
if (!cisdigit(buffer[i]))
return NULL; command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"'%s' should be a string or number, not '%.*s'",
return json_escaped_string_(ctx, buffer + tok->start, name, tok->end - tok->start, buffer + tok->start);
tok->end - tok->start); return false;
} }
static bool parse_fallback(struct command *cmd, static bool parse_fallback(struct command *cmd,
@ -154,10 +151,10 @@ static void json_invoice(struct command *cmd,
{ {
struct invoice invoice; struct invoice invoice;
const struct invoice_details *details; const struct invoice_details *details;
const jsmntok_t *msatoshi, *label, *desctok, *fallbacks; const jsmntok_t *msatoshi, *desctok, *fallbacks;
const jsmntok_t *preimagetok; const jsmntok_t *preimagetok;
u64 *msatoshi_val; u64 *msatoshi_val;
const struct json_escaped *label_val, *desc; struct json_escaped *label_val, *desc;
const char *desc_val; const char *desc_val;
struct json_result *response = new_json_result(cmd); struct json_result *response = new_json_result(cmd);
struct wallet *wallet = cmd->ld->wallet; struct wallet *wallet = cmd->ld->wallet;
@ -169,7 +166,7 @@ static void json_invoice(struct command *cmd,
if (!param(cmd, buffer, params, if (!param(cmd, buffer, params,
p_req("msatoshi", json_tok_tok, &msatoshi), 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_req("description", json_tok_tok, &desctok),
p_opt_def("expiry", json_tok_u64, &expiry, 3600), p_opt_def("expiry", json_tok_u64, &expiry, 3600),
p_opt("fallbacks", json_tok_tok, &fallbacks), p_opt("fallbacks", json_tok_tok, &fallbacks),
@ -192,14 +189,6 @@ static void json_invoice(struct command *cmd,
return; 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)) { if (wallet_invoice_find_by_label(wallet, &invoice, label_val)) {
command_fail(cmd, INVOICE_LABEL_ALREADY_EXISTS, command_fail(cmd, INVOICE_LABEL_ALREADY_EXISTS,
"Duplicate label '%s'", label_val->s); "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, static void json_listinvoices(struct command *cmd,
const char *buffer, const jsmntok_t *params) const char *buffer, const jsmntok_t *params)
{ {
const jsmntok_t *labeltok;
struct json_escaped *label; struct json_escaped *label;
struct json_result *response = new_json_result(cmd); struct json_result *response = new_json_result(cmd);
struct wallet *wallet = cmd->ld->wallet; struct wallet *wallet = cmd->ld->wallet;
if (!param(cmd, buffer, params, if (!param(cmd, buffer, params,
p_opt("label", json_tok_tok, &labeltok), p_opt("label", json_tok_label, &label),
NULL)) NULL))
return; 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_object_start(response, NULL);
json_array_start(response, "invoices"); json_array_start(response, "invoices");
json_add_invoices(response, wallet, label); json_add_invoices(response, wallet, label);
@ -408,26 +382,18 @@ static void json_delinvoice(struct command *cmd,
{ {
struct invoice i; struct invoice i;
const struct invoice_details *details; const struct invoice_details *details;
const jsmntok_t *labeltok, *statustok; const jsmntok_t *statustok;
struct json_result *response = new_json_result(cmd); struct json_result *response = new_json_result(cmd);
const char *status, *actual_status; const char *status, *actual_status;
struct json_escaped *label; struct json_escaped *label;
struct wallet *wallet = cmd->ld->wallet; struct wallet *wallet = cmd->ld->wallet;
if (!param(cmd, buffer, params, 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), p_req("status", json_tok_tok, &statustok),
NULL)) NULL))
return; 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)) { if (!wallet_invoice_find_by_label(wallet, &i, label)) {
command_fail(cmd, LIGHTNINGD, "Unknown invoice"); command_fail(cmd, LIGHTNINGD, "Unknown invoice");
return; return;
@ -564,24 +530,13 @@ static void json_waitinvoice(struct command *cmd,
struct invoice i; struct invoice i;
const struct invoice_details *details; const struct invoice_details *details;
struct wallet *wallet = cmd->ld->wallet; struct wallet *wallet = cmd->ld->wallet;
const jsmntok_t *labeltok;
struct json_escaped *label; struct json_escaped *label;
if (!param(cmd, buffer, params, if (!param(cmd, buffer, params,
p_req("label", json_tok_tok, &labeltok), p_req("label", json_tok_label, &label),
NULL)) NULL))
return; 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)) { if (!wallet_invoice_find_by_label(wallet, &i, label)) {
command_fail(cmd, LIGHTNINGD, "Label not found"); command_fail(cmd, LIGHTNINGD, "Label not found");
return; return;

Loading…
Cancel
Save