libplugin: don't turn non-string JSON ids into strings.

When called with `"id": 1` we replied with `"id": "1"`.  lightningd doesn't
actually care, but it's weird.

Copy the entire token: this way we don't have to special case anything.

Also, remove the doubled test in json_add_jsonstr.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2022-12-27 17:39:34 +10:30
parent 9ed138f5e5
commit 2d8fff6b57
5 changed files with 39 additions and 19 deletions

View file

@ -206,7 +206,9 @@ const char *json_get_id(const tal_t *ctx,
const jsmntok_t *idtok = json_get_member(buffer, obj, "id");
if (!idtok)
return NULL;
return json_strdup(ctx, buffer, idtok);
return tal_strndup(ctx,
json_tok_full(buffer, idtok),
json_tok_full_len(idtok));
}
/*-----------------------------------------------------------------------------

View file

@ -66,7 +66,7 @@ const jsmntok_t *json_get_member(const char *buffer, const jsmntok_t tok[],
/* Get index'th array member. */
const jsmntok_t *json_get_arr(const jsmntok_t tok[], size_t index);
/* Helper to get "id" field from object. */
/* Helper to get "id" field from object (including any quotes!). */
const char *json_get_id(const tal_t *ctx,
const char *buffer, const jsmntok_t *obj);

View file

@ -239,9 +239,6 @@ void json_add_jsonstr(struct json_stream *js,
{
char *p;
if (!json_filter_ok(js->filter, fieldname))
return;
/* NOTE: Filtering doesn't really work here! */
if (!json_filter_ok(js->filter, fieldname))
return;
@ -690,3 +687,11 @@ void json_add_lease_rates(struct json_stream *result,
rates->channel_fee_max_proportional_thousandths);
}
void json_add_id(struct json_stream *result, const char *id)
{
char *p;
/* Bypass escape-required assertion in json_out_add */
p = json_member_direct(result, "id", strlen(id));
memcpy(p, id, strlen(id));
}

View file

@ -390,4 +390,7 @@ void json_add_psbt(struct json_stream *stream,
* Note that field names are set */
void json_add_lease_rates(struct json_stream *result,
const struct lease_rates *rates);
/* Add an id field literally (i.e. it's already a JSON primitive or string!) */
void json_add_id(struct json_stream *result, const char *id);
#endif /* LIGHTNING_COMMON_JSON_STREAM_H */

View file

@ -177,14 +177,22 @@ static const char *get_json_id(const tal_t *ctx,
const char *cmd_id,
const char *method)
{
if (cmd_id)
return tal_fmt(ctx, "%s/%s:%s#%"PRIu64,
cmd_id,
plugin->id, method,
plugin->next_outreq_id++);
return tal_fmt(ctx, "%s:%s#%"PRIu64,
plugin->id, method,
plugin->next_outreq_id++);
const char *prefix;
if (cmd_id) {
/* Strip quotes! */
if (strstarts(cmd_id, "\"")) {
assert(strlen(cmd_id) >= 2);
assert(strends(cmd_id, "\""));
prefix = tal_fmt(tmpctx, "%.*s/",
(int)strlen(cmd_id) - 2, cmd_id + 1);
} else
prefix = tal_fmt(tmpctx, "%s/", cmd_id);
} else
prefix = "";
return tal_fmt(ctx, "\"%s%s:%s#%"PRIu64"\"",
prefix, plugin->id, method, plugin->next_outreq_id++);
}
static void destroy_out_req(struct out_req *out_req, struct plugin *plugin)
@ -225,7 +233,7 @@ jsonrpc_request_start_(struct plugin *plugin, struct command *cmd,
out->js = new_json_stream(NULL, cmd, NULL);
json_object_start(out->js, NULL);
json_add_string(out->js, "jsonrpc", "2.0");
json_add_string(out->js, "id", out->id);
json_add_id(out->js, out->id);
json_add_string(out->js, "method", method);
if (out->errcb)
json_object_start(out->js, "params");
@ -251,7 +259,7 @@ static struct json_stream *jsonrpc_stream_start(struct command *cmd)
json_object_start(js, NULL);
json_add_string(js, "jsonrpc", "2.0");
json_add_string(js, "id", cmd->id);
json_add_id(js, cmd->id);
return js;
}
@ -548,10 +556,12 @@ static const jsmntok_t *sync_req(const tal_t *ctx,
const jsmntok_t *contents;
int reqlen;
struct json_out *jout = json_out_new(tmpctx);
const char *id = get_json_id(tmpctx, plugin, "init", method);
json_out_start(jout, NULL, '{');
json_out_addstr(jout, "jsonrpc", "2.0");
json_out_addstr(jout, "id", get_json_id(tmpctx, plugin, "init", method));
/* Copy in id *literally* */
memcpy(json_out_member_direct(jout, "id", strlen(id)), id, strlen(id));
json_out_addstr(jout, "method", method);
json_out_add_splice(jout, "params", params);
if (taken(params))
@ -810,8 +820,8 @@ static void handle_rpc_reply(struct plugin *plugin, const jsmntok_t *toks)
return;
out = strmap_getn(&plugin->out_reqs,
buf + idtok->start,
idtok->end - idtok->start);
json_tok_full(buf, idtok),
json_tok_full_len(idtok));
if (!out) {
/* This can actually happen, if they free req! */
plugin_log(plugin, LOG_DBG, "JSON reply with unknown id '%.*s'",
@ -1376,7 +1386,7 @@ struct json_stream *plugin_notify_start(struct command *cmd, const char *method)
json_add_string(js, "method", method);
json_object_start(js, "params");
json_add_string(js, "id", cmd->id);
json_add_id(js, cmd->id);
return js;
}