mirror of
https://github.com/ElementsProject/lightning.git
synced 2024-11-19 09:54:16 +01:00
json: Add two param functions to parse string arrs and outpoint arrs
In a couple of places we accept arrays of strings and don't validate them. If we forward them, e.g., call a JSON-RPC method from the plugin, we end up embedding the unverified string in the JSON-RPC call without escaping, which then leads to invalid JSON being passed on. This at least partially causes #4238
This commit is contained in:
parent
eacc54646f
commit
32000b6660
@ -21,6 +21,12 @@ struct wally_psbt;
|
||||
struct bitcoin_txid {
|
||||
struct sha256_double shad;
|
||||
};
|
||||
|
||||
struct bitcoin_outpoint {
|
||||
struct bitcoin_txid txid;
|
||||
u16 n;
|
||||
};
|
||||
|
||||
/* Define bitcoin_txid_eq */
|
||||
STRUCTEQ_DEF(bitcoin_txid, 0, shad.sha.u);
|
||||
|
||||
|
@ -93,6 +93,31 @@ bool json_to_txid(const char *buffer, const jsmntok_t *tok,
|
||||
tok->end - tok->start, txid);
|
||||
}
|
||||
|
||||
bool json_to_outpoint(const char *buffer, const jsmntok_t *tok,
|
||||
struct bitcoin_outpoint *op)
|
||||
{
|
||||
size_t len = tok->end - tok->start;
|
||||
char str[len + 1];
|
||||
|
||||
if (len < 66)
|
||||
return NULL;
|
||||
|
||||
memcpy(str, buffer+tok->start, len);
|
||||
str[len] = 0x00;
|
||||
|
||||
if (str[64] != ':')
|
||||
return NULL;
|
||||
|
||||
if (!bitcoin_txid_from_hex(str, 64, &op->txid))
|
||||
return false;
|
||||
|
||||
op->n = atoi(str + 65);
|
||||
if (op->n < 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool json_to_channel_id(const char *buffer, const jsmntok_t *tok,
|
||||
struct channel_id *cid)
|
||||
{
|
||||
|
@ -62,6 +62,10 @@ bool json_to_msat(const char *buffer, const jsmntok_t *tok,
|
||||
bool json_to_txid(const char *buffer, const jsmntok_t *tok,
|
||||
struct bitcoin_txid *txid);
|
||||
|
||||
/* Extract a bitcoin outpoint from this */
|
||||
bool json_to_outpoint(const char *buffer, const jsmntok_t *tok,
|
||||
struct bitcoin_outpoint *op);
|
||||
|
||||
/* Extract a channel id from this */
|
||||
bool json_to_channel_id(const char *buffer, const jsmntok_t *tok,
|
||||
struct channel_id *cid);
|
||||
|
@ -501,3 +501,32 @@ struct command_result *param_psbt(struct command *cmd,
|
||||
return command_fail_badparam(cmd, name, buffer, tok,
|
||||
"Expected a PSBT");
|
||||
}
|
||||
|
||||
struct command_result *param_outpoint_arr(struct command *cmd,
|
||||
const char *name,
|
||||
const char *buffer,
|
||||
const jsmntok_t *tok,
|
||||
struct bitcoin_outpoint **outpoints)
|
||||
{
|
||||
size_t i;
|
||||
const jsmntok_t *curr;
|
||||
if (tok->type != JSMN_ARRAY) {
|
||||
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||
"Could not decode the outpoint array for %s: "
|
||||
"\"%s\" is not a valid outpoint array.",
|
||||
name, json_strdup(tmpctx, buffer, tok));
|
||||
}
|
||||
|
||||
*outpoints = tal_arr(cmd, struct bitcoin_outpoint, tok->size);
|
||||
|
||||
json_for_each_arr(i, curr, tok) {
|
||||
struct bitcoin_outpoint op;
|
||||
if (!json_to_outpoint(buffer, curr, &op))
|
||||
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||
"Could not decode outpoint \"%.*s\", "
|
||||
"expected format: txid:output",
|
||||
json_tok_full_len(curr), json_tok_full(buffer, curr));
|
||||
(*outpoints)[i] = op;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
@ -11,6 +11,7 @@
|
||||
struct amount_msat;
|
||||
struct amount_sat;
|
||||
struct bitcoin_txid;
|
||||
struct bitcoin_outpoint;
|
||||
struct channel_id;
|
||||
struct command;
|
||||
struct command_result;
|
||||
@ -172,4 +173,13 @@ struct command_result *param_psbt(struct command *cmd,
|
||||
const char *buffer,
|
||||
const jsmntok_t *tok,
|
||||
struct wally_psbt **psbt);
|
||||
|
||||
/**
|
||||
* Parse a list of `txid:output` outpoints.
|
||||
*/
|
||||
struct command_result *param_outpoint_arr(struct command *cmd,
|
||||
const char *name,
|
||||
const char *buffer,
|
||||
const jsmntok_t *tok,
|
||||
struct bitcoin_outpoint **outpoints);
|
||||
#endif /* LIGHTNING_COMMON_JSON_TOK_H */
|
||||
|
@ -52,6 +52,10 @@ bool json_to_channel_id(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEED
|
||||
bool json_to_node_id(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
|
||||
struct node_id *id UNNEEDED)
|
||||
{ fprintf(stderr, "json_to_node_id called!\n"); abort(); }
|
||||
/* Generated stub for json_to_outpoint */
|
||||
bool json_to_outpoint(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
|
||||
struct bitcoin_outpoint *op UNNEEDED)
|
||||
{ fprintf(stderr, "json_to_outpoint called!\n"); abort(); }
|
||||
/* Generated stub for json_to_pubkey */
|
||||
bool json_to_pubkey(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
|
||||
struct pubkey *pubkey UNNEEDED)
|
||||
|
Loading…
Reference in New Issue
Block a user