From f081e8e79f45d6abf1e070b6727fd0874236b4e2 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 25 May 2023 13:36:12 +1000 Subject: [PATCH] proto: add a version argument to ei_connection.sync This is the only request that creates a new object but doesn't specify the version for that object, courtesy of copy/paste from the wayland protocol. In libei/libeis this a bit was hidden away so it didn't get noticed - but it was already buggy: libei would always hardcode to version 1 but libeis would take whichever ei_callback version was agreed upon during handshake. This version could be higher than 1. This is a protocol break but we're still pre-1.0, there are very few people that will be affected by this and it's better than having to carry this bug around for years. Fixes #35 --- proto/protocol.xml | 1 + src/libei-callback.c | 6 ++++++ src/libei-callback.h | 1 + src/libei-connection.c | 2 +- src/libeis-client.c | 4 ++-- test/test_protocol.py | 16 ++++++++-------- 6 files changed, 19 insertions(+), 11 deletions(-) diff --git a/proto/protocol.xml b/proto/protocol.xml index 7bafa7c..10aea60 100644 --- a/proto/protocol.xml +++ b/proto/protocol.xml @@ -248,6 +248,7 @@ + diff --git a/src/libei-callback.c b/src/libei-callback.c index df699f2..69808a6 100644 --- a/src/libei-callback.c +++ b/src/libei-callback.c @@ -68,6 +68,12 @@ ei_callback_get_id(struct ei_callback *callback) return callback->proto_object.id; } +uint32_t +ei_callback_get_version(struct ei_callback *callback) +{ + return callback->proto_object.version; +} + static struct brei_result * handle_msg_done(struct ei_callback *callback, uint64_t callback_data) { diff --git a/src/libei-callback.h b/src/libei-callback.h index 585e6c3..a9fe282 100644 --- a/src/libei-callback.h +++ b/src/libei-callback.h @@ -51,6 +51,7 @@ struct ei_callback { OBJECT_DECLARE_GETTER(ei_callback, context, struct ei*); OBJECT_DECLARE_GETTER(ei_callback, proto_object, const struct brei_object *); OBJECT_DECLARE_GETTER(ei_callback, id, object_id_t); +OBJECT_DECLARE_GETTER(ei_callback, version, uint32_t); OBJECT_DECLARE_GETTER(ei_callback, interface, const struct ei_callback_interface *); OBJECT_DECLARE_GETTER(ei_callback, user_data, void *); OBJECT_DECLARE_SETTER(ei_callback, user_data, void *); diff --git a/src/libei-connection.c b/src/libei-connection.c index 61c8d7a..fe83ce6 100644 --- a/src/libei-connection.c +++ b/src/libei-connection.c @@ -137,5 +137,5 @@ ei_connection_sync(struct ei_connection *connection, ei_connection_sync_callback ei_callback_set_user_data(callback, data); list_append(&connection->pending_callbacks, &callback->link); - ei_connection_request_sync(connection, ei_callback_get_id(callback)); + ei_connection_request_sync(connection, ei_callback_get_id(callback), ei_callback_get_version(callback)); } diff --git a/src/libeis-client.c b/src/libeis-client.c index 9deea74..5581b3d 100644 --- a/src/libeis-client.c +++ b/src/libeis-client.c @@ -318,13 +318,13 @@ client_msg_disconnect(struct eis_connection *connection) } static struct brei_result * -client_msg_sync(struct eis_connection *connection, object_id_t new_id) +client_msg_sync(struct eis_connection *connection, object_id_t new_id, uint32_t version) { struct eis_client *client = eis_connection_get_client(connection); DISCONNECT_IF_INVALID_ID(client, new_id); - struct eis_callback *callback = eis_callback_new(client, new_id, client->interface_versions.ei_callback); + struct eis_callback *callback = eis_callback_new(client, new_id, version); log_debug(eis_client_get_context(client) , "object %#" PRIx64 ": connection sync done", new_id); int rc = eis_callback_event_done(callback, 0); eis_callback_unref(callback); diff --git a/test/test_protocol.py b/test/test_protocol.py index 3d38865..d97b8b9 100644 --- a/test/test_protocol.py +++ b/test/test_protocol.py @@ -148,7 +148,7 @@ class Ei: cb = EiCallback.create(next(self.object_ids), VERSION_V(1)) self.context.register(cb) - self.send(self.connection.Sync(cb.object_id)) + self.send(self.connection.Sync(cb.object_id, VERSION_V(1))) return self.wait_for( lambda: cb not in self.find_objects_by_interface(InterfaceName.EI_CALLBACK) @@ -715,7 +715,7 @@ class TestEiProtocol: cb = EiCallback.create(next(ei.object_ids), VERSION_V(1)) ei.context.register(cb) assert ei.connection is not None - ei.send(ei.connection.Sync(cb.object_id)) + ei.send(ei.connection.Sync(cb.object_id, VERSION_V(1))) ei.dispatch() assert cb.calllog[0].name == "Done" @@ -759,7 +759,7 @@ class TestEiProtocol: # Send the invalid object request ei.send(release) - ei.send(ei.connection.Sync(cb.object_id)) + ei.send(ei.connection.Sync(cb.object_id, VERSION_V(1))) ei.wait_for(lambda: have_sync) assert have_invalid_object_event, "Expected invalid_object event, got none" @@ -923,20 +923,20 @@ class TestEiProtocol: # and some of the next few ids might have been used by pingpongs cb = EiCallback.create(0xFF00000000000100, VERSION_V(1)) ei.context.register(cb) - ei.send(ei.connection.Sync(cb.object_id)) + ei.send(ei.connection.Sync(cb.object_id, VERSION_V(1))) elif test_for == "repeat-id": cb = EiCallback.create(0x100, VERSION_V(1)) ei.context.register(cb) - ei.send(ei.connection.Sync(cb.object_id)) + ei.send(ei.connection.Sync(cb.object_id, VERSION_V(1))) cb = EiCallback.create(0x100, VERSION_V(1)) - ei.send(ei.connection.Sync(cb.object_id)) + ei.send(ei.connection.Sync(cb.object_id, VERSION_V(1))) elif test_for == "decreasing-id": cb = EiCallback.create(0x101, VERSION_V(1)) ei.context.register(cb) - ei.send(ei.connection.Sync(cb.object_id)) + ei.send(ei.connection.Sync(cb.object_id, VERSION_V(1))) cb = EiCallback.create(0x100, VERSION_V(1)) ei.context.register(cb) - ei.send(ei.connection.Sync(cb.object_id)) + ei.send(ei.connection.Sync(cb.object_id, VERSION_V(1))) else: assert False, "Unhandled test parameter"