]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-varlink: gracefully reject arrays/maps with a null element
authorFrantisek Sumsal <frantisek@sumsal.cz>
Fri, 20 Mar 2026 19:27:07 +0000 (20:27 +0100)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Sun, 22 Mar 2026 18:37:47 +0000 (19:37 +0100)
Follow-up for 799392286ec0797c0a2a1260c444360b47ef36fc.

src/libsystemd/sd-varlink/sd-varlink-idl.c
src/test/test-varlink-idl.c

index a70cbe529ce29a8ce511025e46712a6f7c6c7bb0..144450b702d26af6eea538bc627723d6f4a1c35f 100644 (file)
@@ -1705,7 +1705,12 @@ static int varlink_idl_validate_symbol(const sd_varlink_symbol *symbol, sd_json_
 static int varlink_idl_validate_field_element_type(const sd_varlink_field *field, sd_json_variant *v) {
         assert(field);
         assert(v);
-        assert(!sd_json_variant_is_null(v));
+
+        if (sd_json_variant_is_null(v))
+                return varlink_idl_log(
+                                SYNTHETIC_ERRNO(EMEDIUMTYPE),
+                                "Field '%s' element is null, refusing.",
+                                strna(field->name));
 
         switch (field->field_type) {
 
@@ -1767,7 +1772,7 @@ static int varlink_idl_validate_field_element_type(const sd_varlink_field *field
 
         case SD_VARLINK_ANY:
                 /* The any type accepts any non-null JSON value, no validation needed. (Note that null is
-                 * already handled by the caller.) */
+                 * already gracefully rejected at the start of this function.) */
                 break;
 
         case _SD_VARLINK_FIELD_COMMENT:
index 039d36a85e42d294a7ad863225e3f2450267f09f..469bf8c2fe08e60173ba360b059f2d1312b7f7df 100644 (file)
@@ -581,4 +581,42 @@ TEST(any) {
         ASSERT_NULL(bad_field);
 }
 
+static SD_VARLINK_DEFINE_METHOD(
+                ArrayTest,
+                SD_VARLINK_DEFINE_INPUT(arr, SD_VARLINK_INT, SD_VARLINK_ARRAY));
+
+static SD_VARLINK_DEFINE_METHOD(
+                MapTest,
+                SD_VARLINK_DEFINE_INPUT(m, SD_VARLINK_STRING, SD_VARLINK_MAP));
+
+TEST(null_array_element) {
+        _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
+
+        /* Build an array with a null element - this should be rejected gracefully, not crash */
+        ASSERT_OK(sd_json_buildo(&v,
+                                 SD_JSON_BUILD_PAIR("arr", SD_JSON_BUILD_ARRAY(
+                                                 SD_JSON_BUILD_INTEGER(1),
+                                                 SD_JSON_BUILD_NULL,
+                                                 SD_JSON_BUILD_INTEGER(3)))));
+
+        const char *bad_field = NULL;
+        ASSERT_ERROR(varlink_idl_validate_method_call(&vl_method_ArrayTest, v, /* flags= */ 0, &bad_field), EMEDIUMTYPE);
+        ASSERT_STREQ(bad_field, "arr");
+}
+
+TEST(null_map_element) {
+        _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
+
+        /* Build a map with a null value - this should be rejected gracefully, not crash */
+        ASSERT_OK(sd_json_buildo(&v,
+                                 SD_JSON_BUILD_PAIR("m", SD_JSON_BUILD_OBJECT(
+                                                 SD_JSON_BUILD_PAIR_STRING("key1", "value1"),
+                                                 SD_JSON_BUILD_PAIR_NULL("key2"),
+                                                 SD_JSON_BUILD_PAIR_STRING("key3", "value3")))));
+
+        const char *bad_field = NULL;
+        ASSERT_ERROR(varlink_idl_validate_method_call(&vl_method_MapTest, v, /* flags= */ 0, &bad_field), EMEDIUMTYPE);
+        ASSERT_STREQ(bad_field, "m");
+}
+
 DEFINE_TEST_MAIN(LOG_DEBUG);