From 629b5ab9f3f03f54fb115d169ed2bbe666f2799f Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Mon, 15 Jun 2020 15:25:17 +0200 Subject: libaxl_receive_handshake and libaxl_send_request MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- libaxl_connect_without_handshake.c | 3 ++- libaxl_receive_handshake.c | 34 ++++++++++++++++++++++++++++++++-- libaxl_send_request.c | 29 +++++++++++++++++++---------- 3 files changed, 53 insertions(+), 13 deletions(-) diff --git a/libaxl_connect_without_handshake.c b/libaxl_connect_without_handshake.c index 181cdb2..e05dd66 100644 --- a/libaxl_connect_without_handshake.c +++ b/libaxl_connect_without_handshake.c @@ -62,6 +62,7 @@ libaxl_connect_without_handshake(const char *host, const char *protocol, int dis if ((!protocol || !*protocol) && (!host || !*host)) { sprintf(path, "/tmp/.X11-unix/X%i", display); fd = connect_unix(path); + /* TODO also try abstract address version with a NUL byte before it (truncate address to remove tailing NULs) */ if (fd < 0) { fd = connect_tcp_ip("localhost", display); if (fd >= 0) @@ -88,7 +89,7 @@ libaxl_connect_without_handshake(const char *host, const char *protocol, int dis conn = libaxl_create(fd); if (conn) - conn->info.default_screen_number = screen; + conn->info.default_screen_number = screen < 0 ? 0 : screen; return conn; } diff --git a/libaxl_receive_handshake.c b/libaxl_receive_handshake.c index d26a5d4..f37fe88 100644 --- a/libaxl_receive_handshake.c +++ b/libaxl_receive_handshake.c @@ -50,11 +50,13 @@ libaxl_receive_handshake(LIBAXL_CONTEXT *restrict ctx, int *restrict majorp, int { LIBAXL_CONNECTION *conn = ctx->conn; char *restrict inbuf, *new; - size_t i, n, t, len, vendor_len, out_off, in_off; + size_t i, j, k, n, t, len, vendor_len, out_off, in_off; ssize_t r; int read_stage = 0, saved_errno, status; struct response *resp; uint32_t xid_base, xid_mask; + struct libaxl_screen *screen; + struct libaxl_depth *depth; #ifdef MSG_TRUNC int flag_trunc; #endif @@ -205,7 +207,7 @@ continue_read: conn->info_buf = inbuf; conn->info.vendor = inbuf; conn->info.formats = (void *)&inbuf[t]; - conn->info.screens = (void *)&inbuf[t + conn->info.nformats * 8]; + conn->info.screens = screen = (void *)&inbuf[t + conn->info.nformats * 8]; if ((size_t)conn->info.default_screen_number < conn->info.nscreens) { conn->info.default_screen = conn->info.screens; for (i = 0; i < (size_t)conn->info.default_screen_number; i++) @@ -214,6 +216,34 @@ continue_read: conn->info.default_screen = NULL; } + for (i = 0; i < (size_t)conn->info.nscreens; i++) { + screen->root = ntohl(screen->root); + screen->default_colormap = ntohl(screen->default_colormap); + screen->white_pixel = ntohl(screen->white_pixel); + screen->black_pixel = ntohl(screen->black_pixel); + screen->current_input_masks = ntohl(screen->current_input_masks); + screen->width_in_pixels = ntohs(screen->width_in_pixels); + screen->height_in_pixels = ntohs(screen->height_in_pixels); + screen->width_in_millimeters = ntohs(screen->width_in_millimeters); + screen->height_in_millimeters = ntohs(screen->height_in_millimeters); + screen->min_installed_maps = ntohs(screen->min_installed_maps); + screen->max_installed_maps = ntohs(screen->max_installed_maps); + screen->root_visual = ntohs(screen->root_visual); + depth = screen->allowed_depths; + for (j = 0; j < (size_t)screen->number_of_allowed_depths; j++) { + depth->number_of_visuals = ntohs(depth->number_of_visuals); + for (k = 0; k < (size_t)depth->number_of_visuals; k++) { + depth->visuals[k].visual_id = ntohl(depth->visuals[k].visual_id); + depth->visuals[k].colormap_entries = ntohs(depth->visuals[k].colormap_entries); + depth->visuals[k].red_mask = ntohl(depth->visuals[k].red_mask); + depth->visuals[k].green_mask = ntohl(depth->visuals[k].green_mask); + depth->visuals[k].blue_mask = ntohl(depth->visuals[k].blue_mask); + } + depth = (void *)(uintptr_t)&depth->visuals[depth->number_of_visuals]; + } + screen = (void *)(uintptr_t)depth; + } + ctx->in_buf_size = 0; ctx->in_buf = NULL; break; diff --git a/libaxl_send_request.c b/libaxl_send_request.c index 471da0b..11352c8 100644 --- a/libaxl_send_request.c +++ b/libaxl_send_request.c @@ -180,6 +180,8 @@ libaxl_send_request(LIBAXL_CONTEXT *restrict ctx, union libaxl_request_const_ptr uint32_t mask; char *buf = ctx->out_buf, *subbuf, *new; size_t size = ctx->out_buf_size; + uint16_t u16; + uint32_t u32; RLOCK_CONNECTION_SEND(conn); pending = conn->pending_out; @@ -225,12 +227,15 @@ again: case '_': buf[o++] = 0; /* need not be 0 */ + i += 1; /* fall through */ case ',': buf[o++] = 0; /* need not be 0 */ + i += 1; /* fall through */ case '.': buf[o++] = 0; /* need not be 0 */ + i += 1; break; case '!': @@ -261,15 +266,17 @@ again: break; case 's': - *(uint16_t *)&buf[o] = htons(*(const uint16_t *)&req[i]); - TWOS_COMPLEMENT16(&buf[o]); + u16 = *(const uint16_t *)&req[i]; + TWOS_COMPLEMENT16(&u16); + *(uint16_t *)&buf[o] = htons(u16); i += 2; o += 2; break; case 'S': - *(uint32_t *)&buf[o] = htonl(*(const uint32_t *)&req[i]); - TWOS_COMPLEMENT32(&buf[o]); + u32 = *(const uint32_t *)&req[i]; + TWOS_COMPLEMENT32(&u32); + *(uint32_t *)&buf[o] = htonl(u32); i += 4; o += 4; break; @@ -416,9 +423,10 @@ again: case '2': case 's': if (mask & 1) { - *(uint32_t *)&buf[o] = htonl((uint32_t)*(const uint16_t *)&req[i]); - if (*fmt == 'z') - TWOS_COMPLEMENT16(&buf[o]); + u16 = *(const uint16_t *)&req[i]; + if (*fmt == 's') + TWOS_COMPLEMENT16(&u16); + *(uint32_t *)&buf[o] = htonl((uint32_t)u16); o += 4; } mask >>= 1; @@ -428,9 +436,10 @@ again: case '4': case 'S': if (mask & 1) { - *(uint32_t *)&buf[o] = htonl(*(const uint32_t *)&req[i]); - if (*fmt == 'z') - TWOS_COMPLEMENT32(&buf[o]); + u32 = *(const uint16_t *)&req[i]; + if (*fmt == 'S') + TWOS_COMPLEMENT32(&u32); + *(uint32_t *)&buf[o] = htonl(u32); o += 4; } mask >>= 1; -- cgit v1.2.3-70-g09d2