libplugin: add command_finish_rawstr() for when we're simply repeating an entore response.
What changed, and why it matters
This commit adds a new helper function that lets plugin code send a pre-built JSON response directly, instead of building it piece by piece. It is a straightforward internal code refactor with no obvious security relevance.
No security action required; review as normal code-quality change.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch introduces command_finish_rawstr() in libplugin, which creates a json_stream, writes a caller-supplied raw JSON string into it via json_out_direct()/memcpy(), and completes the command without adding an extra enclosing JSON object. The existing command_complete() logic is split so the new helper can reuse the non-JSON-finalization completion path. There is no change to parsing, validation, authentication, or network handling.
Changed components
plugins/libplugin.cplugins/libplugin.hInspect captured patch +31 / −4
diff --git a/plugins/libplugin.c b/plugins/libplugin.c
index 7f4db9f4..ed888bdb 100644
--- a/plugins/libplugin.c
+++ b/plugins/libplugin.c
@@ -473,11 +473,9 @@ struct json_stream *jsonrpc_stream_fail_data(struct command *cmd,
return js;
}
-static struct command_result *command_complete(struct command *cmd,
- struct json_stream *result)
+static struct command_result *command_complete_nojson(struct command *cmd,
+ struct json_stream *result)
{
- /* Global object */
- json_object_end(result);
json_stream_close(result, cmd);
ld_send(cmd->plugin, result);
tal_free(cmd);
@@ -485,6 +483,14 @@ static struct command_result *command_complete(struct command *cmd,
return &complete;
}
+static struct command_result *command_complete(struct command *cmd,
+ struct json_stream *result)
+{
+ /* Global object */
+ json_object_end(result);
+ return command_complete_nojson(cmd, result);
+}
+
struct command_result *command_finished(struct command *cmd,
struct json_stream *response)
{
@@ -506,6 +512,20 @@ struct command_result *command_finished(struct command *cmd,
return command_complete(cmd, response);
}
+struct command_result *command_finish_rawstr(struct command *cmd,
+ const char *json,
+ size_t json_len)
+{
+ struct json_stream *js = new_json_stream(cmd, cmd, NULL);
+ char *raw;
+
+ assert(cmd->type == COMMAND_TYPE_NORMAL
+ || cmd->type == COMMAND_TYPE_HOOK);
+ raw = json_out_direct(js->jout, json_len);
+ memcpy(raw, json, json_len);
+ return command_complete_nojson(cmd, js);
+}
+
struct command_result *WARN_UNUSED_RESULT
command_still_pending(struct command *cmd)
{
diff --git a/plugins/libplugin.h b/plugins/libplugin.h
index 6b3ad7bf..28772184 100644
--- a/plugins/libplugin.h
+++ b/plugins/libplugin.h
@@ -363,6 +363,13 @@ WARN_UNUSED_RESULT
struct command_result *command_still_pending(struct command *cmd)
NON_NULL_ARGS(1);
+/* Forward this raw JSON string as the command response */
+WARN_UNUSED_RESULT
+struct command_result *command_finish_rawstr(struct command *cmd,
+ const char *json,
+ size_t json_len)
+ NO_NULL_ARGS;
+
/* Helper to create a zero or single-value JSON object; if @str is NULL,
* object is empty. */
struct json_out *json_out_obj(const tal_t *ctx,
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.