Re: libxcb & xcb-util fixes

David Coppa <[email protected]> Tue, 3 Aug 2010 15:15:11 +0200
Newsgroups gmane.os.openbsd.x11
Message-ID <20100803131511.GB18598@cl0311500093650>
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;