lightningd/params: fix typesafe check.

typesafe_cb isn't suitable here, as it is simply a conditional cast,
and the result is passed through '...' and doesn't matter.

Reported-by: @wythe
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell
2018-07-07 15:22:14 +09:30
parent dd7afc33ee
commit b14cc0c9f7
2 changed files with 26 additions and 16 deletions

View File

@@ -1,7 +1,6 @@
#ifndef LIGHTNING_LIGHTNINGD_PARAMS_H #ifndef LIGHTNING_LIGHTNINGD_PARAMS_H
#define LIGHTNING_LIGHTNINGD_PARAMS_H #define LIGHTNING_LIGHTNINGD_PARAMS_H
#include "config.h" #include "config.h"
#include <ccan/ccan/typesafe_cb/typesafe_cb.h>
struct param; struct param;
@@ -55,17 +54,17 @@ typedef bool(*param_cb)(const char *buffer, const jsmntok_t *tok, void *arg);
* called with a descriptive error message. * called with a descriptive error message.
* *
* This operation is typesafe; i.e., a compilation error will occur if the types * This operation is typesafe; i.e., a compilation error will occur if the types
* of @arg and the last parameter of @cb do not match. * of @arg and the last parameter of @cb do not match (see the weird 0*sizeof).
* *
* Returns an opaque pointer that can be later used in param_is_set(). * Returns an opaque pointer that can be later used in param_is_set().
*/ */
#define param_req(name, cb, arg) \ #define param_req(name, cb, arg) \
name"", \ name"", \
typesafe_cb_preargs(bool, void *, \ (cb), \
(cb), (arg), \ (arg) + 0*sizeof((cb)((const char *)NULL, \
const char *, \ (const jsmntok_t *)NULL, \
const jsmntok_t *), \ (arg)) == true), \
(arg), 0 0
/* /*
* Similar to above but for optional parameters. * Similar to above but for optional parameters.
* @arg must be the address of a pointer. If found during parsing, it will be * @arg must be the address of a pointer. If found during parsing, it will be
@@ -73,10 +72,21 @@ typedef bool(*param_cb)(const char *buffer, const jsmntok_t *tok, void *arg);
*/ */
#define param_opt(name, cb, arg) \ #define param_opt(name, cb, arg) \
name"", \ name"", \
typesafe_cb_preargs(bool, void *, \ (cb), \
(cb), *(arg), \ (arg) + 0*sizeof((cb)((const char *)NULL, \
const char *, \ (const jsmntok_t *)NULL,\
const jsmntok_t *), \ *(arg)) == true), \
(arg), sizeof(**arg) sizeof(**(arg))
/*
* For when you want an optional raw token.
*
* Note: weird sizeof() does type check that arg really is a (const) jsmntok_t **.
*/
#define param_opt_tok(name, arg) \
name"", \
json_tok_tok, \
(arg) + 0*sizeof(*(arg) == (jsmntok_t *)NULL), \
sizeof(const jsmntok_t *)
#endif /* LIGHTNING_LIGHTNINGD_PARAMS_H */ #endif /* LIGHTNING_LIGHTNINGD_PARAMS_H */

View File

@@ -175,7 +175,7 @@ static void tok_tok(void)
struct json *j = json_parse(cmd, "{}"); struct json *j = json_parse(cmd, "{}");
assert(param_parse(cmd, j->buffer, j->toks, assert(param_parse(cmd, j->buffer, j->toks,
param_opt("satoshi", json_tok_tok, &tok), NULL)); param_opt_tok("satoshi", &tok), NULL));
/* make sure it *is* NULL */ /* make sure it *is* NULL */
assert(tok == NULL); assert(tok == NULL);
@@ -328,7 +328,7 @@ static void bad_programmer(void)
if (setjmp(jump) == 0) { if (setjmp(jump) == 0) {
param_parse(cmd, j->buffer, j->toks, param_parse(cmd, j->buffer, j->toks,
param_req("u64", NULL, &ival), NULL); param_req("u64", (param_cb)NULL, &ival), NULL);
restore_assert(old_stderr); restore_assert(old_stderr);
assert(false); assert(false);
} }
@@ -417,7 +417,7 @@ static void sendpay(void)
if (!param_parse(cmd, j->buffer, j->toks, if (!param_parse(cmd, j->buffer, j->toks,
param_req("route", json_tok_tok, &routetok), param_req("route", json_tok_tok, &routetok),
param_req("cltv", json_tok_number, &cltv), param_req("cltv", json_tok_number, &cltv),
param_opt("note", json_tok_tok, &note), param_opt_tok("note", &note),
param_opt("msatoshi", json_tok_u64, &msatoshi), param_opt("msatoshi", json_tok_u64, &msatoshi),
NULL)) NULL))
assert(false); assert(false);
@@ -439,7 +439,7 @@ static void sendpay_nulltok(void)
if (!param_parse(cmd, j->buffer, j->toks, if (!param_parse(cmd, j->buffer, j->toks,
param_req("route", json_tok_tok, &routetok), param_req("route", json_tok_tok, &routetok),
param_req("cltv", json_tok_number, &cltv), param_req("cltv", json_tok_number, &cltv),
param_opt("note", json_tok_tok, &note), param_opt_tok("note", &note),
param_opt("msatoshi", json_tok_u64, &msatoshi), param_opt("msatoshi", json_tok_u64, &msatoshi),
NULL)) NULL))
assert(false); assert(false);