Make NEW_IDs nullable

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

Signed-off-by: Daniel Stone <daniel@fooishbar.org>
This commit is contained in:
Daniel Stone 2012-07-23 19:54:41 +01:00 committed by Kristian Høgsberg
parent efe23443d8
commit db0add6d5e
3 changed files with 48 additions and 6 deletions

View file

@ -532,6 +532,10 @@ wl_closure_vmarshal(struct wl_object *sender,
object = va_arg(ap, struct wl_object *); object = va_arg(ap, struct wl_object *);
if (end - p < 1) if (end - p < 1)
goto err; goto err;
if (!arg.nullable && object == NULL)
goto err_null;
*p++ = object ? object->id : 0; *p++ = object ? object->id : 0;
break; break;
@ -719,6 +723,15 @@ wl_connection_demarshal(struct wl_connection *connection,
extra += sizeof *object; extra += sizeof *object;
closure->args[i] = 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); *object = wl_map_lookup(objects, *p);
if (*object == WL_ZOMBIE_OBJECT) { if (*object == WL_ZOMBIE_OBJECT) {
/* references object we've already /* references object we've already
@ -751,6 +764,14 @@ wl_connection_demarshal(struct wl_connection *connection,
closure->args[i] = id; closure->args[i] = id;
*id = p; *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) { if (wl_map_reserve_new(objects, *p) < 0) {
printf("not a valid new object id (%d), " printf("not a valid new object id (%d), "
"message %s(%s)\n", "message %s(%s)\n",
@ -935,7 +956,17 @@ wl_closure_print(struct wl_closure *closure, struct wl_object *target, int send)
fprintf(stderr, "nil"); fprintf(stderr, "nil");
break; break;
case 'n': 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; break;
case 'a': case 'a':
fprintf(stderr, "array"); fprintf(stderr, "array");

View file

@ -228,6 +228,7 @@ is_nullable_type(struct arg *arg)
/* Strings, objects, and arrays are possibly nullable */ /* Strings, objects, and arrays are possibly nullable */
case STRING: case STRING:
case OBJECT: case OBJECT:
case NEW_ID:
case ARRAY: case ARRAY:
return 1; return 1;
default: default:

View file

@ -479,19 +479,29 @@ create_proxies(struct wl_display *display, struct wl_closure *closure)
{ {
struct wl_proxy *proxy; struct wl_proxy *proxy;
const char *signature; const char *signature;
struct argument_details arg;
uint32_t id; uint32_t id;
int i; int i;
int count;
signature = closure->message->signature; signature = closure->message->signature;
for (i = 0; signature[i]; i++) { count = arg_count_for_signature(signature) + 2;
switch (signature[i]) { for (i = 2; i < count; i++) {
signature = get_next_argument(signature, &arg);
switch (arg.type) {
case 'n': 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, proxy = wl_proxy_create_for_id(&display->proxy, id,
closure->message->types[i]); closure->message->types[i - 2]);
if (proxy == NULL) if (proxy == NULL)
return -1; return -1;
*(void **) closure->args[i + 2] = proxy; *(void **) closure->args[i] = proxy;
break;
default:
break; break;
} }
} }