[PATCH wayland 04/10] Make NEW_IDs nullable

Daniel Stone daniel at fooishbar.org
Mon Jul 23 11:54:41 PDT 2012


The connection-handling code already allows this, so make it legal in
the protocol definition too.

Signed-off-by: Daniel Stone <daniel at fooishbar.org>
---
 src/connection.c     |   33 ++++++++++++++++++++++++++++++++-
 src/scanner.c        |    1 +
 src/wayland-client.c |   20 +++++++++++++++-----
 3 files changed, 48 insertions(+), 6 deletions(-)

diff --git a/src/connection.c b/src/connection.c
index b228c92..4ba7f63 100644
--- a/src/connection.c
+++ b/src/connection.c
@@ -532,6 +532,10 @@ wl_closure_vmarshal(struct wl_object *sender,
 			object = va_arg(ap, struct wl_object *);
 			if (end - p < 1)
 				goto err;
+
+			if (!arg.nullable && object == NULL)
+				goto err_null;
+
 			*p++ = object ? object->id : 0;
 			break;
 
@@ -719,6 +723,15 @@ wl_connection_demarshal(struct wl_connection *connection,
 			extra += sizeof *object;
 			closure->args[i] = object;
 
+			if (*p == 0 && !arg.nullable) {
+				printf("NULL new ID received on non-nullable "
+				       "type, message %s(%s)\n", message->name,
+				       message->signature);
+				*object = NULL;
+				errno = EINVAL;
+				goto err;
+			}
+
 			*object = wl_map_lookup(objects, *p);
 			if (*object == WL_ZOMBIE_OBJECT) {
 				/* references object we've already
@@ -751,6 +764,14 @@ wl_connection_demarshal(struct wl_connection *connection,
 			closure->args[i] = id;
 			*id = p;
 
+			if (*id == 0 && !arg.nullable) {
+				printf("NULL new ID received on non-nullable "
+				       "type, message %s(%s)\n", message->name,
+				       message->signature);
+				errno = EINVAL;
+				goto err;
+			}
+
 			if (wl_map_reserve_new(objects, *p) < 0) {
 				printf("not a valid new object id (%d), "
 				       "message %s(%s)\n",
@@ -935,7 +956,17 @@ wl_closure_print(struct wl_closure *closure, struct wl_object *target, int send)
 				fprintf(stderr, "nil");
 			break;
 		case 'n':
-			fprintf(stderr, "new id %u", value->uint32);
+			fprintf(stderr, "new id %s@",
+				(closure->message->types[i - 2]) ?
+				 closure->message->types[i - 2]->name :
+				  "[unknown]");
+			if (send && value->new_id != 0)
+				fprintf(stderr, "%u", value->new_id);
+			else if (!send && value->object != NULL)
+				fprintf(stderr, "%u",
+					*((uint32_t *)value->object));
+			else
+				fprintf(stderr, "nil");
 			break;
 		case 'a':
 			fprintf(stderr, "array");
diff --git a/src/scanner.c b/src/scanner.c
index 50e26c1..0fc26e7 100644
--- a/src/scanner.c
+++ b/src/scanner.c
@@ -228,6 +228,7 @@ is_nullable_type(struct arg *arg)
 	/* Strings, objects, and arrays are possibly nullable */
 	case STRING:
 	case OBJECT:
+	case NEW_ID:
 	case ARRAY:
 		return 1;
 	default:
diff --git a/src/wayland-client.c b/src/wayland-client.c
index b41fb9b..7130cb7 100644
--- a/src/wayland-client.c
+++ b/src/wayland-client.c
@@ -479,19 +479,29 @@ create_proxies(struct wl_display *display, struct wl_closure *closure)
 {
 	struct wl_proxy *proxy;
 	const char *signature;
+	struct argument_details arg;
 	uint32_t id;
 	int i;
+	int count;
 
 	signature = closure->message->signature;
-	for (i = 0; signature[i]; i++) {
-		switch (signature[i]) {
+	count = arg_count_for_signature(signature) + 2;
+	for (i = 2; i < count; i++) {
+		signature = get_next_argument(signature, &arg);
+		switch (arg.type) {
 		case 'n':
-			id = **(uint32_t **) closure->args[i + 2];
+			id = **(uint32_t **) closure->args[i];
+			if (id == 0) {
+				*(void **) closure->args[i] = NULL;
+				break;
+			}
 			proxy = wl_proxy_create_for_id(&display->proxy, id,
-						       closure->message->types[i]);		       
+						       closure->message->types[i - 2]);
 			if (proxy == NULL)
 				return -1;
-			*(void **) closure->args[i + 2] = proxy;
+			*(void **) closure->args[i] = proxy;
+			break;
+		default:
 			break;
 		}
 	}
-- 
1.7.10.4



More information about the wayland-devel mailing list