]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
json: export json_variant_is_sensitive_recursive()
authorLennart Poettering <lennart@poettering.net>
Tue, 16 Jan 2024 10:54:20 +0000 (11:54 +0100)
committerLennart Poettering <lennart@poettering.net>
Tue, 16 Jan 2024 16:16:18 +0000 (17:16 +0100)
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)

src/shared/json.c
src/shared/json.h

index 0259196e4e2b9b34ccb89c70968829b891c50dfe..270aef41051d30093fbfa5460cc5824067b3452f 100644 (file)
@@ -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;
index 3c20f94b5874fc33584c950eb5e41986807660db..156f8e731e4e6fb7f4f64fd55f67269886e58016 100644 (file)
@@ -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;