From: Lennart Poettering Date: Tue, 16 Jan 2024 10:54:20 +0000 (+0100) Subject: json: export json_variant_is_sensitive_recursive() X-Git-Tag: v256-rc1~1134^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c609338b1d7f5c627f93cc57ae2967cfb675c53c;p=thirdparty%2Fsystemd.git json: export json_variant_is_sensitive_recursive() Let's export this function, so that we can use it elsewhere. Also, while at it, let's cache the result in a flag. This is only safe if the result is positive, since we allow the flag to be enabled at any time down thre tree somewhere, which we need to look at. (We never allow it to be turned off however) --- diff --git a/src/shared/json.c b/src/shared/json.c index 0259196e4e2..270aef41051 100644 --- a/src/shared/json.c +++ b/src/shared/json.c @@ -89,6 +89,9 @@ struct JsonVariant { /* Erase from memory when freeing */ bool sensitive:1; + /* True if we know that any referenced json object is marked sensitive */ + bool recursive_sensitive:1; + /* If this is an object the fields are strictly ordered by name */ bool sorted:1; @@ -1453,6 +1456,33 @@ bool json_variant_is_sensitive(JsonVariant *v) { return v->sensitive; } +bool json_variant_is_sensitive_recursive(JsonVariant *v) { + if (!v) + return false; + if (json_variant_is_sensitive(v)) + return true; + if (!json_variant_is_regular(v)) + return false; + if (v->recursive_sensitive) /* Already checked this before */ + return true; + if (!IN_SET(v->type, JSON_VARIANT_ARRAY, JSON_VARIANT_OBJECT)) + return false; + if (v->is_reference) { + if (!json_variant_is_sensitive_recursive(v->reference)) + return false; + + return (v->recursive_sensitive = true); + } + + for (size_t i = 0; i < json_variant_elements(v); i++) + if (json_variant_is_sensitive_recursive(json_variant_by_index(v, i))) + return (v->recursive_sensitive = true); + + /* Note: we only cache the result here in case true, since we allow all elements down the tree to + * have their sensitive flag toggled later on (but never off) */ + return false; +} + static void json_variant_propagate_sensitive(JsonVariant *from, JsonVariant *to) { if (json_variant_is_sensitive(from)) json_variant_sensitive(to); @@ -1773,25 +1803,6 @@ 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 (!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; diff --git a/src/shared/json.h b/src/shared/json.h index 3c20f94b587..156f8e731e4 100644 --- a/src/shared/json.h +++ b/src/shared/json.h @@ -155,6 +155,7 @@ bool json_variant_equal(JsonVariant *a, JsonVariant *b); void json_variant_sensitive(JsonVariant *v); bool json_variant_is_sensitive(JsonVariant *v); +bool json_variant_is_sensitive_recursive(JsonVariant *v); struct json_variant_foreach_state { JsonVariant *variant;