diff options
author | Matthieu Herrb <matthieu@cvs.openbsd.org> | 2022-07-17 08:31:11 +0000 |
---|---|---|
committer | Matthieu Herrb <matthieu@cvs.openbsd.org> | 2022-07-17 08:31:11 +0000 |
commit | 6cccfd93d90df41c275b06d3e5a40658b661566c (patch) | |
tree | 1aab3c632b04c7332392b5c1273406ac2b049e60 /dist | |
parent | c36abfebd4d7981796005f812b8f35bf745e1d64 (diff) |
Update libxcb to version 1.15 + xcb-protos 1.15.2
Diffstat (limited to 'dist')
-rw-r--r-- | dist/libxcb/ChangeLog | 305 | ||||
-rw-r--r-- | dist/libxcb/build-aux/compile | 6 | ||||
-rw-r--r-- | dist/libxcb/build-aux/test-driver | 19 | ||||
-rw-r--r-- | dist/libxcb/configure.ac | 4 | ||||
-rw-r--r-- | dist/libxcb/m4/libtool.m4 | 2 | ||||
-rw-r--r-- | dist/libxcb/src/Makefile.am | 2 | ||||
-rw-r--r-- | dist/libxcb/src/c_client.py | 102 | ||||
-rw-r--r-- | dist/libxcb/src/xcb.h | 6 | ||||
-rw-r--r-- | dist/libxcb/src/xcb_auth.c | 12 | ||||
-rw-r--r-- | dist/libxcb/src/xcb_conn.c | 72 | ||||
-rw-r--r-- | dist/libxcb/src/xcb_in.c | 29 | ||||
-rw-r--r-- | dist/libxcb/src/xcb_list.c | 6 | ||||
-rw-r--r-- | dist/libxcb/src/xcb_out.c | 9 | ||||
-rw-r--r-- | dist/libxcb/src/xcb_util.c | 6 | ||||
-rw-r--r-- | dist/libxcb/src/xcb_xid.c | 2 | ||||
-rw-r--r-- | dist/libxcb/src/xcbint.h | 15 | ||||
-rw-r--r-- | dist/libxcb/tests/check_public.c | 30 |
17 files changed, 518 insertions, 109 deletions
diff --git a/dist/libxcb/ChangeLog b/dist/libxcb/ChangeLog index b94abb472..8722e5a52 100644 --- a/dist/libxcb/ChangeLog +++ b/dist/libxcb/ChangeLog @@ -1,3 +1,308 @@ +commit c2c4a2cd1947e559718acdba19ef6e7db731dbeb +Author: Matt Turner <mattst88@gmail.com> +Date: Tue May 3 15:09:54 2022 -0700 + + libxcb 1.15 + + Signed-off-by: Matt Turner <mattst88@gmail.com> + +commit ddafdba11f6919e6fcf977c09c78b06f94de47aa +Author: Hodong <hodong@yozmos.com> +Date: Sat Jan 15 02:32:04 2022 +0900 + + Fix a memory leak + + Signed-off-by: Hodong <hodong@yozmos.com> + +commit 43fbf03e549bf6da8d1d8522e0ceddc4d49c37c6 +Author: Demi Marie Obenour <demiobenour@gmail.com> +Date: Thu Sep 23 16:46:32 2021 -0400 + + Fix integer overflows in xcb_in.c + + This fixes an integer overflow security vulnerability in xcb_in.c, which + may allow for memory corruption. + +commit 233d7b7f1f03ef18bf3955eb1f20421e745d22f0 +Author: Thomas Anderson <thomasanderson@google.com> +Date: Wed Dec 2 00:25:42 2020 +0000 + + Fix hang in xcb_request_check() + + This fixes https://gitlab.freedesktop.org/xorg/lib/libxcb/-/issues/53 + + The issue was that libxcb expected to get a reply based on the request_expected + variable, but a reply would never arrive because the request was never actually + written. To resolve this, a separate request_expected_written variable is + added. + +commit dc2811874729ee83fa2aef110f60808c450f9a5a +Author: Ran Benita <ran@unusedvar.com> +Date: Tue Nov 17 23:18:53 2020 +0200 + + Avoid request counter truncation in replies map after 2**32 requests + + The c->in request counters are uint64_t, and can realistically go over + 2**32 over a lifetime of a client. The c->in->replies map however uses + unsigned int keys and the passed request numbers are silently truncated. + + I haven't analyzed in depth what happens what it wraps around but it's + probably nothing good. + + The only user of the xcb_list.c map code is c->in->replies, so just + change it to use uint64_t keys. + + Reviewed-by: Uli Schlachter <psychon@znc.in> + Signed-off-by: Ran Benita <ran@unusedvar.com> + +commit 26396bf156cfa00ecd655ec6a5f2f46626d674c0 +Author: Julien Cristau <jcristau@debian.org> +Date: Tue Feb 2 12:15:10 2021 +0100 + + Add newline when printing auth/connection failure string to stderr + + The reason strings returned by the server don't all include a newline, + so make sure we add one to avoid confusing clients. Xlib used to do + this before it delegated that work to libxcb. + + Fixes #34 + + Signed-off-by: Julien Cristau <jcristau@debian.org> + +commit a503167f751ba77e6819df568b7f5042d2baa9c9 +Author: Uli Schlachter <psychon@znc.in> +Date: Sat May 22 21:43:22 2021 +0200 + + Improve/fix docs for reply fds functions + + Fixes: https://gitlab.freedesktop.org/xorg/lib/libxcb/-/issues/56 + Signed-off-by: Uli Schlachter <psychon@znc.in> + +commit 3c76c0579ffa521af41f78ee937b1337581da985 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: Fri Jul 30 22:58:47 2021 +0300 + + c_client.py: Implement handling of <length> element + + Signed-off-by: Povilas Kanapickas <povilas@radix.lt> + +commit bdc3f21a5205293852bbaa173f43389cbf66f52b +Author: Povilas Kanapickas <povilas@radix.lt> +Date: Fri Jul 30 22:58:46 2021 +0300 + + c_client: Extract _c_get_field_mapping_for_expr() + +commit 068af21cb376eb824fa1dee29a6539feadb93587 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: Fri Jul 30 22:58:45 2021 +0300 + + c_client.py: Use get_expr_field_names directly to resolve list fields + + Using get_expr_fields() is only needed in case we are doing things that + can span multiple types easily, e.g. when deciding what data to pass via + function parameters and so on. + + In _c_serialize_helper_list_field() we are building function body, so + acquiring field names via get_expr_field_names() is enough. + + Signed-off-by: Povilas Kanapickas <povilas@radix.lt> + +commit 4d678b162bf8a3b10e5bdf76df2be63d33c23381 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: Fri Jul 30 22:58:44 2021 +0300 + + c_client.py: Extract get_expr_field_names() + + Signed-off-by: Povilas Kanapickas <povilas@radix.lt> + +commit 21414e7c447f18224c577ed5e32bd5d6e45c44f9 +Author: Peter Harris <pharris@opentext.com> +Date: Mon Feb 1 19:45:28 2021 -0500 + + Fix writev emulation on Windows + + There are at least two bugs in the previous implementation: + + - If an early iovec is partially written, there can be a gap of missing + data (as a later iovec will be started before the early iovec is + completed). + - If a late iovec returns WSAEWOULDBLOCK, *vector and *count are not + updated, leading to a re-send of the entire request. + + Move the *vector update into the send() loop to update piecemeal as + individual iovecs are sent. + + Example program that demonstrates the issue (this program should run + forever after these bugs have been fixed): + + #include <stdio.h> + #include <stdlib.h> + #include "xcb.h" + + // Non-cryptographic random number generator from http://burtleburtle.net/bob/rand/smallprng.html + // because Microsoft's random number generators either have a too small RAND_MAX or are too slow + typedef struct ranctx { uint32_t a; uint32_t b; uint32_t c; uint32_t d; } ranctx; + + static uint32_t ranval(ranctx *x); + static void raninit(ranctx *x, uint32_t seed); + + + #define MAX_PROP_LEN (128 * 1024) + + int main(int argc, char *argv[]) { + uint32_t seed = 0x12345678; + if (argc > 1) { + seed = strtoul(argv[1], NULL, 0); + } + ranctx ran; + raninit(&ran, seed); + + xcb_connection_t *c = xcb_connect(NULL, NULL); + if (!c || xcb_connection_has_error(c)) { + printf("Cannot connect to $DISPLAY\n"); + return 1; + } + const xcb_setup_t *setup = xcb_get_setup(c); + char *buf = malloc(MAX_PROP_LEN + 8); // plus a bit of slack so we can run random values off the end + if (!buf) { + printf("oom\n"); + return 1; + } + for (uint32_t i=0; i < (MAX_PROP_LEN + 3) / 4; i++) { + ((uint32_t *)buf)[i] = ranval(&ran); + } + + xcb_window_t win = xcb_generate_id(c); + xcb_create_window(c, 0, win, xcb_setup_roots_iterator(setup).data[0].root, 0, 0, 1, 1, 0, + XCB_WINDOW_CLASS_INPUT_ONLY, 0, 0, NULL); + printf("Created window 0x%X\n", win); + + for (;;) { + xcb_flush(c); + xcb_generic_event_t *ev = xcb_poll_for_event(c); + if (ev) { + if (ev->response_type == 0) { + xcb_generic_error_t *err = (xcb_generic_error_t *)ev; + printf("Unexpected X Error %d\n", err->error_code); + printf(" Sequence %d\n", err->sequence); + printf(" Resource ID 0x%X\n", err->resource_id); + printf(" Opcode: %d.%d\n", err->major_code, err->minor_code); + return 1; + } + printf("Unexpected X Event %d\n", ev->response_type); + return 1; + } + + uint32_t siz = ranval(&ran) % MAX_PROP_LEN + 1; + xcb_change_property(c, XCB_PROP_MODE_REPLACE, win, XCB_ATOM_STRING, XCB_ATOM_STRING, 8, siz, buf); + } + + return 0; + } + + + #define rot(x,k) (((x)<<(k))|((x)>>(32-(k)))) + static uint32_t ranval(ranctx *x) { + uint32_t e = x->a - rot(x->b, 27); + x->a = x->b ^ rot(x->c, 17); + x->b = x->c + x->d; + x->c = x->d + e; + x->d = e + x->a; + return x->d; + } + + static void raninit(ranctx *x, uint32_t seed) { + uint32_t i; + x->a = 0xf1ea5eed, x->b = x->c = x->d = seed; + for (i = 0; i<20; ++i) { + (void)ranval(x); + } + } + + Signed-off-by: Peter Harris <pharris@opentext.com> + +commit 4b0d9d3868aad8d5f4266821e9eda586e6c2bfa7 +Author: Peter Harris <pharris@opentext.com> +Date: Mon Feb 1 17:43:52 2021 -0500 + + Fix build on Windows + + Notable changes: Protect include of unistd.h (and other POSIX headers). + Use SOCKET (which is larger than int) and closesocket (because close is + not compatible) for sockets. Use <stdint.h>'s intptr_t instead of the + non-portable ssize_t. + + Signed-off-by: Peter Harris <pharris@opentext.com> + +commit cd0fba98a2d0867d505ff1a7ca8d7a7c757acfa2 +Author: Alan Coopersmith <alan.coopersmith@oracle.com> +Date: Tue Jun 1 18:36:17 2021 -0700 + + xcb_auth: Quiet -Wimplicit-fallthrough warning in get_authptr() + + xcb_auth.c:135:14: warning: this statement may fall through [-Wimplicit-fallthrough=] + addr += 12; + ~~~~~^~~~~ + xcb_auth.c:138:5: note: here + case AF_INET: + ^~~~ + + Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com> + +commit 2ef8655987b9862cdddb72223c9f259a860d5777 +Author: Julien Cristau <jcristau@debian.org> +Date: Mon Feb 1 19:23:02 2021 +0100 + + Increment libtool version info for libxcb-dri3 + + Somewhat belatedly given the last update was in xcb-proto 1.13 in 2017... + + Quoting @smcv from https://bugs.debian.org/921069: + >>> + libxcb-dri3 version 1.13 appears to have added new symbols without increasing + the minor ABI version in its -version-info. This will break anything that + compares libraries by their version info to decide which one is newer. + + The Steam Runtime uses libraries' major/minor/micro ABI version info (in this + case 0.0.0) to decide whether to use the system copy of a library or the copy + in the Steam Runtime, depending on which one is newer (#921026). We can + work around this by adding a versioned dependency on libxcb-dri3-0 and + deleting the copy from the Steam Runtime, but this isn't a particularly + scalable solution. + >>> + +commit 4cbcac4eca967abfbff7cf1ea473777c5e8c375c +Author: Ran Benita <ran@unusedvar.com> +Date: Tue Nov 17 23:45:14 2020 +0200 + + gitignore: add files generated by make check + + Signed-off-by: Ran Benita <ran@unusedvar.com> + +commit f01f3c378eb0168fbb055c7be1c2d08a7acd3752 +Author: Ran Benita <ran@unusedvar.com> +Date: Tue Nov 17 23:43:06 2020 +0200 + + tests: don't use deprecated fail_unless check API + + It causes errors like this when running make check: + + check_public.c:40:24: error: too many arguments for format [-Werror=format-extra-args] + 40 | fail_unless(success, "unexpected parse failure %sfor '%s'", test_string[test_type], name); + + Closes: https://gitlab.freedesktop.org/xorg/lib/libxcb/-/issues/49 + Tested-by: Matt Turner <mattst88@gmail.com> + Signed-off-by: Ran Benita <ran@unusedvar.com> + +commit 704e0a91b1dece9a4cce7cfe8beaeb86a5e14267 +Author: Eduardo Sánchez Muñoz <esm@eduardosm.net> +Date: Mon Mar 2 18:59:45 2020 +0100 + + Use the 'present' field to properly check that the XC-MISC + extension is available in xcb_generate_id. + + Also document the returned value when xcb_generate_id fails. + commit 4b40b44cb6d088b6ffa2fb5cf3ad8f12da588cef Author: Matt Turner <mattst88@gmail.com> Date: Sat Feb 22 12:10:53 2020 -0800 diff --git a/dist/libxcb/build-aux/compile b/dist/libxcb/build-aux/compile index 99e50524b..df363c8fb 100644 --- a/dist/libxcb/build-aux/compile +++ b/dist/libxcb/build-aux/compile @@ -3,7 +3,7 @@ scriptversion=2018-03-07.03; # UTC -# Copyright (C) 1999-2018 Free Software Foundation, Inc. +# Copyright (C) 1999-2021 Free Software Foundation, Inc. # Written by Tom Tromey <tromey@cygnus.com>. # # This program is free software; you can redistribute it and/or modify @@ -53,7 +53,7 @@ func_file_conv () MINGW*) file_conv=mingw ;; - CYGWIN*) + CYGWIN* | MSYS*) file_conv=cygwin ;; *) @@ -67,7 +67,7 @@ func_file_conv () mingw/*) file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` ;; - cygwin/*) + cygwin/* | msys/*) file=`cygpath -m "$file" || echo "$file"` ;; wine/*) diff --git a/dist/libxcb/build-aux/test-driver b/dist/libxcb/build-aux/test-driver index b8521a482..be73b80ad 100644 --- a/dist/libxcb/build-aux/test-driver +++ b/dist/libxcb/build-aux/test-driver @@ -3,7 +3,7 @@ scriptversion=2018-03-07.03; # UTC -# Copyright (C) 2011-2018 Free Software Foundation, Inc. +# Copyright (C) 2011-2021 Free Software Foundation, Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -42,11 +42,13 @@ print_usage () { cat <<END Usage: - test-driver --test-name=NAME --log-file=PATH --trs-file=PATH - [--expect-failure={yes|no}] [--color-tests={yes|no}] - [--enable-hard-errors={yes|no}] [--] + test-driver --test-name NAME --log-file PATH --trs-file PATH + [--expect-failure {yes|no}] [--color-tests {yes|no}] + [--enable-hard-errors {yes|no}] [--] TEST-SCRIPT [TEST-SCRIPT-ARGUMENTS] + The '--test-name', '--log-file' and '--trs-file' options are mandatory. +See the GNU Automake documentation for information. END } @@ -103,8 +105,11 @@ trap "st=130; $do_exit" 2 trap "st=141; $do_exit" 13 trap "st=143; $do_exit" 15 -# Test script is run here. -"$@" >$log_file 2>&1 +# Test script is run here. We create the file first, then append to it, +# to ameliorate tests themselves also writing to the log file. Our tests +# don't, but others can (automake bug#35762). +: >"$log_file" +"$@" >>"$log_file" 2>&1 estatus=$? if test $enable_hard_errors = no && test $estatus -eq 99; then @@ -126,7 +131,7 @@ esac # know whether the test passed or failed simply by looking at the '.log' # file, without the need of also peaking into the corresponding '.trs' # file (automake bug#11814). -echo "$res $test_name (exit status: $estatus)" >>$log_file +echo "$res $test_name (exit status: $estatus)" >>"$log_file" # Report outcome to console. echo "${col}${res}${std}: $test_name" diff --git a/dist/libxcb/configure.ac b/dist/libxcb/configure.ac index adb48e789..4198a508c 100644 --- a/dist/libxcb/configure.ac +++ b/dist/libxcb/configure.ac @@ -2,7 +2,7 @@ dnl Process this file with autoconf to produce a configure script. # Initialize Autoconf AC_PREREQ([2.60]) -AC_INIT([libxcb],[1.14], +AC_INIT([libxcb],[1.15], [https://gitlab.freedesktop.org/xorg/lib/libxcb/issues], [libxcb]) AC_CONFIG_AUX_DIR([build-aux]) @@ -36,7 +36,7 @@ if test x"$HAVE_DOT" = xno; then AC_MSG_WARN([dot not found - doxygen targets will be skipped]) fi -PKG_CHECK_MODULES(CHECK, [check >= 0.9.4], [HAVE_CHECK=yes], [HAVE_CHECK=no]) +PKG_CHECK_MODULES(CHECK, [check >= 0.9.6], [HAVE_CHECK=yes], [HAVE_CHECK=no]) AM_CONDITIONAL(HAVE_CHECK, test x$HAVE_CHECK = xyes) XSLTPROC=no diff --git a/dist/libxcb/m4/libtool.m4 b/dist/libxcb/m4/libtool.m4 index ae7c90613..a70aea9fe 100644 --- a/dist/libxcb/m4/libtool.m4 +++ b/dist/libxcb/m4/libtool.m4 @@ -1076,7 +1076,7 @@ _LT_EOF _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; 10.[[012]][[,.]]*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; - 10.*) + 10.*|11.*) _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; esac ;; diff --git a/dist/libxcb/src/Makefile.am b/dist/libxcb/src/Makefile.am index 17b64a80e..c2984b3f0 100644 --- a/dist/libxcb/src/Makefile.am +++ b/dist/libxcb/src/Makefile.am @@ -59,7 +59,7 @@ endif EXTSOURCES += dri3.c if BUILD_DRI3 lib_LTLIBRARIES += libxcb-dri3.la -libxcb_dri3_la_LDFLAGS = -version-info 0:0:0 -no-undefined @lt_enable_auto_import@ +libxcb_dri3_la_LDFLAGS = -version-info 1:0:1 -no-undefined @lt_enable_auto_import@ libxcb_dri3_la_LIBADD = $(XCB_LIBS) nodist_libxcb_dri3_la_SOURCES = dri3.c dri3.h endif diff --git a/dist/libxcb/src/c_client.py b/dist/libxcb/src/c_client.py index 39f162ea9..fd256f015 100644 --- a/dist/libxcb/src/c_client.py +++ b/dist/libxcb/src/c_client.py @@ -649,39 +649,42 @@ def _c_helper_resolve_field_names (prefix): return all_fields + +def get_expr_field_names(expr): + """ + returns a list of field names referenced in an expression + """ + if expr.op is None or expr.op == 'calculate_len': + if expr.lenfield_name is not None: + return [expr.lenfield_name] + # constant value expr + return [] + + if expr.op == '~': + return get_expr_field_names(expr.rhs) + if expr.op == 'popcount': + return get_expr_field_names(expr.rhs) + if expr.op == 'sumof': + # sumof expr references another list, + # we need that list's length field here + field = None + for f in expr.lenfield_parent.fields: + if f.field_name == expr.lenfield_name: + field = f + break + if field is None: + raise Exception("list field '%s' referenced by sumof not found" % expr.lenfield_name) + # referenced list + its length field + return [expr.lenfield_name] + get_expr_field_names(field.type.expr) + if expr.op == 'enumref': + return [] + return get_expr_field_names(expr.lhs) + get_expr_field_names(expr.rhs) + + def get_expr_fields(self): """ get the Fields referenced by switch or list expression """ - def get_expr_field_names(expr): - if expr.op is None or expr.op == 'calculate_len': - if expr.lenfield_name is not None: - return [expr.lenfield_name] - else: - # constant value expr - return [] - else: - if expr.op == '~': - return get_expr_field_names(expr.rhs) - elif expr.op == 'popcount': - return get_expr_field_names(expr.rhs) - elif expr.op == 'sumof': - # sumof expr references another list, - # we need that list's length field here - field = None - for f in expr.lenfield_parent.fields: - if f.field_name == expr.lenfield_name: - field = f - break - if field is None: - raise Exception("list field '%s' referenced by sumof not found" % expr.lenfield_name) - # referenced list + its length field - return [expr.lenfield_name] + get_expr_field_names(field.type.expr) - elif expr.op == 'enumref': - return [] - else: - return get_expr_field_names(expr.lhs) + get_expr_field_names(expr.rhs) - # get_expr_field_names() # resolve the field names with the parent structure(s) unresolved_fields_names = get_expr_field_names(self.expr) @@ -963,18 +966,15 @@ def _c_get_additional_type_params(type): param_fields, wire_fields, params = get_serialize_params('sizeof', type) return params[1:] -def _c_serialize_helper_list_field(context, self, field, - code_lines, temp_vars, - space, prefix): + +def _c_get_field_mapping_for_expr(self, expr, prefix): """ - helper function to cope with lists of variable length + helper function to get field mapping of a particular expression. """ - expr = field.type.expr - prefix_str = _c_helper_fieldaccess_expr(prefix) param_fields, wire_fields, params = get_serialize_params('sizeof', self) param_names = [p[2] for p in params] - expr_fields_names = [f.field_name for f in get_expr_fields(field.type)] + expr_fields_names = get_expr_field_names(expr) resolved = [x for x in expr_fields_names if x in param_names] unresolved = [x for x in expr_fields_names if x not in param_names] @@ -993,6 +993,21 @@ def _c_serialize_helper_list_field(context, self, field, unresolved = [x for x in unresolved if x not in field_mapping] if len(unresolved)>0: raise Exception('could not resolve the length fields required for list %s' % field.c_field_name) + + return field_mapping + + +def _c_serialize_helper_list_field(context, self, field, + code_lines, temp_vars, + space, prefix): + """ + helper function to cope with lists of variable length + """ + expr = field.type.expr + prefix_str = _c_helper_fieldaccess_expr(prefix) + + field_mapping = _c_get_field_mapping_for_expr(self, field.type.expr, prefix) + if expr.op == 'calculate_len': list_length = field.type.expr.lenfield_name else: @@ -1402,6 +1417,16 @@ def _c_serialize(context, self): elif 'sizeof' == context: param_names = [p[2] for p in params] + if self.length_expr is not None: + _c(' const %s *_aux = (%s *)_buffer;', self.c_type, self.c_type) + prefix = [('_aux', '->', self)] + + field_mapping = _c_get_field_mapping_for_expr(self, self.length_expr, prefix) + + _c(' return %s;', _c_accessor_get_expr(self.length_expr, field_mapping)) + _c('}') + _c_pre.redirect_end() + return if self.is_switch: # switch: call _unpack() _c(' %s _aux;', self.c_type) @@ -2586,9 +2611,10 @@ def _c_reply_fds(self, name): _h(' * @param c The connection') _h(' * @param reply The reply') _h(' *') - _h(' * Returns the array of reply fds of the request asked by') + _h(' * Returns a pointer to the array of reply fds of the reply.') _h(' *') - _h(' * The returned value must be freed by the caller using free().') + _h(' * The returned value points into the reply and must not be free().') + _h(' * The fds are not managed by xcb. You must close() them before freeing the reply.') _h(' */') _c('') _hc('int *') diff --git a/dist/libxcb/src/xcb.h b/dist/libxcb/src/xcb.h index dd7f532d0..3f39bb4ab 100644 --- a/dist/libxcb/src/xcb.h +++ b/dist/libxcb/src/xcb.h @@ -51,7 +51,11 @@ extern "C" { * @file xcb.h */ +#ifdef __GNUC__ #define XCB_PACKED __attribute__((__packed__)) +#else +#define XCB_PACKED +#endif /** * @defgroup XCB_Core_API XCB Core API @@ -591,7 +595,7 @@ xcb_connection_t *xcb_connect_to_display_with_auth_info(const char *display, xcb /** * @brief Allocates an XID for a new object. * @param c The connection. - * @return A newly allocated XID. + * @return A newly allocated XID, or -1 on failure. * * Allocates an XID for a new object. Typically used just prior to * various object creation functions, such as xcb_create_window. diff --git a/dist/libxcb/src/xcb_auth.c b/dist/libxcb/src/xcb_auth.c index 26eebbb0c..8ebe9a437 100644 --- a/dist/libxcb/src/xcb_auth.c +++ b/dist/libxcb/src/xcb_auth.c @@ -31,8 +31,6 @@ #include <assert.h> #include <X11/Xauth.h> -#include <sys/param.h> -#include <unistd.h> #include <stdlib.h> #include <time.h> @@ -49,6 +47,8 @@ #endif #include "xcb_windefs.h" #else +#include <sys/param.h> +#include <unistd.h> #include <arpa/inet.h> #include <sys/socket.h> #include <netinet/in.h> @@ -134,6 +134,7 @@ static Xauth *get_authptr(struct sockaddr *sockname, int display) } addr += 12; /* if v4-mapped, fall through. */ + XCB_ALLOW_FALLTHRU #endif case AF_INET: if(!addr) @@ -270,10 +271,17 @@ static int compute_auth(xcb_auth_info_t *info, Xauth *authptr, struct sockaddr * to the value returned by either getpeername() or getsockname() (according to POSIX, applications should not assume a particular length for `sockaddr_un.sun_path') */ +#ifdef _WIN32 +static struct sockaddr *get_peer_sock_name(int(_stdcall *socket_func)(SOCKET, + struct sockaddr *, + socklen_t *), + int fd) +#else static struct sockaddr *get_peer_sock_name(int (*socket_func)(int, struct sockaddr *, socklen_t *), int fd) +#endif { socklen_t socknamelen = sizeof(struct sockaddr) + INITIAL_SOCKNAME_SLACK; socklen_t actual_socknamelen = socknamelen; diff --git a/dist/libxcb/src/xcb_conn.c b/dist/libxcb/src/xcb_conn.c index 8dab6589b..3084c18fd 100644 --- a/dist/libxcb/src/xcb_conn.c +++ b/dist/libxcb/src/xcb_conn.c @@ -32,7 +32,6 @@ #include <assert.h> #include <string.h> #include <stdio.h> -#include <unistd.h> #include <stdlib.h> #include <fcntl.h> #include <errno.h> @@ -48,7 +47,9 @@ #ifdef _WIN32 #include "xcb_windefs.h" +#include <io.h> #else +#include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> #endif /* _WIN32 */ @@ -169,6 +170,8 @@ static int write_setup(xcb_connection_t *c, xcb_auth_info_t *auth_info) static int read_setup(xcb_connection_t *c) { + const char newline = '\n'; + /* Read the server response */ c->setup = malloc(sizeof(xcb_setup_generic_t)); if(!c->setup) @@ -194,6 +197,7 @@ static int read_setup(xcb_connection_t *c) { xcb_setup_failed_t *setup = (xcb_setup_failed_t *) c->setup; write(STDERR_FILENO, xcb_setup_failed_reason(setup), xcb_setup_failed_reason_length(setup)); + write(STDERR_FILENO, &newline, 1); return 0; } @@ -201,6 +205,7 @@ static int read_setup(xcb_connection_t *c) { xcb_setup_authenticate_t *setup = (xcb_setup_authenticate_t *) c->setup; write(STDERR_FILENO, xcb_setup_authenticate_reason(setup), xcb_setup_authenticate_reason_length(setup)); + write(STDERR_FILENO, &newline, 1); return 0; } } @@ -211,33 +216,47 @@ static int read_setup(xcb_connection_t *c) /* precondition: there must be something for us to write. */ static int write_vec(xcb_connection_t *c, struct iovec **vector, int *count) { +#ifndef _WIN32 int n; +#endif + assert(!c->out.queue_len); #ifdef _WIN32 - int i = 0; - int ret = 0,err = 0; - struct iovec *vec; - n = 0; - /* Could use the WSASend win32 function for scatter/gather i/o but setting up the WSABUF struct from an iovec would require more work and I'm not sure of the benefit....works for now */ - vec = *vector; - while(i < *count) + while (*count) { - ret = send(c->fd,vec->iov_base,vec->iov_len,0); - if(ret == SOCKET_ERROR) - { - err = WSAGetLastError(); - if(err == WSAEWOULDBLOCK) - { - return 1; - } - } - n += ret; - *vec++; - i++; + struct iovec *vec = *vector; + if (vec->iov_len) + { + int ret = send(c->fd, vec->iov_base, vec->iov_len, 0); + if (ret == SOCKET_ERROR) + { + int err = WSAGetLastError(); + if (err == WSAEWOULDBLOCK) + { + return 1; + } + } + if (ret <= 0) + { + _xcb_conn_shutdown(c, XCB_CONN_ERROR); + return 0; + } + c->out.total_written += ret; + vec->iov_len -= ret; + vec->iov_base = (char *)vec->iov_base + ret; + } + if (vec->iov_len == 0) { + (*vector)++; + (*count)--; + } } + + if (!*count) + *vector = 0; + #else n = *count; if (n > IOV_MAX) @@ -279,8 +298,6 @@ static int write_vec(xcb_connection_t *c, struct iovec **vector, int *count) return 1; } -#endif /* _WIN32 */ - if(n <= 0) { _xcb_conn_shutdown(c, XCB_CONN_ERROR); @@ -302,6 +319,9 @@ static int write_vec(xcb_connection_t *c, struct iovec **vector, int *count) if(!*count) *vector = 0; assert(n == 0); + +#endif /* _WIN32 */ + return 1; } @@ -345,7 +365,11 @@ xcb_connection_t *xcb_connect_to_fd(int fd, xcb_auth_info_t *auth_info) c = calloc(1, sizeof(xcb_connection_t)); if(!c) { +#ifdef _WIN32 + closesocket(fd); +#else close(fd); +#endif return _xcb_conn_ret_error(XCB_CONN_CLOSED_MEM_INSUFFICIENT) ; } @@ -378,7 +402,11 @@ void xcb_disconnect(xcb_connection_t *c) /* disallow further sends and receives */ shutdown(c->fd, SHUT_RDWR); +#ifdef _WIN32 + closesocket(c->fd); +#else close(c->fd); +#endif pthread_mutex_destroy(&c->iolock); _xcb_in_destroy(&c->in); 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); diff --git a/dist/libxcb/src/xcb_list.c b/dist/libxcb/src/xcb_list.c index 129540bc4..bdd2d43f7 100644 --- a/dist/libxcb/src/xcb_list.c +++ b/dist/libxcb/src/xcb_list.c @@ -36,7 +36,7 @@ typedef struct node { struct node *next; - unsigned int key; + uint64_t key; void *data; } node; @@ -73,7 +73,7 @@ void _xcb_map_delete(_xcb_map *list, xcb_list_free_func_t do_free) free(list); } -int _xcb_map_put(_xcb_map *list, unsigned int key, void *data) +int _xcb_map_put(_xcb_map *list, uint64_t key, void *data) { node *cur = malloc(sizeof(node)); if(!cur) @@ -86,7 +86,7 @@ int _xcb_map_put(_xcb_map *list, unsigned int key, void *data) return 1; } -void *_xcb_map_remove(_xcb_map *list, unsigned int key) +void *_xcb_map_remove(_xcb_map *list, uint64_t key) { node **cur; for(cur = &list->head; *cur; cur = &(*cur)->next) diff --git a/dist/libxcb/src/xcb_out.c b/dist/libxcb/src/xcb_out.c index c9593e5f2..a4fe823b3 100644 --- a/dist/libxcb/src/xcb_out.c +++ b/dist/libxcb/src/xcb_out.c @@ -31,7 +31,11 @@ #include <assert.h> #include <stdlib.h> +#ifdef _WIN32 +#include <io.h> +#else #include <unistd.h> +#endif #include <string.h> #include "xcb.h" @@ -443,6 +447,7 @@ int _xcb_out_init(_xcb_out *out) out->request = 0; out->request_written = 0; + out->request_expected_written = 0; if(pthread_mutex_init(&out->reqlenlock, 0)) return 0; @@ -453,8 +458,9 @@ int _xcb_out_init(_xcb_out *out) void _xcb_out_destroy(_xcb_out *out) { - pthread_cond_destroy(&out->cond); pthread_mutex_destroy(&out->reqlenlock); + pthread_cond_destroy(&out->cond); + pthread_cond_destroy(&out->socket_cond); } int _xcb_out_send(xcb_connection_t *c, struct iovec *vector, int count) @@ -463,6 +469,7 @@ int _xcb_out_send(xcb_connection_t *c, struct iovec *vector, int count) while(ret && count) ret = _xcb_conn_wait(c, &c->out.cond, &vector, &count); c->out.request_written = c->out.request; + c->out.request_expected_written = c->in.request_expected; pthread_cond_broadcast(&c->out.cond); _xcb_in_wake_up_next_reader(c); return ret; diff --git a/dist/libxcb/src/xcb_util.c b/dist/libxcb/src/xcb_util.c index a16270c63..0296ce0dd 100644 --- a/dist/libxcb/src/xcb_util.c +++ b/dist/libxcb/src/xcb_util.c @@ -36,12 +36,12 @@ #include <stdio.h> #include <stdlib.h> #include <stddef.h> -#include <unistd.h> #include <string.h> #ifdef _WIN32 #include "xcb_windefs.h" #else +#include <unistd.h> #include <arpa/inet.h> #include <sys/socket.h> #include <sys/un.h> @@ -415,7 +415,11 @@ static int _xcb_open_tcp(const char *host, char *protocol, const unsigned short if(_xcb_do_connect(fd, (struct sockaddr*)&_s, sizeof(_s)) >= 0) break; +#ifdef _WIN32 + closesocket(fd); +#else close(fd); +#endif fd = -1; ++_c; } diff --git a/dist/libxcb/src/xcb_xid.c b/dist/libxcb/src/xcb_xid.c index 79a9a27de..ebe41a142 100644 --- a/dist/libxcb/src/xcb_xid.c +++ b/dist/libxcb/src/xcb_xid.c @@ -55,7 +55,7 @@ uint32_t xcb_generate_id(xcb_connection_t *c) /* check for extension */ const xcb_query_extension_reply_t *xc_misc_reply = xcb_get_extension_data(c, &xcb_xc_misc_id); - if (!xc_misc_reply) { + if (!xc_misc_reply || !xc_misc_reply->present) { pthread_mutex_unlock(&c->xid.lock); return -1; } diff --git a/dist/libxcb/src/xcbint.h b/dist/libxcb/src/xcbint.h index cef9821a8..235c8481a 100644 --- a/dist/libxcb/src/xcbint.h +++ b/dist/libxcb/src/xcbint.h @@ -38,6 +38,16 @@ #pragma GCC visibility push(hidden) #endif +#ifndef __has_attribute +# define __has_attribute(x) 0 /* Compatibility with older compilers. */ +#endif + +#if __has_attribute(fallthrough) +# define XCB_ALLOW_FALLTHRU __attribute__ ((fallthrough)); +#else +# define XCB_ALLOW_FALLTHRU /* FALLTHRU */ +#endif + enum workarounds { WORKAROUND_NONE, WORKAROUND_GLX_GET_FB_CONFIGS_BUG, @@ -73,8 +83,8 @@ typedef struct _xcb_map _xcb_map; _xcb_map *_xcb_map_new(void); void _xcb_map_delete(_xcb_map *q, xcb_list_free_func_t do_free); -int _xcb_map_put(_xcb_map *q, unsigned int key, void *data); -void *_xcb_map_remove(_xcb_map *q, unsigned int key); +int _xcb_map_put(_xcb_map *q, uint64_t key, void *data); +void *_xcb_map_remove(_xcb_map *q, uint64_t key); /* xcb_out.c */ @@ -103,6 +113,7 @@ typedef struct _xcb_out { uint64_t request; uint64_t request_written; + uint64_t request_expected_written; uint64_t total_written; pthread_mutex_t reqlenlock; diff --git a/dist/libxcb/tests/check_public.c b/dist/libxcb/tests/check_public.c index 2094bfef1..aed40c8fb 100644 --- a/dist/libxcb/tests/check_public.c +++ b/dist/libxcb/tests/check_public.c @@ -37,18 +37,18 @@ static void parse_display_pass(const char *name, const char *host, const int dis got_display = got_screen = -42; mark_point(); success = xcb_parse_display(argument, &got_host, &got_display, &got_screen); - fail_unless(success, "unexpected parse failure %sfor '%s'", test_string[test_type], name); - fail_unless(strcmp(host, got_host) == 0, "parse %sproduced unexpected hostname '%s' for '%s': expected '%s'", test_string[test_type], got_host, name, host); - fail_unless(display == got_display, "parse %sproduced unexpected display '%d' for '%s': expected '%d'", test_string[test_type], got_display, name, display); - fail_unless(screen == got_screen, "parse %sproduced unexpected screen '%d' for '%s': expected '%d'", test_string[test_type], got_screen, name, screen); + ck_assert_msg(success, "unexpected parse failure %sfor '%s'", test_string[test_type], name); + ck_assert_msg(strcmp(host, got_host) == 0, "parse %sproduced unexpected hostname '%s' for '%s': expected '%s'", test_string[test_type], got_host, name, host); + ck_assert_msg(display == got_display, "parse %sproduced unexpected display '%d' for '%s': expected '%d'", test_string[test_type], got_display, name, display); + ck_assert_msg(screen == got_screen, "parse %sproduced unexpected screen '%d' for '%s': expected '%d'", test_string[test_type], got_screen, name, screen); got_host = (char *) -1; got_display = got_screen = -42; mark_point(); success = xcb_parse_display(argument, &got_host, &got_display, 0); - fail_unless(success, "unexpected screenless parse failure %sfor '%s'", test_string[test_type], name); - fail_unless(strcmp(host, got_host) == 0, "screenless parse %sproduced unexpected hostname '%s' for '%s': expected '%s'", test_string[test_type], got_host, name, host); - fail_unless(display == got_display, "screenless parse %sproduced unexpected display '%d' for '%s': expected '%d'", test_string[test_type], got_display, name, display); + ck_assert_msg(success, "unexpected screenless parse failure %sfor '%s'", test_string[test_type], name); + ck_assert_msg(strcmp(host, got_host) == 0, "screenless parse %sproduced unexpected hostname '%s' for '%s': expected '%s'", test_string[test_type], got_host, name, host); + ck_assert_msg(display == got_display, "screenless parse %sproduced unexpected display '%d' for '%s': expected '%d'", test_string[test_type], got_display, name, display); } putenv("DISPLAY="); } @@ -79,18 +79,18 @@ static void parse_display_fail(const char *name) got_display = got_screen = -42; mark_point(); success = xcb_parse_display(argument, &got_host, &got_display, &got_screen); - fail_unless(!success, "unexpected parse success %sfor '%s'", test_string[test_type], name); - fail_unless(got_host == (char *) -1, "host changed on parse failure %sfor '%s': got %p", test_string[test_type], name, got_host); - fail_unless(got_display == -42, "display changed on parse failure %sfor '%s': got %d", test_string[test_type], name, got_display); - fail_unless(got_screen == -42, "screen changed on parse failure %sfor '%s': got %d", test_string[test_type], name, got_screen); + ck_assert_msg(!success, "unexpected parse success %sfor '%s'", test_string[test_type], name); + ck_assert_msg(got_host == (char *) -1, "host changed on parse failure %sfor '%s': got %p", test_string[test_type], name, got_host); + ck_assert_msg(got_display == -42, "display changed on parse failure %sfor '%s': got %d", test_string[test_type], name, got_display); + ck_assert_msg(got_screen == -42, "screen changed on parse failure %sfor '%s': got %d", test_string[test_type], name, got_screen); got_host = (char *) -1; got_display = got_screen = -42; mark_point(); success = xcb_parse_display(argument, &got_host, &got_display, 0); - fail_unless(!success, "unexpected screenless parse success %sfor '%s'", test_string[test_type], name); - fail_unless(got_host == (char *) -1, "host changed on parse failure %sfor '%s': got %p", test_string[test_type], name, got_host); - fail_unless(got_display == -42, "display changed on parse failure %sfor '%s': got %d", test_string[test_type], name, got_display); + ck_assert_msg(!success, "unexpected screenless parse success %sfor '%s'", test_string[test_type], name); + ck_assert_msg(got_host == (char *) -1, "host changed on parse failure %sfor '%s': got %p", test_string[test_type], name, got_host); + ck_assert_msg(got_display == -42, "display changed on parse failure %sfor '%s': got %d", test_string[test_type], name, got_display); } putenv("DISPLAY="); } @@ -183,7 +183,7 @@ END_TEST static void popcount_eq(uint32_t bits, int count) { - fail_unless(xcb_popcount(bits) == count, "unexpected popcount(%08x) != %d", bits, count); + ck_assert_msg(xcb_popcount(bits) == count, "unexpected popcount(%08x) != %d", bits, count); } START_TEST(popcount) |