libxcb & xcb-util fixes

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

libxcb & xcb-util fixes

David Coppa
Hi,

Since upstream is still far from a new stable release,
I think it would be good to have some fixes from their git
imported in our xenocara tree for 4.8.

Obviously, I've only included fixes and improvements and
not those patches adding new features.

Tested with two xcb-based WMs from ports, x11/i3 and
x11/awesome.

Would it be ok for you?

Cheers,
David

Index: libxcb/src/xcb_auth.c
===================================================================
RCS file: /cvs/xenocara/dist/libxcb/src/xcb_auth.c,v
retrieving revision 1.3
diff -u -p -r1.3 xcb_auth.c
--- libxcb/src/xcb_auth.c 18 Apr 2010 20:06:18 -0000 1.3
+++ libxcb/src/xcb_auth.c 22 Jul 2010 09:56:48 -0000
@@ -89,8 +89,7 @@ static int authname_match(enum auth_prot
 
 #define SIN6_ADDR(s) (&((struct sockaddr_in6 *)s)->sin6_addr)
 
-static Xauth *get_authptr(struct sockaddr *sockname, unsigned int socknamelen,
-                          int display)
+static Xauth *get_authptr(struct sockaddr *sockname, int display)
 {
     char *addr = 0;
     int addrlen = 0;
@@ -243,13 +242,55 @@ static int compute_auth(xcb_auth_info_t
     return 0;   /* Unknown authorization type */
 }
 
+/* `sockaddr_un.sun_path' typical size usually ranges between 92 and 108 */
+#define INITIAL_SOCKNAME_SLACK 108
+
+/* Return a dynamically allocated socket address structure according
+   to the value returned by either getpeername() or getsockname()
+   (according to POSIX, applications should not assume a particular
+   length for `sockaddr_un.sun_path') */
+static struct sockaddr *get_peer_sock_name(int (*socket_func)(int,
+      struct sockaddr *,
+      socklen_t *),
+   int fd)
+{
+    socklen_t socknamelen = sizeof(struct sockaddr) + INITIAL_SOCKNAME_SLACK;
+    socklen_t actual_socknamelen = socknamelen;
+    struct sockaddr *sockname = malloc(socknamelen), *new_sockname = NULL;
+
+    if (sockname == NULL)
+        return NULL;
+
+    /* Both getpeername() and getsockname() truncates sockname if
+       there is not enough space and set the required length in
+       actual_socknamelen */
+    if (socket_func(fd, sockname, &actual_socknamelen) == -1)
+        goto sock_or_realloc_error;
+
+    if (actual_socknamelen > socknamelen)
+    {
+        socknamelen = actual_socknamelen;
+
+        if ((new_sockname = realloc(sockname, actual_socknamelen)) == NULL ||
+            socket_func(fd, new_sockname, &actual_socknamelen) == -1 ||
+            actual_socknamelen > socknamelen)
+            goto sock_or_realloc_error;
+
+        sockname = new_sockname;
+    }
+
+    return sockname;
+
+ sock_or_realloc_error:
+    free(sockname);
+    return NULL;
+}
+
 int _xcb_get_auth_info(int fd, xcb_auth_info_t *info, int display)
 {
     /* code adapted from Xlib/ConnDis.c, xtrans/Xtranssocket.c,
        xtrans/Xtransutils.c */
-    char sockbuf[sizeof(struct sockaddr) + MAXPATHLEN];
-    unsigned int socknamelen = sizeof(sockbuf);   /* need extra space */
-    struct sockaddr *sockname = (struct sockaddr *) &sockbuf;
+    struct sockaddr *sockname = NULL;
     int gotsockname = 0;
     Xauth *authptr = 0;
     int ret = 1;
@@ -258,24 +299,30 @@ int _xcb_get_auth_info(int fd, xcb_auth_
      * for UNIX Domain Sockets, but this is irrelevant,
      * since compute_auth() ignores the peer name in this
      * case anyway.*/
-    if (getpeername(fd, sockname, &socknamelen) == -1)
+    if ((sockname = get_peer_sock_name(getpeername, fd)) == NULL)
     {
-        if (getsockname(fd, sockname, &socknamelen) == -1)
+        if ((sockname = get_peer_sock_name(getsockname, fd)) == NULL)
             return 0;   /* can only authenticate sockets */
         if (sockname->sa_family != AF_UNIX)
+        {
+            free(sockname);
             return 0;   /* except for AF_UNIX, sockets should have peernames */
+        }
         gotsockname = 1;
     }
 
-    authptr = get_authptr(sockname, socknamelen, display);
+    authptr = get_authptr(sockname, display);
     if (authptr == 0)
+    {
+        free(sockname);
         return 0;   /* cannot find good auth data */
+    }
 
     info->namelen = memdup(&info->name, authptr->name, authptr->name_length);
     if (!info->namelen)
         goto no_auth;   /* out of memory */
 
-    if (!gotsockname && getsockname(fd, sockname, &socknamelen) == -1)
+    if (!gotsockname && (sockname = get_peer_sock_name(getsockname, fd)) == NULL)
     {
         free(info->name);
         goto no_auth;   /* can only authenticate sockets */
@@ -288,10 +335,15 @@ int _xcb_get_auth_info(int fd, xcb_auth_
         goto no_auth;   /* cannot build auth record */
     }
 
+    free(sockname);
+    sockname = NULL;
+
     XauDisposeAuth(authptr);
     return ret;
 
  no_auth:
+    free(sockname);
+
     info->name = 0;
     info->namelen = 0;
     XauDisposeAuth(authptr);
Index: libxcb/src/xcb_conn.c
===================================================================
RCS file: /cvs/xenocara/dist/libxcb/src/xcb_conn.c,v
retrieving revision 1.3
diff -u -p -r1.3 xcb_conn.c
--- libxcb/src/xcb_conn.c 18 Apr 2010 20:06:18 -0000 1.3
+++ libxcb/src/xcb_conn.c 22 Jul 2010 09:56:48 -0000
@@ -102,10 +102,7 @@ static int write_setup(xcb_connection_t
     assert(count <= (int) (sizeof(parts) / sizeof(*parts)));
 
     pthread_mutex_lock(&c->iolock);
-    {
-        struct iovec *parts_ptr = parts;
-        ret = _xcb_out_send(c, &parts_ptr, &count);
-    }
+    ret = _xcb_out_send(c, parts, count);
     pthread_mutex_unlock(&c->iolock);
     return ret;
 }
Index: libxcb/src/xcb_in.c
===================================================================
RCS file: /cvs/xenocara/dist/libxcb/src/xcb_in.c,v
retrieving revision 1.3
diff -u -p -r1.3 xcb_in.c
--- libxcb/src/xcb_in.c 18 Apr 2010 20:06:18 -0000 1.3
+++ libxcb/src/xcb_in.c 22 Jul 2010 09:56:48 -0000
@@ -69,16 +69,6 @@ typedef struct reader_list {
     struct reader_list *next;
 } reader_list;
 
-static void wake_up_next_reader(xcb_connection_t *c)
-{
-    int pthreadret;
-    if(c->in.readers)
-        pthreadret = pthread_cond_signal(c->in.readers->data);
-    else
-        pthreadret = pthread_cond_signal(&c->in.event_cond);
-    assert(pthreadret == 0);
-}
-
 static int read_packet(xcb_connection_t *c)
 {
     xcb_generic_reply_t genrep;
@@ -154,9 +144,7 @@ static int read_packet(xcb_connection_t
 
     /* XGE events may have sizes > 32 */
     if (genrep.response_type == XCB_XGE_EVENT)
-    {
-        eventlength = ((xcb_ge_event_t*)&genrep)->length * 4;
-    }
+        eventlength = genrep.length * 4;
 
     buf = malloc(length + eventlength +
             (genrep.response_type == XCB_REPLY ? 0 : sizeof(uint32_t)));
@@ -404,7 +392,7 @@ void *xcb_wait_for_reply(xcb_connection_
         pthread_cond_destroy(&cond);
     }
 
-    wake_up_next_reader(c);
+    _xcb_in_wake_up_next_reader(c);
     pthread_mutex_unlock(&c->iolock);
     return ret;
 }
@@ -547,7 +535,7 @@ xcb_generic_event_t *xcb_wait_for_event(
         if(!_xcb_conn_wait(c, &c->in.event_cond, 0, 0))
             break;
 
-    wake_up_next_reader(c);
+    _xcb_in_wake_up_next_reader(c);
     pthread_mutex_unlock(&c->iolock);
     return ret;
 }
@@ -629,6 +617,16 @@ void _xcb_in_destroy(_xcb_in *in)
         in->pending_replies = pend->next;
         free(pend);
     }
+}
+
+void _xcb_in_wake_up_next_reader(xcb_connection_t *c)
+{
+    int pthreadret;
+    if(c->in.readers)
+        pthreadret = pthread_cond_signal(c->in.readers->data);
+    else
+        pthreadret = pthread_cond_signal(&c->in.event_cond);
+    assert(pthreadret == 0);
 }
 
 int _xcb_in_expect_reply(xcb_connection_t *c, uint64_t request, enum workarounds workaround, int flags)
Index: libxcb/src/xcb_out.c
===================================================================
RCS file: /cvs/xenocara/dist/libxcb/src/xcb_out.c,v
retrieving revision 1.2
diff -u -p -r1.2 xcb_out.c
--- libxcb/src/xcb_out.c 5 Sep 2009 15:54:43 -0000 1.2
+++ libxcb/src/xcb_out.c 22 Jul 2010 09:57:35 -0000
@@ -52,7 +52,7 @@ static int write_block(xcb_connection_t
     vector[0].iov_base = c->out.queue;
     vector[0].iov_len = c->out.queue_len;
     c->out.queue_len = 0;
-    return _xcb_out_send(c, &vector, &count);
+    return _xcb_out_send(c, vector, count);
 }
 
 static void get_socket_back(xcb_connection_t *c)
@@ -283,7 +283,7 @@ int xcb_writev(xcb_connection_t *c, stru
         return 0;
     pthread_mutex_lock(&c->iolock);
     c->out.request += requests;
-    ret = _xcb_out_send(c, &vector, &count);
+    ret = _xcb_out_send(c, vector, count);
     pthread_mutex_unlock(&c->iolock);
     return ret;
 }
@@ -331,13 +331,14 @@ void _xcb_out_destroy(_xcb_out *out)
     pthread_mutex_destroy(&out->reqlenlock);
 }
 
-int _xcb_out_send(xcb_connection_t *c, struct iovec **vector, int *count)
+int _xcb_out_send(xcb_connection_t *c, struct iovec *vector, int count)
 {
     int ret = 1;
-    while(ret && *count)
-        ret = _xcb_conn_wait(c, &c->out.cond, vector, count);
+    while(ret && count)
+        ret = _xcb_conn_wait(c, &c->out.cond, &vector, &count);
     c->out.request_written = c->out.request;
     pthread_cond_broadcast(&c->out.cond);
+    _xcb_in_wake_up_next_reader(c);
     return ret;
 }
 
@@ -348,12 +349,11 @@ int _xcb_out_flush_to(xcb_connection_t *
         return 1;
     if(c->out.queue_len)
     {
-        struct iovec vec, *vec_ptr = &vec;
-        int count = 1;
+        struct iovec vec;
         vec.iov_base = c->out.queue;
         vec.iov_len = c->out.queue_len;
         c->out.queue_len = 0;
-        return _xcb_out_send(c, &vec_ptr, &count);
+        return _xcb_out_send(c, &vec, 1);
     }
     while(c->out.writing)
         pthread_cond_wait(&c->out.cond, &c->iolock);
Index: libxcb/src/xcb_util.c
===================================================================
RCS file: /cvs/xenocara/dist/libxcb/src/xcb_util.c,v
retrieving revision 1.3
diff -u -p -r1.3 xcb_util.c
--- libxcb/src/xcb_util.c 18 Apr 2010 20:06:18 -0000 1.3
+++ libxcb/src/xcb_util.c 22 Jul 2010 09:57:36 -0000
@@ -28,6 +28,7 @@
 #include <assert.h>
 #include <sys/types.h>
 #include <sys/socket.h>
+#include <limits.h>
 #include <sys/un.h>
 #include <netinet/in.h>
 #include <netinet/tcp.h>
@@ -63,11 +64,19 @@ static int _xcb_parse_display(const char
 {
     int len, display, screen;
     char *slash, *colon, *dot, *end;
+
     if(!name || !*name)
         name = getenv("DISPLAY");
     if(!name)
         return 0;
+
+#ifdef HAVE_LAUNCHD
+    if(strncmp(name, "/tmp/launch", 11) == 0)
+        slash = NULL;
+    else
+#endif
     slash = strrchr(name, '/');
+
     if (slash) {
         len = slash - name;
         if (protocol) {
@@ -84,35 +93,43 @@ static int _xcb_parse_display(const char
 
     colon = strrchr(name, ':');
     if(!colon)
-        return 0;
+        goto error_out;
     len = colon - name;
     ++colon;
     display = strtoul(colon, &dot, 10);
     if(dot == colon)
-        return 0;
+        goto error_out;
     if(*dot == '\0')
         screen = 0;
     else
     {
         if(*dot != '.')
-            return 0;
+            goto error_out;
         ++dot;
         screen = strtoul(dot, &end, 10);
         if(end == dot || *end != '\0')
-            return 0;
+            goto error_out;
     }
     /* At this point, the display string is fully parsed and valid, but
      * the caller's memory is untouched. */
 
     *host = malloc(len + 1);
     if(!*host)
-        return 0;
+        goto error_out;
     memcpy(*host, name, len);
     (*host)[len] = '\0';
     *displayp = display;
     if(screenp)
         *screenp = screen;
     return 1;
+
+error_out:
+    if (protocol) {
+        free(*protocol);
+        *protocol = NULL;
+    }
+
+    return 0;
 }
 
 int xcb_parse_display(const char *name, char **host, int *displayp,
@@ -121,7 +138,7 @@ int xcb_parse_display(const char *name,
     return _xcb_parse_display(name, host, NULL, displayp, screenp);
 }
 
-static int _xcb_open_tcp(char *host, char *protocol, const unsigned short port);
+static int _xcb_open_tcp(const char *host, char *protocol, const unsigned short port);
 static int _xcb_open_unix(char *protocol, const char *file);
 #ifdef DNETCONN
 static int _xcb_open_decnet(const char *host, char *protocol, const unsigned short port);
@@ -130,16 +147,24 @@ static int _xcb_open_decnet(const char *
 static int _xcb_open_abstract(char *protocol, const char *file, size_t filelen);
 #endif
 
-static int _xcb_open(char *host, char *protocol, const int display)
+static int _xcb_open(const char *host, char *protocol, const int display)
 {
-#ifdef HAVE_ABSTRACT_SOCKETS
     int fd;
+    static const char unix_base[] = "/tmp/.X11-unix/X";
+    const char *base = unix_base;
+    size_t filelen;
+    char *file = NULL;
+    int actual_filelen;
+
+#ifdef HAVE_LAUNCHD
+        if(strncmp(host, "/tmp/launch", 11) == 0) {
+ base = host;
+ host = "";
+ protocol = NULL;
+        }
 #endif
-    static const char base[] = "/tmp/.X11-unix/X";
-    char file[sizeof(base) + 20];
-    int filelen;
 
-    if(*host)
+    if(*host || protocol)
     {
 #ifdef DNETCONN
         /* DECnet displays have two colons, so _xcb_parse_display will have
@@ -163,19 +188,38 @@ static int _xcb_open(char *host, char *p
             }
     }
 
+    filelen = strlen(base) + 1 + sizeof(display) * 3 + 1;
+    file = malloc(filelen);
+    if(file == NULL)
+        return -1;
+
     /* display specifies Unix socket */
-    filelen = snprintf(file, sizeof(file), "%s%d", base, display);
-    if(filelen < 0)
+#ifdef HAVE_LAUNCHD
+    if(strncmp(base, "/tmp/launch", 11) == 0)
+        actual_filelen = snprintf(file, filelen, "%s:%d", base, display);
+    else
+#endif
+        actual_filelen = snprintf(file, filelen, "%s%d", base, display);
+    if(actual_filelen < 0)
+    {
+        free(file);
         return -1;
+    }
     /* snprintf may truncate the file */
-    filelen = MIN(filelen, sizeof(file) - 1);
+    filelen = MIN(actual_filelen, filelen - 1);
 #ifdef HAVE_ABSTRACT_SOCKETS
     fd = _xcb_open_abstract(protocol, file, filelen);
     if (fd >= 0 || (errno != ENOENT && errno != ECONNREFUSED))
+    {
+        free(file);
         return fd;
+    }
 
 #endif
-    return  _xcb_open_unix(protocol, file);
+    fd = _xcb_open_unix(protocol, file);
+    free(file);
+
+    return fd;
 }
 
 static int _xcb_socket(int family, int type, int proto)
@@ -234,7 +278,7 @@ static int _xcb_open_decnet(const char *
 }
 #endif
 
-static int _xcb_open_tcp(char *host, char *protocol, const unsigned short port)
+static int _xcb_open_tcp(const char *host, char *protocol, const unsigned short port)
 {
     int fd = -1;
     struct addrinfo hints;
@@ -242,8 +286,15 @@ static int _xcb_open_tcp(char *host, cha
     struct addrinfo *results, *addr;
     char *bracket;
 
-    if (protocol && strcmp("tcp",protocol))
+    if (protocol && strcmp("tcp",protocol) && strcmp("inet",protocol)
+#ifdef AF_INET6
+         && strcmp("inet6",protocol)
+#endif
+ )
         return -1;
+
+    if (*host == '\0')
+ host = "localhost";
 
     memset(&hints, 0, sizeof(hints));
 #ifdef AI_ADDRCONFIG
@@ -347,31 +398,28 @@ xcb_connection_t *xcb_connect(const char
 xcb_connection_t *xcb_connect_to_display_with_auth_info(const char *displayname, xcb_auth_info_t *auth, int *screenp)
 {
     int fd, display = 0;
-    char *host;
-    char *protocol;
+    char *host = NULL;
+    char *protocol = NULL;
     xcb_auth_info_t ourauth;
     xcb_connection_t *c;
 
     int parsed = _xcb_parse_display(displayname, &host, &protocol, &display, screenp);
     
-#ifdef HAVE_LAUNCHD
-    if(!displayname)
-        displayname = getenv("DISPLAY");
-    if(displayname && strlen(displayname)>11 && !strncmp(displayname, "/tmp/launch", 11))
-        fd = _xcb_open_unix(NULL, displayname);
-    else
-#endif
-    if(!parsed)
-        return (xcb_connection_t *) &error_connection;
-    else
+    if(!parsed) {
+        c = (xcb_connection_t *) &error_connection;
+        goto out;
+    } else
         fd = _xcb_open(host, protocol, display);
-    free(host);
 
-    if(fd == -1)
-        return (xcb_connection_t *) &error_connection;
+    if(fd == -1) {
+        c = (xcb_connection_t *) &error_connection;
+        goto out;
+    }
 
-    if(auth)
-        return xcb_connect_to_fd(fd, auth);
+    if(auth) {
+        c = xcb_connect_to_fd(fd, auth);
+        goto out;
+    }
 
     if(_xcb_get_auth_info(fd, &ourauth, display))
     {
@@ -382,5 +430,8 @@ xcb_connection_t *xcb_connect_to_display
     else
         c = xcb_connect_to_fd(fd, 0);
 
+out:
+    free(host);
+    free(protocol);
     return c;
 }
Index: libxcb/src/xcbint.h
===================================================================
RCS file: /cvs/xenocara/dist/libxcb/src/xcbint.h,v
retrieving revision 1.2
diff -u -p -r1.2 xcbint.h
--- libxcb/src/xcbint.h 31 May 2009 16:44:44 -0000 1.2
+++ libxcb/src/xcbint.h 22 Jul 2010 09:57:36 -0000
@@ -106,7 +106,7 @@ typedef struct _xcb_out {
 int _xcb_out_init(_xcb_out *out);
 void _xcb_out_destroy(_xcb_out *out);
 
-int _xcb_out_send(xcb_connection_t *c, struct iovec **vector, int *count);
+int _xcb_out_send(xcb_connection_t *c, struct iovec *vector, int count);
 int _xcb_out_flush_to(xcb_connection_t *c, uint64_t request);
 
 
@@ -136,6 +136,8 @@ typedef struct _xcb_in {
 
 int _xcb_in_init(_xcb_in *in);
 void _xcb_in_destroy(_xcb_in *in);
+
+void _xcb_in_wake_up_next_reader(xcb_connection_t *c);
 
 int _xcb_in_expect_reply(xcb_connection_t *c, uint64_t request, enum workarounds workaround, int flags);
 void _xcb_in_replies_done(xcb_connection_t *c);
Index: xcb-util/event/xcb_event.h
===================================================================
RCS file: /cvs/xenocara/dist/xcb-util/event/xcb_event.h,v
retrieving revision 1.2
diff -u -p -r1.2 xcb_event.h
--- xcb-util/event/xcb_event.h 5 Sep 2009 15:55:46 -0000 1.2
+++ xcb-util/event/xcb_event.h 22 Jul 2010 09:57:36 -0000
@@ -168,53 +168,8 @@ XCB_EVENT_MAKE_EVENT_HANDLER(colormap_no
 XCB_EVENT_MAKE_EVENT_HANDLER(client_message, CLIENT_MESSAGE)
 XCB_EVENT_MAKE_EVENT_HANDLER(mapping_notify, MAPPING_NOTIFY)
 
-/** Everyting is ok */
-#define XCB_EVENT_ERROR_SUCESS 0
-/** Bad request code */
-#define XCB_EVENT_ERROR_BAD_REQUEST 1
-/** Int parameter out of range */
-#define XCB_EVENT_ERROR_BAD_VALUE 2
-/** Parameter not a Window */
-#define XCB_EVENT_ERROR_BAD_WINDOW 3
-/** Parameter not a Pixmap */
-#define XCB_EVENT_ERROR_BAD_PIXMAP 4
-/** Parameter not an Atom */
-#define XCB_EVENT_ERROR_BAD_ATOM 5
-/** Parameter not a Cursor */
-#define XCB_EVENT_ERROR_BAD_CURSOR 6
-/** Parameter not a Font */
-#define XCB_EVENT_ERROR_BAD_FONT 7
-/** Parameter mismatch */
-#define XCB_EVENT_ERROR_BAD_MATCH 8
-/** Parameter not a Pixmap or Window */
-#define XCB_EVENT_ERROR_BAD_DRAWABLE 9
-/* Depending on context:
-   - key/button already grabbed
-   - attempt to free an illegal
-     cmap entry
-   - attempt to store into a read-only
-     color map entry.
-   - attempt to modify the access control
-     list from other than the local host.
-*/
-#define XCB_EVENT_ERROR_BAD_ACCESS 10
-/** Insufficient resources */
-#define XCB_EVENT_ERROR_BAD_ALLOC 11
-/** No such colormap */
-#define XCB_EVENT_ERROR_BAD_COLOR 12
-/** Parameter not a GC */
-#define XCB_EVENT_ERROR_BAD_GC 13
-/** Choice not in range or already used */
-#define XCB_EVENT_ERROR_BAD_ID_CHOICE 14
-/** Font or color name doesn't exist */
-#define XCB_EVENT_ERROR_BAD_NAME 15
-/** Request length incorrect */
-#define XCB_EVENT_ERROR_BAD_LENGTH 16
-/** Server is defective */
-#define XCB_EVENT_ERROR_BAD_IMPLEMENTATION 17
-
 /**
- * @brief Convert an event reponse type to a label.
+ * @brief Convert an event response type to a label.
  * @param type The event type.
  * @return A string with the event name, or NULL if unknown.
  */
@@ -222,7 +177,7 @@ const char * xcb_event_get_label(uint8_t
 
 /**
  * @brief Convert an event error type to a label.
- * @param type The erro type.
+ * @param type The error type.
  * @return A string with the event name, or NULL if unknown or if the event is
  * not an error.
  */
Index: xcb-util/icccm/icccm.c
===================================================================
RCS file: /cvs/xenocara/dist/xcb-util/icccm/icccm.c,v
retrieving revision 1.7
diff -u -p -r1.7 icccm.c
--- xcb-util/icccm/icccm.c 20 Mar 2010 07:41:31 -0000 1.7
+++ xcb-util/icccm/icccm.c 22 Jul 2010 09:57:37 -0000
@@ -58,8 +58,10 @@ xcb_get_text_property_reply(xcb_connecti
 {
   xcb_get_property_reply_t *reply = xcb_get_property_reply(c, cookie, e);
 
-  if(!reply || reply->type == XCB_NONE)
+  if(!reply || reply->type == XCB_NONE) {
+    free(reply);
     return 0;
+  }
 
   prop->_reply = reply;
   prop->encoding = prop->_reply->type;
Index: xcb-util/icccm/xcb_icccm.h
===================================================================
RCS file: /cvs/xenocara/dist/xcb-util/icccm/xcb_icccm.h,v
retrieving revision 1.3
diff -u -p -r1.3 xcb_icccm.h
--- xcb-util/icccm/xcb_icccm.h 7 Mar 2010 15:51:34 -0000 1.3
+++ xcb-util/icccm/xcb_icccm.h 22 Jul 2010 09:57:37 -0000
@@ -330,7 +330,7 @@ xcb_get_property_cookie_t xcb_get_wm_cla
 
 /**
  * @brief Fill give structure with the WM_CLASS property of a window.
- * @param prop The property structur to fill.
+ * @param prop The property structure to fill.
  * @param reply The property request reply.
  * @return Return 1 on success, 0 otherwise.
  */
Index: xcb-util/image/xcb_image.h
===================================================================
RCS file: /cvs/xenocara/dist/xcb-util/image/xcb_image.h,v
retrieving revision 1.1.1.1
diff -u -p -r1.1.1.1 xcb_image.h
--- xcb-util/image/xcb_image.h 23 May 2009 14:38:17 -0000 1.1.1.1
+++ xcb-util/image/xcb_image.h 22 Jul 2010 09:57:37 -0000
@@ -513,7 +513,7 @@ xcb_image_subimage(xcb_image_t *  image,
  * bits. For XYPixmap and ZPixmap, the depth must match the depth of
  * the drawable, or a ``BadMatch'' error results.
  *
- * If a problem occurs, the functons returns @c 0. Otherwise, it
+ * If a problem occurs, the function returns @c 0. Otherwise, it
  * returns @c 1.
  * @ingroup xcb__image_t
  */
@@ -551,7 +551,7 @@ xcb_image_shm_put (xcb_connection_t *  
  * within the drawable, and @p plane_mask defines which planes are to be
  * read.
  *
- * If a problem occurs, the functons returns @c 0. It returns 1
+ * If a problem occurs, the function returns @c 0. It returns 1
  * otherwise.
  * @ingroup xcb__image_t
  */
Index: xcb-util/property/xcb_property.h
===================================================================
RCS file: /cvs/xenocara/dist/xcb-util/property/xcb_property.h,v
retrieving revision 1.2
diff -u -p -r1.2 xcb_property.h
--- xcb-util/property/xcb_property.h 5 Sep 2009 15:55:46 -0000 1.2
+++ xcb-util/property/xcb_property.h 22 Jul 2010 09:57:37 -0000
@@ -29,7 +29,7 @@
 /**
  * @defgroup xcb__property_t XCB Property Functions
  *
- * These functions ease the handling of X propertiess received.
+ * These functions ease the handling of X properties received.
  *
  * @{
  */

[demime 1.01d removed an attachment of type text/x-diff]

Reply | Threaded
Open this post in threaded view
|

Re: libxcb & xcb-util fixes

David Coppa
On Thu, 22 Jul 2010, David Coppa wrote:

> Hi,
>
> Since upstream is still far from a new stable release,
> I think it would be good to have some fixes from their git
> imported in our xenocara tree for 4.8.
>
> Obviously, I've only included fixes and improvements and
> not those patches adding new features.
>
> Tested with two xcb-based WMs from ports, x11/i3 and
> x11/awesome.

Barely essential diff this time... Please have a look.

* Fixes for some nasty memory leaks
* Fix for java apps misbehaving when run on xcb-based WMs

Ciao,
David

Index: libxcb/src/xcb_util.c
===================================================================
RCS file: /cvs/xenocara/dist/libxcb/src/xcb_util.c,v
retrieving revision 1.3
diff -u -p -r1.3 xcb_util.c
--- libxcb/src/xcb_util.c 18 Apr 2010 20:06:18 -0000 1.3
+++ libxcb/src/xcb_util.c 3 Aug 2010 12:14:33 -0000
@@ -84,35 +84,43 @@ static int _xcb_parse_display(const char
 
     colon = strrchr(name, ':');
     if(!colon)
-        return 0;
+        goto error_out;
     len = colon - name;
     ++colon;
     display = strtoul(colon, &dot, 10);
     if(dot == colon)
-        return 0;
+        goto error_out;
     if(*dot == '\0')
         screen = 0;
     else
     {
         if(*dot != '.')
-            return 0;
+            goto error_out;
         ++dot;
         screen = strtoul(dot, &end, 10);
         if(end == dot || *end != '\0')
-            return 0;
+            goto error_out;
     }
     /* At this point, the display string is fully parsed and valid, but
      * the caller's memory is untouched. */
 
     *host = malloc(len + 1);
     if(!*host)
-        return 0;
+        goto error_out;
     memcpy(*host, name, len);
     (*host)[len] = '\0';
     *displayp = display;
     if(screenp)
         *screenp = screen;
     return 1;
+
+error_out:
+    if (protocol) {
+        free(*protocol);
+        *protocol = NULL;
+    }
+
+    return 0;
 }
 
 int xcb_parse_display(const char *name, char **host, int *displayp,
@@ -347,8 +355,8 @@ xcb_connection_t *xcb_connect(const char
 xcb_connection_t *xcb_connect_to_display_with_auth_info(const char *displayname, xcb_auth_info_t *auth, int *screenp)
 {
     int fd, display = 0;
-    char *host;
-    char *protocol;
+    char *host = NULL;
+    char *protocol = NULL;
     xcb_auth_info_t ourauth;
     xcb_connection_t *c;
 
@@ -361,17 +369,21 @@ xcb_connection_t *xcb_connect_to_display
         fd = _xcb_open_unix(NULL, displayname);
     else
 #endif
-    if(!parsed)
-        return (xcb_connection_t *) &error_connection;
-    else
+    if(!parsed) {
+        c = (xcb_connection_t *) &error_connection;
+        goto out;
+    } else
         fd = _xcb_open(host, protocol, display);
-    free(host);
 
-    if(fd == -1)
-        return (xcb_connection_t *) &error_connection;
+    if(fd == -1) {
+        c = (xcb_connection_t *) &error_connection;
+        goto out;
+    }
 
-    if(auth)
-        return xcb_connect_to_fd(fd, auth);
+    if(auth) {
+        c = xcb_connect_to_fd(fd, auth);
+        goto out;
+    }
 
     if(_xcb_get_auth_info(fd, &ourauth, display))
     {
@@ -382,5 +394,8 @@ xcb_connection_t *xcb_connect_to_display
     else
         c = xcb_connect_to_fd(fd, 0);
 
+out:
+    free(host);
+    free(protocol);
     return c;
 }
Index: xcb-util/icccm/icccm.c
===================================================================
RCS file: /cvs/xenocara/dist/xcb-util/icccm/icccm.c,v
retrieving revision 1.7
diff -u -p -r1.7 icccm.c
--- xcb-util/icccm/icccm.c 20 Mar 2010 07:41:31 -0000 1.7
+++ xcb-util/icccm/icccm.c 3 Aug 2010 12:14:34 -0000
@@ -58,8 +58,10 @@ xcb_get_text_property_reply(xcb_connecti
 {
   xcb_get_property_reply_t *reply = xcb_get_property_reply(c, cookie, e);
 
-  if(!reply || reply->type == XCB_NONE)
+  if(!reply || reply->type == XCB_NONE) {
+    free(reply);
     return 0;
+  }
 
   prop->_reply = reply;
   prop->encoding = prop->_reply->type;
@@ -242,7 +244,7 @@ uint8_t
 xcb_get_wm_class_from_reply(xcb_get_wm_class_reply_t *prop,
                             xcb_get_property_reply_t *reply)
 {
-  int name_len;
+  int name_len, len;
 
   if(!reply || reply->type != STRING || reply->format != 8)
     return 0;
@@ -250,8 +252,17 @@ xcb_get_wm_class_from_reply(xcb_get_wm_c
   prop->_reply = reply;
   prop->instance_name = (char *) xcb_get_property_value(prop->_reply);
 
+  len = xcb_get_property_value_length(prop->_reply);
+  /* Ensure there's a C end-of-string at the end of the property.
+     Truncate the property if necessary (the spec says there's already
+     a 0 in the last position, so this only hurts invalid props). */
+  if(len < reply->length * 4)
+    prop->instance_name[len] = 0;
+  else
+    prop->instance_name[len-1] = 0;
+
   name_len = strlen(prop->instance_name);
-  if(name_len == xcb_get_property_value_length(prop->_reply))
+  if(name_len == len)
     name_len--;
 
   prop->class_name = prop->instance_name + name_len + 1;