Increase closure buffer size and fail gracefully for too big closures.

Buffer size changed from 256 to 1024 bytes. Marshalling will now stop
if the buffer is not big enough.
This commit is contained in:
Laszlo Agocs 2011-12-16 10:29:36 +02:00 committed by Kristian Høgsberg
parent f598691831
commit 34901868b8
3 changed files with 38 additions and 6 deletions

View File

@ -39,8 +39,6 @@
#include "wayland-util.h"
#include "wayland-private.h"
#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])
struct wl_buffer {
char data[4096];
int head, tail;
@ -54,7 +52,7 @@ struct wl_closure {
ffi_type *types[20];
ffi_cif cif;
void *args[20];
uint32_t buffer[64];
uint32_t buffer[256];
uint32_t *start;
};
@ -392,7 +390,7 @@ wl_connection_vmarshal(struct wl_connection *connection,
{
struct wl_closure *closure = &connection->send_closure;
struct wl_object **objectp, *object;
uint32_t length, *p, *start, size;
uint32_t length, *p, *start, size, *end;
int dup_fd;
struct wl_array **arrayp, *array;
const char **sp, *s;
@ -403,17 +401,23 @@ wl_connection_vmarshal(struct wl_connection *connection,
count = strlen(message->signature) + 2;
extra = (char *) closure->buffer;
start = &closure->buffer[DIV_ROUNDUP(extra_size, sizeof *p)];
end = &closure->buffer[ARRAY_LENGTH(closure->buffer)];
p = &start[2];
for (i = 2; i < count; i++) {
switch (message->signature[i - 2]) {
case 'u':
closure->types[i] = &ffi_type_uint32;
closure->args[i] = p;
if (end - p < 1)
goto err;
*p++ = va_arg(ap, uint32_t);
break;
case 'i':
closure->types[i] = &ffi_type_sint32;
closure->args[i] = p;
if (end - p < 1)
goto err;
*p++ = va_arg(ap, int32_t);
break;
case 's':
@ -424,6 +428,8 @@ wl_connection_vmarshal(struct wl_connection *connection,
s = va_arg(ap, const char *);
length = s ? strlen(s) + 1: 0;
if (end - p < DIV_ROUNDUP(length, sizeof *p) + 1)
goto err;
*p++ = length;
if (length > 0)
@ -442,6 +448,8 @@ wl_connection_vmarshal(struct wl_connection *connection,
object = va_arg(ap, struct wl_object *);
*objectp = object;
if (end - p < 1)
goto err;
*p++ = object ? object->id : 0;
break;
@ -449,6 +457,8 @@ wl_connection_vmarshal(struct wl_connection *connection,
closure->types[i] = &ffi_type_uint32;
closure->args[i] = p;
object = va_arg(ap, struct wl_object *);
if (end - p < 1)
goto err;
*p++ = object ? object->id : 0;
break;
@ -463,9 +473,13 @@ wl_connection_vmarshal(struct wl_connection *connection,
array = va_arg(ap, struct wl_array *);
if (array == NULL || array->size == 0) {
if (end - p < 1)
goto err;
*p++ = 0;
break;
}
if (end - p < DIV_ROUNDUP(array->size, sizeof *p) + 1)
goto err;
*p++ = array->size;
memcpy(p, array->data, array->size);
@ -509,6 +523,12 @@ wl_connection_vmarshal(struct wl_connection *connection,
closure->count = count;
return closure;
err:
printf("request too big to marshal, maximum size is %d\n",
sizeof closure->buffer);
errno = ENOMEM;
return NULL;
}
struct wl_closure *
@ -535,7 +555,8 @@ wl_connection_demarshal(struct wl_connection *connection,
extra_space = wl_message_size_extra(message);
if (sizeof closure->buffer < size + extra_space) {
printf("request too big, should malloc tmp buffer here\n");
printf("request too big to demarshal, maximum %d actual %d\n",
sizeof closure->buffer, size + extra_space);
errno = ENOMEM;
wl_connection_consume(connection, size);
return NULL;

View File

@ -198,6 +198,11 @@ wl_proxy_marshal(struct wl_proxy *proxy, uint32_t opcode, ...)
&proxy->object.interface->methods[opcode]);
va_end(ap);
if (closure == NULL) {
fprintf(stderr, "Error marshalling request\n");
abort();
}
wl_closure_send(closure, proxy->display->connection);
if (wl_debug)
@ -473,7 +478,7 @@ handle_event(struct wl_display *display,
size, &display->objects, message);
if (closure == NULL) {
fprintf(stderr, "Error demarshalling event: %m\n");
fprintf(stderr, "Error demarshalling event\n");
abort();
}

View File

@ -100,6 +100,9 @@ wl_resource_post_event(struct wl_resource *resource, uint32_t opcode, ...)
&object->interface->events[opcode]);
va_end(ap);
if (closure == NULL)
return;
wl_closure_send(closure, resource->client->connection);
if (wl_debug)
@ -122,6 +125,9 @@ wl_resource_queue_event(struct wl_resource *resource, uint32_t opcode, ...)
&object->interface->events[opcode]);
va_end(ap);
if (closure == NULL)
return;
wl_closure_queue(closure, resource->client->connection);
if (wl_debug)