diff options
Diffstat (limited to 'dist/libxcb/src/xcb_in.c')
-rw-r--r-- | dist/libxcb/src/xcb_in.c | 29 |
1 files changed, 20 insertions, 9 deletions
diff --git a/dist/libxcb/src/xcb_in.c b/dist/libxcb/src/xcb_in.c index 796b4e946..c9a264dcf 100644 --- a/dist/libxcb/src/xcb_in.c +++ b/dist/libxcb/src/xcb_in.c @@ -32,7 +32,6 @@ #include <assert.h> #include <string.h> #include <stdlib.h> -#include <unistd.h> #include <stdio.h> #include <errno.h> @@ -40,6 +39,7 @@ #include <poll.h> #endif #ifndef _WIN32 +#include <unistd.h> #include <sys/select.h> #include <sys/socket.h> #endif @@ -239,9 +239,15 @@ static int read_packet(xcb_connection_t *c) if(pend && pend->workaround == WORKAROUND_GLX_GET_FB_CONFIGS_BUG) { uint32_t *p = (uint32_t *) c->in.queue; - genrep.length = p[2] * p[3] * 2; + uint64_t new_length = ((uint64_t)p[2]) * ((uint64_t)p[3]); + if(new_length >= (UINT32_MAX / UINT32_C(16))) + { + _xcb_conn_shutdown(c, XCB_CONN_CLOSED_MEM_INSUFFICIENT); + return 0; + } + genrep.length = (uint32_t)(new_length * UINT64_C(2)); } - length += genrep.length * 4; + length += genrep.length * UINT64_C(4); /* XXX a bit of a hack -- we "know" that all FD replys place * the number of fds in the pad0 byte */ @@ -251,7 +257,7 @@ static int read_packet(xcb_connection_t *c) /* XGE events may have sizes > 32 */ if ((genrep.response_type & 0x7f) == XCB_XGE_EVENT) - eventlength = genrep.length * 4; + eventlength = genrep.length * UINT64_C(4); bufsize = length + eventlength + nfd * sizeof(int) + (genrep.response_type == XCB_REPLY ? 0 : sizeof(uint32_t)); @@ -365,7 +371,7 @@ static void free_reply_list(struct reply_list *head) } } -static int read_block(const int fd, void *buf, const ssize_t len) +static int read_block(const int fd, void *buf, const intptr_t len) { int done = 0; while(done < len) @@ -736,11 +742,16 @@ xcb_generic_error_t *xcb_request_check(xcb_connection_t *c, xcb_void_cookie_t co return 0; pthread_mutex_lock(&c->iolock); request = widen(c, cookie.sequence); - if(XCB_SEQUENCE_COMPARE(request, >=, c->in.request_expected) - && XCB_SEQUENCE_COMPARE(request, >, c->in.request_completed)) + if (XCB_SEQUENCE_COMPARE(request, >, c->in.request_completed)) { - _xcb_out_send_sync(c); - _xcb_out_flush_to(c, c->out.request); + if(XCB_SEQUENCE_COMPARE(request, >=, c->in.request_expected)) + { + _xcb_out_send_sync(c); + } + if (XCB_SEQUENCE_COMPARE(request, >=, c->out.request_expected_written)) + { + _xcb_out_flush_to(c, c->out.request); + } } reply = wait_for_reply(c, request, &ret); assert(!reply); |