chiark / gitweb /
util: introduce our own gperf based capability list
[elogind.git] / src / libsystemd / sd-bus / bus-objects.c
index ecac73a94dd8fe1a1acae4470e78c464685969c7..6162d12c1d38854776a9c8a2f47078d89044843a 100644 (file)
@@ -617,6 +617,9 @@ static int property_get_set_callbacks_run(
                         return r;
 
         } else {
+                const char *signature = NULL;
+                char type = 0;
+
                 if (c->vtable->type != _SD_BUS_VTABLE_WRITABLE_PROPERTY)
                         return sd_bus_reply_method_errorf(m, SD_BUS_ERROR_PROPERTY_READ_ONLY, "Property '%s' is not writable.", c->member);
 
@@ -628,6 +631,13 @@ static int property_get_set_callbacks_run(
 
                 c->last_iteration = bus->iteration_counter;
 
+                r = sd_bus_message_peek_type(m, &type, &signature);
+                if (r < 0)
+                        return r;
+
+                if (type != 'v' || !streq(strempty(signature), strempty(c->vtable->x.property.signature)))
+                        return sd_bus_reply_method_errorf(m, SD_BUS_ERROR_INVALID_ARGS, "Incorrect parameters for property '%s', expected '%s', got '%s'.", c->member, strempty(c->vtable->x.property.signature), strempty(signature));
+
                 r = sd_bus_message_enter_container(m, 'v', c->vtable->x.property.signature);
                 if (r < 0)
                         return r;
@@ -820,7 +830,7 @@ static int property_get_all_callbacks_run(
         return 1;
 }
 
-static bool bus_node_exists(
+static int bus_node_exists(
                 sd_bus *bus,
                 struct node *n,
                 const char *path,
@@ -828,6 +838,7 @@ static bool bus_node_exists(
 
         struct node_vtable *c;
         struct node_callback *k;
+        int r;
 
         assert(bus);
         assert(n);
@@ -836,11 +847,14 @@ static bool bus_node_exists(
         /* Tests if there's anything attached directly to this node
          * for the specified path */
 
+        if (!require_fallback && (n->enumerators || n->object_managers))
+                return true;
+
         LIST_FOREACH(callbacks, k, n->callbacks) {
                 if (require_fallback && !k->is_fallback)
                         continue;
 
-                return true;
+                return 1;
         }
 
         LIST_FOREACH(vtables, c, n->vtables) {
@@ -849,13 +863,14 @@ static bool bus_node_exists(
                 if (require_fallback && !c->is_fallback)
                         continue;
 
-                if (node_vtable_get_userdata(bus, path, c, NULL, &error) > 0)
-                        return true;
+                r = node_vtable_get_userdata(bus, path, c, NULL, &error);
+                if (r != 0)
+                        return r;
                 if (bus->nodes_modified)
-                        return false;
+                        return 0;
         }
 
-        return !require_fallback && (n->enumerators || n->object_managers);
+        return 0;
 }
 
 static int process_introspect(
@@ -938,12 +953,12 @@ static int process_introspect(
                 /* Nothing?, let's see if we exist at all, and if not
                  * refuse to do anything */
                 r = bus_node_exists(bus, n, m->path, require_fallback);
-                if (r < 0)
-                        return r;
-                if (bus->nodes_modified)
-                        return 0;
-                if (r == 0)
+                if (r <= 0)
+                        goto finish;
+                if (bus->nodes_modified) {
+                        r = 0;
                         goto finish;
+                }
         }
 
         *found_object = true;
@@ -1293,6 +1308,8 @@ static int object_find_and_run(
                 r = bus_node_exists(bus, n, m->path, require_fallback);
                 if (r < 0)
                         return r;
+                if (bus->nodes_modified)
+                        return 0;
                 if (r > 0)
                         *found_object = true;
         }
@@ -1675,6 +1692,11 @@ static int add_object_vtable_internal(
                                 goto fail;
                         }
 
+                        if (v->flags & SD_BUS_VTABLE_PROPERTY_CONST) {
+                                r = -EINVAL;
+                                goto fail;
+                        }
+
                         /* Fall through */
 
                 case _SD_BUS_VTABLE_PROPERTY: {