json: add JSON_FORMAT_REFUSE_SENSITIVE to json_variant_format()
Returns -EPERM if any node in the variant is marked as sensitive, useful to avoid leaking data to log messages and so on
This commit is contained in:
@@ -1771,6 +1771,28 @@ static int json_format(FILE *f, JsonVariant *v, JsonFormatFlags flags, const cha
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool json_variant_is_sensitive_recursive(JsonVariant *v) {
|
||||
if (!v)
|
||||
return false;
|
||||
if (json_variant_is_sensitive(v))
|
||||
return true;
|
||||
if (v == JSON_VARIANT_MAGIC_EMPTY_ARRAY ||
|
||||
v == JSON_VARIANT_MAGIC_EMPTY_OBJECT)
|
||||
return false;
|
||||
if (!json_variant_is_regular(v))
|
||||
return false;
|
||||
if (!IN_SET(v->type, JSON_VARIANT_ARRAY, JSON_VARIANT_OBJECT))
|
||||
return false;
|
||||
if (v->is_reference)
|
||||
return json_variant_is_sensitive_recursive(v->reference);
|
||||
|
||||
for (size_t i = 0; i < json_variant_elements(v); i++)
|
||||
if (json_variant_is_sensitive_recursive(json_variant_by_index(v, i)))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int json_variant_format(JsonVariant *v, JsonFormatFlags flags, char **ret) {
|
||||
_cleanup_(memstream_done) MemStream m = {};
|
||||
size_t sz;
|
||||
@@ -1786,6 +1808,10 @@ int json_variant_format(JsonVariant *v, JsonFormatFlags flags, char **ret) {
|
||||
if (flags & JSON_FORMAT_OFF)
|
||||
return -ENOEXEC;
|
||||
|
||||
if ((flags & JSON_FORMAT_REFUSE_SENSITIVE))
|
||||
if (json_variant_is_sensitive_recursive(v))
|
||||
return -EPERM;
|
||||
|
||||
f = memstream_init(&m);
|
||||
if (!f)
|
||||
return -ENOMEM;
|
||||
|
||||
+12
-11
@@ -185,17 +185,18 @@ struct json_variant_foreach_state {
|
||||
int json_variant_get_source(JsonVariant *v, const char **ret_source, unsigned *ret_line, unsigned *ret_column);
|
||||
|
||||
typedef enum JsonFormatFlags {
|
||||
JSON_FORMAT_NEWLINE = 1 << 0, /* suffix with newline */
|
||||
JSON_FORMAT_PRETTY = 1 << 1, /* add internal whitespace to appeal to human readers */
|
||||
JSON_FORMAT_PRETTY_AUTO = 1 << 2, /* same, but only if connected to a tty (and JSON_FORMAT_NEWLINE otherwise) */
|
||||
JSON_FORMAT_COLOR = 1 << 3, /* insert ANSI color sequences */
|
||||
JSON_FORMAT_COLOR_AUTO = 1 << 4, /* insert ANSI color sequences if colors_enabled() says so */
|
||||
JSON_FORMAT_SOURCE = 1 << 5, /* prefix with source filename/line/column */
|
||||
JSON_FORMAT_SSE = 1 << 6, /* prefix/suffix with W3C server-sent events */
|
||||
JSON_FORMAT_SEQ = 1 << 7, /* prefix/suffix with RFC 7464 application/json-seq */
|
||||
JSON_FORMAT_FLUSH = 1 << 8, /* call fflush() after dumping JSON */
|
||||
JSON_FORMAT_EMPTY_ARRAY = 1 << 9, /* output "[]" for empty input */
|
||||
JSON_FORMAT_OFF = 1 << 10, /* make json_variant_format() fail with -ENOEXEC */
|
||||
JSON_FORMAT_NEWLINE = 1 << 0, /* suffix with newline */
|
||||
JSON_FORMAT_PRETTY = 1 << 1, /* add internal whitespace to appeal to human readers */
|
||||
JSON_FORMAT_PRETTY_AUTO = 1 << 2, /* same, but only if connected to a tty (and JSON_FORMAT_NEWLINE otherwise) */
|
||||
JSON_FORMAT_COLOR = 1 << 3, /* insert ANSI color sequences */
|
||||
JSON_FORMAT_COLOR_AUTO = 1 << 4, /* insert ANSI color sequences if colors_enabled() says so */
|
||||
JSON_FORMAT_SOURCE = 1 << 5, /* prefix with source filename/line/column */
|
||||
JSON_FORMAT_SSE = 1 << 6, /* prefix/suffix with W3C server-sent events */
|
||||
JSON_FORMAT_SEQ = 1 << 7, /* prefix/suffix with RFC 7464 application/json-seq */
|
||||
JSON_FORMAT_FLUSH = 1 << 8, /* call fflush() after dumping JSON */
|
||||
JSON_FORMAT_EMPTY_ARRAY = 1 << 9, /* output "[]" for empty input */
|
||||
JSON_FORMAT_OFF = 1 << 10, /* make json_variant_format() fail with -ENOEXEC */
|
||||
JSON_FORMAT_REFUSE_SENSITIVE = 1 << 11, /* return EPERM if any node in the tree is marked as senstitive */
|
||||
} JsonFormatFlags;
|
||||
|
||||
int json_variant_format(JsonVariant *v, JsonFormatFlags flags, char **ret);
|
||||
|
||||
Reference in New Issue
Block a user