From b14cc0c9f78c17158e57fca6629dfb21c53cad6d Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Sat, 7 Jul 2018 15:22:14 +0930 Subject: [PATCH] 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 --- lightningd/params.h | 34 ++++++++++++++++++++++------------ lightningd/test/run-params.c | 8 ++++---- 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/lightningd/params.h b/lightningd/params.h index 45e5d3db0..88c0f8c14 100644 --- a/lightningd/params.h +++ b/lightningd/params.h @@ -1,7 +1,6 @@ #ifndef LIGHTNING_LIGHTNINGD_PARAMS_H #define LIGHTNING_LIGHTNINGD_PARAMS_H #include "config.h" -#include 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. * * 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(). */ #define param_req(name, cb, arg) \ name"", \ - typesafe_cb_preargs(bool, void *, \ - (cb), (arg), \ - const char *, \ - const jsmntok_t *), \ - (arg), 0 + (cb), \ + (arg) + 0*sizeof((cb)((const char *)NULL, \ + (const jsmntok_t *)NULL, \ + (arg)) == true), \ + 0 /* * Similar to above but for optional parameters. * @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) \ name"", \ - typesafe_cb_preargs(bool, void *, \ - (cb), *(arg), \ - const char *, \ - const jsmntok_t *), \ - (arg), sizeof(**arg) + (cb), \ + (arg) + 0*sizeof((cb)((const char *)NULL, \ + (const jsmntok_t *)NULL,\ + *(arg)) == true), \ + 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 */ diff --git a/lightningd/test/run-params.c b/lightningd/test/run-params.c index 2ae03c4b4..584b9577e 100644 --- a/lightningd/test/run-params.c +++ b/lightningd/test/run-params.c @@ -175,7 +175,7 @@ static void tok_tok(void) struct json *j = json_parse(cmd, "{}"); 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 */ assert(tok == NULL); @@ -328,7 +328,7 @@ static void bad_programmer(void) if (setjmp(jump) == 0) { 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); assert(false); } @@ -417,7 +417,7 @@ static void sendpay(void) if (!param_parse(cmd, j->buffer, j->toks, param_req("route", json_tok_tok, &routetok), param_req("cltv", json_tok_number, &cltv), - param_opt("note", json_tok_tok, ¬e), + param_opt_tok("note", ¬e), param_opt("msatoshi", json_tok_u64, &msatoshi), NULL)) assert(false); @@ -439,7 +439,7 @@ static void sendpay_nulltok(void) if (!param_parse(cmd, j->buffer, j->toks, param_req("route", json_tok_tok, &routetok), param_req("cltv", json_tok_number, &cltv), - param_opt("note", json_tok_tok, ¬e), + param_opt_tok("note", ¬e), param_opt("msatoshi", json_tok_u64, &msatoshi), NULL)) assert(false);