summaryrefslogtreecommitdiff
path: root/dist/libxcb
diff options
context:
space:
mode:
Diffstat (limited to 'dist/libxcb')
-rw-r--r--dist/libxcb/ChangeLog305
-rw-r--r--dist/libxcb/build-aux/compile6
-rw-r--r--dist/libxcb/build-aux/test-driver19
-rw-r--r--dist/libxcb/configure.ac4
-rw-r--r--dist/libxcb/m4/libtool.m42
-rw-r--r--dist/libxcb/src/Makefile.am2
-rw-r--r--dist/libxcb/src/c_client.py102
-rw-r--r--dist/libxcb/src/xcb.h6
-rw-r--r--dist/libxcb/src/xcb_auth.c12
-rw-r--r--dist/libxcb/src/xcb_conn.c72
-rw-r--r--dist/libxcb/src/xcb_in.c29
-rw-r--r--dist/libxcb/src/xcb_list.c6
-rw-r--r--dist/libxcb/src/xcb_out.c9
-rw-r--r--dist/libxcb/src/xcb_util.c6
-rw-r--r--dist/libxcb/src/xcb_xid.c2
-rw-r--r--dist/libxcb/src/xcbint.h15
-rw-r--r--dist/libxcb/tests/check_public.c30
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)