Skip to content

Commit

Permalink
common/json_stream: support filtering don't print fields not allowed.
Browse files Browse the repository at this point in the history
Signed-off-by: Rusty Russell <[email protected]>
  • Loading branch information
rustyrussell committed Nov 9, 2022
1 parent 22c42de commit f0731d2
Show file tree
Hide file tree
Showing 7 changed files with 88 additions and 19 deletions.
85 changes: 66 additions & 19 deletions common/json_stream.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,15 @@
#include <ccan/json_escape/json_escape.h>
#include <ccan/json_out/json_out.h>
#include <ccan/str/hex/hex.h>
#include <ccan/strmap/strmap.h>
#include <ccan/tal/str/str.h>
#include <common/channel_id.h>
#include <common/configdir.h>
#include <common/json_filter.h>
#include <common/json_parse.h>
#include <common/json_stream.h>
#include <common/node_id.h>
#include <common/type_to_string.h>
#include <common/utils.h>
#include <common/wireaddr.h>
#include <inttypes.h>
#include <stdio.h>
Expand Down Expand Up @@ -46,9 +48,29 @@ struct json_stream *new_json_stream(const tal_t *ctx,
js->writer = writer;
js->reader = NULL;
js->log = log;
js->filter = NULL;
return js;
}

void json_stream_attach_filter(struct json_stream *js,
struct json_filter *filter STEALS)
{
assert(!js->filter);
js->filter = tal_steal(js, filter);
}

const char *json_stream_detach_filter(const tal_t *ctx, struct json_stream *js)
{
const char *err;
assert(js->filter);
/* Should be well-formed at this point! */
assert(json_filter_finished(js->filter));

err = json_filter_misused(ctx, js->filter);
js->filter = tal_free(js->filter);
return err;
}

struct json_stream *json_stream_dup(const tal_t *ctx,
struct json_stream *original,
struct log *log)
Expand All @@ -57,6 +79,8 @@ struct json_stream *json_stream_dup(const tal_t *ctx,

js->jout = json_out_dup(js, original->jout);
js->log = log;
/* You can't dup things with filters! */
assert(!js->filter);
return js;
}

Expand All @@ -83,6 +107,8 @@ void json_stream_append(struct json_stream *js,
{
char *dest;

/* Only on low-level streams! */
assert(!js->filter);
dest = json_out_direct(js->jout, len);
memcpy(dest, str, len);
}
Expand Down Expand Up @@ -115,7 +141,7 @@ void json_stream_close(struct json_stream *js, struct command *writer)
* I used to assert(writer); here. */
assert(js->writer == writer);

/* Should be well-formed at this point! */
assert(!js->filter);
json_stream_double_cr(js);
json_stream_flush(js);
js->writer = NULL;
Expand All @@ -130,22 +156,26 @@ void json_stream_flush(struct json_stream *js)

void json_array_start(struct json_stream *js, const char *fieldname)
{
json_out_start(js->jout, fieldname, '[');
if (json_filter_down(&js->filter, fieldname))
json_out_start(js->jout, fieldname, '[');
}

void json_array_end(struct json_stream *js)
{
json_out_end(js->jout, ']');
if (json_filter_up(&js->filter))
json_out_end(js->jout, ']');
}

void json_object_start(struct json_stream *js, const char *fieldname)
{
json_out_start(js->jout, fieldname, '{');
if (json_filter_down(&js->filter, fieldname))
json_out_start(js->jout, fieldname, '{');
}

void json_object_end(struct json_stream *js)
{
json_out_end(js->jout, '}');
if (json_filter_up(&js->filter))
json_out_end(js->jout, '}');
}

void json_add_primitive_fmt(struct json_stream *js,
Expand All @@ -154,9 +184,11 @@ void json_add_primitive_fmt(struct json_stream *js,
{
va_list ap;

va_start(ap, fmt);
json_out_addv(js->jout, fieldname, false, fmt, ap);
va_end(ap);
if (json_filter_ok(js->filter, fieldname)) {
va_start(ap, fmt);
json_out_addv(js->jout, fieldname, false, fmt, ap);
va_end(ap);
}
}

void json_add_str_fmt(struct json_stream *js,
Expand All @@ -165,9 +197,11 @@ void json_add_str_fmt(struct json_stream *js,
{
va_list ap;

va_start(ap, fmt);
json_out_addv(js->jout, fieldname, true, fmt, ap);
va_end(ap);
if (json_filter_ok(js->filter, fieldname)) {
va_start(ap, fmt);
json_out_addv(js->jout, fieldname, true, fmt, ap);
va_end(ap);
}
}

void json_add_primitive(struct json_stream *js,
Expand All @@ -183,7 +217,8 @@ void json_add_string(struct json_stream *js,
const char *fieldname,
const char *str TAKES)
{
json_out_addstr(js->jout, fieldname, str);
if (json_filter_ok(js->filter, fieldname))
json_out_addstr(js->jout, fieldname, str);
if (taken(str))
tal_free(str);
}
Expand All @@ -204,6 +239,13 @@ 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;

p = json_member_direct(js, fieldname, jsonstrlen);
memcpy(p, jsonstr, jsonstrlen);
}
Expand Down Expand Up @@ -321,13 +363,15 @@ void json_add_hex_talarr(struct json_stream *result,
void json_add_escaped_string(struct json_stream *result, const char *fieldname,
const struct json_escape *esc TAKES)
{
/* Already escaped, don't re-escape! */
char *dest = json_member_direct(result, fieldname,
1 + strlen(esc->s) + 1);
if (json_filter_ok(result->filter, fieldname)) {
/* Already escaped, don't re-escape! */
char *dest = json_member_direct(result, fieldname,
1 + strlen(esc->s) + 1);

dest[0] = '"';
memcpy(dest + 1, esc->s, strlen(esc->s));
dest[1+strlen(esc->s)] = '"';
dest[0] = '"';
memcpy(dest + 1, esc->s, strlen(esc->s));
dest[1+strlen(esc->s)] = '"';
}
if (taken(esc))
tal_free(esc);
}
Expand Down Expand Up @@ -373,6 +417,9 @@ void json_add_tok(struct json_stream *result, const char *fieldname,
char *space;
assert(tok->type != JSMN_UNDEFINED);

if (!json_filter_ok(result->filter, fieldname))
return;

space = json_member_direct(result, fieldname, json_tok_full_len(tok));
memcpy(space, json_tok_full(buffer, tok), json_tok_full_len(tok));
}
Expand Down
12 changes: 12 additions & 0 deletions common/json_stream.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <ccan/time/time.h>
#include <common/amount.h>
#include <common/jsonrpc_errors.h>
#include <common/utils.h>

struct command;
struct io_conn;
Expand Down Expand Up @@ -48,6 +49,9 @@ struct json_stream {
void *reader_arg;
size_t len_read;

/* If non-NULL, reflects the current filter position */
struct json_filter *filter;

/* Where to log I/O */
struct log *log;
};
Expand Down Expand Up @@ -78,6 +82,14 @@ struct json_stream *json_stream_dup(const tal_t *ctx,
struct json_stream *original,
struct log *log);

/* Attach a filter. Usually this works at the result level: you don't
* want to filter out id, etc! */
void json_stream_attach_filter(struct json_stream *js,
struct json_filter *filter STEALS);

/* Detach the filter: returns non-NULL string if it was misused. */
const char *json_stream_detach_filter(const tal_t *ctx, struct json_stream *js);

/**
* json_stream_close - finished writing to a JSON stream.
* @js: the json_stream.
Expand Down
3 changes: 3 additions & 0 deletions common/test/run-json.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ bool json_filter_down(struct json_filter **filter UNNEEDED, const char *member U
/* Generated stub for json_filter_finished */
bool json_filter_finished(const struct json_filter *filter UNNEEDED)
{ fprintf(stderr, "json_filter_finished called!\n"); abort(); }
/* Generated stub for json_filter_misused */
const char *json_filter_misused(const tal_t *ctx UNNEEDED, const struct json_filter *f UNNEEDED)
{ fprintf(stderr, "json_filter_misused called!\n"); abort(); }
/* Generated stub for json_filter_ok */
bool json_filter_ok(const struct json_filter *filter UNNEEDED, const char *member UNNEEDED)
{ fprintf(stderr, "json_filter_ok called!\n"); abort(); }
Expand Down
4 changes: 4 additions & 0 deletions common/test/run-param.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "config.h"
#include "../json_filter.c"
#include "../json_parse.c"
#include "../json_parse_simple.c"
#include "../json_param.c"
Expand Down Expand Up @@ -35,6 +36,9 @@ struct command_result *command_fail(struct command *cmd,
}

/* AUTOGENERATED MOCKS START */
/* Generated stub for command_filter_ptr */
struct json_filter **command_filter_ptr(struct command *cmd UNNEEDED)
{ fprintf(stderr, "command_filter_ptr called!\n"); abort(); }
/* Generated stub for deprecated_apis */
bool deprecated_apis;
/* Generated stub for fromwire_tlv */
Expand Down
1 change: 1 addition & 0 deletions lightningd/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ LIGHTNINGD_COMMON_OBJS := \
common/htlc_wire.o \
common/key_derive.o \
common/keyset.o \
common/json_filter.o \
common/json_param.o \
common/json_parse.o \
common/json_parse_simple.o \
Expand Down
1 change: 1 addition & 0 deletions plugins/bkpr/test/run-bkpr_db.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ void db_fatal(const char *fmt, ...)
}
#endif /* DB_FATAL */

#include "common/json_filter.c"
#include "plugins/bkpr/db.c"
#include "plugins/libplugin.c"

Expand Down
1 change: 1 addition & 0 deletions plugins/bkpr/test/run-recorder.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "config.h"
#include "common/json_filter.c"
#include "test_utils.h"

#include "plugins/libplugin.c"
Expand Down

0 comments on commit f0731d2

Please sign in to comment.