dbus-protocol: Implement argument type checking for normal methods.

This commit is contained in:
Tanu Kaskinen 2009-08-31 18:12:55 +03:00
parent 8a28e5de94
commit 587131917f
2 changed files with 43 additions and 3 deletions

View file

@ -101,7 +101,7 @@ static pa_dbus_method_handler method_handlers[METHOD_HANDLER_MAX] = {
[METHOD_HANDLER_REMOVE_PROPERTIES] = { [METHOD_HANDLER_REMOVE_PROPERTIES] = {
.method_name = "RemoveProperties", .method_name = "RemoveProperties",
.arguments = remove_properties_args, .arguments = remove_properties_args,
.n_arguments = sizeof(update_properties_args) / sizeof(pa_dbus_arg_info), .n_arguments = sizeof(remove_properties_args) / sizeof(pa_dbus_arg_info),
.receive_cb = handle_remove_properties } .receive_cb = handle_remove_properties }
}; };

View file

@ -72,6 +72,7 @@ struct connection_entry {
struct interface_entry { struct interface_entry {
char *name; char *name;
pa_hashmap *method_handlers; pa_hashmap *method_handlers;
pa_hashmap *method_signatures; /* Derived from method_handlers. Contains only "in" arguments. */
pa_hashmap *property_handlers; pa_hashmap *property_handlers;
pa_dbus_receive_cb_t get_all_properties_cb; pa_dbus_receive_cb_t get_all_properties_cb;
pa_dbus_signal_info *signals; pa_dbus_signal_info *signals;
@ -354,8 +355,14 @@ static enum find_result_t find_handler_by_method(struct call_info *call_info) {
pa_assert(call_info); pa_assert(call_info);
PA_HASHMAP_FOREACH(call_info->iface_entry, call_info->obj_entry->interfaces, state) { PA_HASHMAP_FOREACH(call_info->iface_entry, call_info->obj_entry->interfaces, state) {
if ((call_info->method_handler = pa_hashmap_get(call_info->iface_entry->method_handlers, call_info->method))) if ((call_info->method_handler = pa_hashmap_get(call_info->iface_entry->method_handlers, call_info->method))) {
call_info->expected_method_sig = pa_hashmap_get(call_info->iface_entry->method_signatures, call_info->method);
if (pa_streq(call_info->method_sig, call_info->expected_method_sig))
return FOUND_METHOD; return FOUND_METHOD;
else
return INVALID_METHOD_SIG;
}
} }
return NO_SUCH_METHOD; return NO_SUCH_METHOD;
@ -630,6 +637,31 @@ static pa_hashmap *create_method_handlers(const pa_dbus_interface_info *info) {
return handlers; return handlers;
} }
static pa_hashmap *extract_method_signatures(pa_hashmap *method_handlers) {
pa_hashmap *signatures = NULL;
pa_dbus_method_handler *handler = NULL;
void *state = NULL;
pa_strbuf *sig_buf = NULL;
unsigned i = 0;
pa_assert(method_handlers);
signatures = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
PA_HASHMAP_FOREACH(handler, method_handlers, state) {
sig_buf = pa_strbuf_new();
for (i = 0; i < handler->n_arguments; ++i) {
if (pa_streq(handler->arguments[i].direction, "in"))
pa_strbuf_puts(sig_buf, handler->arguments[i].type);
}
pa_hashmap_put(signatures, handler->method_name, pa_strbuf_tostring_free(sig_buf));
}
return signatures;
}
static pa_hashmap *create_property_handlers(const pa_dbus_interface_info *info) { static pa_hashmap *create_property_handlers(const pa_dbus_interface_info *info) {
pa_hashmap *handlers; pa_hashmap *handlers;
unsigned i = 0; unsigned i = 0;
@ -707,6 +739,7 @@ int pa_dbus_protocol_add_interface(pa_dbus_protocol *p,
iface_entry = pa_xnew(struct interface_entry, 1); iface_entry = pa_xnew(struct interface_entry, 1);
iface_entry->name = pa_xstrdup(info->name); iface_entry->name = pa_xstrdup(info->name);
iface_entry->method_handlers = create_method_handlers(info); iface_entry->method_handlers = create_method_handlers(info);
iface_entry->method_signatures = extract_method_signatures(iface_entry->method_handlers);
iface_entry->property_handlers = create_property_handlers(info); iface_entry->property_handlers = create_property_handlers(info);
iface_entry->get_all_properties_cb = info->get_all_properties_cb; iface_entry->get_all_properties_cb = info->get_all_properties_cb;
iface_entry->signals = copy_signals(info); iface_entry->signals = copy_signals(info);
@ -760,6 +793,12 @@ static void method_handler_free_cb(void *p, void *userdata) {
pa_xfree((pa_dbus_arg_info *) h->arguments); pa_xfree((pa_dbus_arg_info *) h->arguments);
} }
static void method_signature_free_cb(void *p, void *userdata) {
pa_assert(p);
pa_xfree(p);
}
static void property_handler_free_cb(void *p, void *userdata) { static void property_handler_free_cb(void *p, void *userdata) {
pa_dbus_property_handler *h = p; pa_dbus_property_handler *h = p;
@ -792,6 +831,7 @@ int pa_dbus_protocol_remove_interface(pa_dbus_protocol *p, const char* path, con
pa_xfree(iface_entry->name); pa_xfree(iface_entry->name);
pa_hashmap_free(iface_entry->method_handlers, method_handler_free_cb, NULL); pa_hashmap_free(iface_entry->method_handlers, method_handler_free_cb, NULL);
pa_hashmap_free(iface_entry->method_signatures, method_signature_free_cb, NULL);
pa_hashmap_free(iface_entry->property_handlers, property_handler_free_cb, NULL); pa_hashmap_free(iface_entry->property_handlers, property_handler_free_cb, NULL);
for (i = 0; i < iface_entry->n_signals; ++i) { for (i = 0; i < iface_entry->n_signals; ++i) {