[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

libxres: Changes to 'upstream-unstable'



 autogen.sh                    |   13 +-
 configure.ac                  |   15 +-
 include/X11/extensions/XRes.h |   79 +++++++++++++
 src/XRes.c                    |  238 +++++++++++++++++++++++++++++++++++++++---
 4 files changed, 322 insertions(+), 23 deletions(-)

New commits:
commit 47f8ced17f5ef0a1f1539fd8837cd8f47aa0eb6e
Author: Alan Coopersmith <alan.coopersmith@oracle.com>
Date:   Sat Apr 13 10:34:22 2013 -0700

    Use _XEatDataWords to avoid overflow of rep.length shifting
    
    rep.length is a CARD32, so rep.length << 2 could overflow in 32-bit builds
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>

diff --git a/configure.ac b/configure.ac
index 5e3703b..b829cc1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -50,6 +50,12 @@ XORG_CHECK_MALLOC_ZERO
 # Obtain compiler/linker options for depedencies
 PKG_CHECK_MODULES(XRES, [x11 >= 1.6] xext xextproto [resourceproto >= 1.2.0])
 
+# Check for _XEatDataWords function that may be patched into older Xlib release
+SAVE_LIBS="$LIBS"
+LIBS="$XRES_LIBS"
+AC_CHECK_FUNCS([_XEatDataWords])
+LIBS="$SAVE_LIBS"
+
 AC_CONFIG_FILES([Makefile
 		src/Makefile
 		man/Makefile

commit 84b9156c7833dfd91c65d33542420ff4fe226948
Author: Adam Jackson <ajax@redhat.com>
Date:   Wed Oct 11 11:11:01 2017 -0400

    libXRes 1.2.0
    
    Signed-off-by: Adam Jackson <ajax@redhat.com>

diff --git a/configure.ac b/configure.ac
index b082de8..5e3703b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -29,7 +29,7 @@ AC_PREREQ([2.60])
 # digit in the version number to track changes which don't affect the
 # protocol, so XRes version l.n.m corresponds to protocol version l.n
 #
-AC_INIT([libXres], [1.1.99.0],
+AC_INIT([libXres], [1.2.0],
         [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], [libXres])
 AC_CONFIG_SRCDIR([Makefile.am])
 AC_CONFIG_HEADERS([config.h])

commit 1bc34457619c0d9b94ebd1cadac53366da20fbe3
Author: Mihail Konev <k.mvc@ya.ru>
Date:   Thu Jan 26 13:52:49 2017 +1000

    autogen: add default patch prefix
    
    Signed-off-by: Mihail Konev <k.mvc@ya.ru>

diff --git a/autogen.sh b/autogen.sh
index 0006de8..86e51a2 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -9,6 +9,9 @@ cd "$srcdir"
 autoreconf -v --install || exit 1
 cd "$ORIGDIR" || exit $?
 
+git config --local --get format.subjectPrefix >/dev/null 2>&1 ||
+    git config --local format.subjectPrefix "PATCH libXRes"
+
 if test -z "$NOCONFIGURE"; then
     exec "$srcdir"/configure "$@"
 fi

commit e5fbb99729d460eda477bf6e299728bc47542ccb
Author: Emil Velikov <emil.l.velikov@gmail.com>
Date:   Mon Mar 9 12:00:52 2015 +0000

    autogen.sh: use quoted string variables
    
    Place quotes around the $srcdir, $ORIGDIR and $0 variables to prevent
    fall-outs, when they contain space.
    
    Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
    Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>

diff --git a/autogen.sh b/autogen.sh
index fd9c59a..0006de8 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -1,14 +1,14 @@
 #! /bin/sh
 
-srcdir=`dirname $0`
+srcdir=`dirname "$0"`
 test -z "$srcdir" && srcdir=.
 
 ORIGDIR=`pwd`
-cd $srcdir
+cd "$srcdir"
 
 autoreconf -v --install || exit 1
-cd $ORIGDIR || exit $?
+cd "$ORIGDIR" || exit $?
 
 if test -z "$NOCONFIGURE"; then
-    exec $srcdir/configure "$@"
+    exec "$srcdir"/configure "$@"
 fi

commit 16b2d184302d259a8481693285976045386fcc01
Author: Peter Hutterer <peter.hutterer@who-t.net>
Date:   Tue Jan 24 10:32:07 2017 +1000

    autogen.sh: use exec instead of waiting for configure to finish
    
    Syncs the invocation of configure with the one from the server.
    
    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
    Reviewed-by: Emil Velikov <emil.velikov@collabora.com>

diff --git a/autogen.sh b/autogen.sh
index fc34bd5..fd9c59a 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -10,5 +10,5 @@ autoreconf -v --install || exit 1
 cd $ORIGDIR || exit $?
 
 if test -z "$NOCONFIGURE"; then
-    $srcdir/configure "$@"
+    exec $srcdir/configure "$@"
 fi

commit ae0ddaa9c960aee1b7845da01270b00177f95f3d
Author: Alan Coopersmith <alan.coopersmith@oracle.com>
Date:   Fri Nov 22 23:22:36 2013 -0800

    Remove fallback for _XEatDataWords, require libX11 1.6 for it
    
    _XEatDataWords was orignally introduced with the May 2013 security
    patches, and in order to ease the process of delivering those,
    fallback versions of _XEatDataWords were included in the X extension
    library patches so they could be applied to older versions that didn't
    have libX11 1.6 yet.   Now that we're past that hurdle, we can drop
    the fallbacks and just require libX11 1.6 for building new versions
    of the extension libraries.
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>

diff --git a/configure.ac b/configure.ac
index f68b689..b082de8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -48,13 +48,7 @@ XORG_DEFAULT_OPTIONS
 XORG_CHECK_MALLOC_ZERO
 
 # Obtain compiler/linker options for depedencies
-PKG_CHECK_MODULES(XRES, x11 xext xextproto [resourceproto >= 1.2.0])
-
-# Check for _XEatDataWords function that may be patched into older Xlib release
-SAVE_LIBS="$LIBS"
-LIBS="$XRES_LIBS"
-AC_CHECK_FUNCS([_XEatDataWords])
-LIBS="$SAVE_LIBS"
+PKG_CHECK_MODULES(XRES, [x11 >= 1.6] xext xextproto [resourceproto >= 1.2.0])
 
 AC_CONFIG_FILES([Makefile
 		src/Makefile
diff --git a/src/XRes.c b/src/XRes.c
index 89fab82..2bee277 100644
--- a/src/XRes.c
+++ b/src/XRes.c
@@ -15,17 +15,6 @@
 #include <assert.h>
 #include <limits.h>
 
-#ifndef HAVE__XEATDATAWORDS
-static inline void _XEatDataWords(Display *dpy, unsigned long n)
-{
-# ifndef LONG64
-    if (n >= (ULONG_MAX >> 2))
-        _XIOError(dpy);
-# endif
-    _XEatData (dpy, n << 2);
-}
-#endif
-
 static XExtensionInfo _xres_ext_info_data;
 static XExtensionInfo *xres_ext_info = &_xres_ext_info_data;
 static const char *xres_extension_name = XRES_NAME;

commit 0f5cfdc3136dd8ef43800bda64f9d39e6b23b2e9
Author: Julien Cristau <jcristau@debian.org>
Date:   Sun Jun 30 20:09:49 2013 +0200

    Compute number of bytes correctly in XResQueryClientPixmapBytes
    
    64-bit servers send the upper 32-bit in bytes_overflow.  We were
    multiplying by 2^32 - 1 instead of 2^32 when putting things back
    together.
    
    Debian bug#621702
    
    Reported-by: Kevin Ryde <user42@zip.com.au>
    Signed-off-by: Julien Cristau <jcristau@debian.org>
    Reviewed-by: Alan Coopersmith <alan.coopersmith@oracle.com>

diff --git a/src/XRes.c b/src/XRes.c
index 51e905f..89fab82 100644
--- a/src/XRes.c
+++ b/src/XRes.c
@@ -240,7 +240,7 @@ Status XResQueryClientPixmapBytes (
     }
 
 #ifdef LONG64
-    *bytes = (rep.bytes_overflow * 4294967295) + rep.bytes;
+    *bytes = (rep.bytes_overflow * 4294967296UL) + rep.bytes;
 #else
     *bytes = rep.bytes_overflow ? 0xffffffff : rep.bytes;
 #endif

commit f468184963e53feda848853c4aefd0197b2cc116
Author: Alan Coopersmith <alan.coopersmith@oracle.com>
Date:   Fri Apr 12 23:36:13 2013 -0700

    integer overflow in XResQueryClientResources() [CVE-2013-1988 2/2]
    
    The CARD32 rep.num_types needs to be bounds checked before multiplying
    by sizeof(XResType) to avoid integer overflow leading to underallocation
    and writing data from the network past the end of the allocated buffer.
    
    Reported-by: Ilja Van Sprundel <ivansprundel@ioactive.com>
    Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>

diff --git a/src/XRes.c b/src/XRes.c
index c989985..51e905f 100644
--- a/src/XRes.c
+++ b/src/XRes.c
@@ -187,7 +187,12 @@ Status XResQueryClientResources (
     }
 
     if(rep.num_types) {
-        if((typs = Xmalloc(sizeof(XResType) * rep.num_types))) {
+        if (rep.num_types < (INT_MAX / sizeof(XResType)))
+            typs = Xmalloc(sizeof(XResType) * rep.num_types);
+        else
+            typs = NULL;
+
+        if (typs != NULL) {
             xXResType scratch;
             int i;
 

commit b053d215b80e721f9afdc5794e4f3f4f2aee0141
Author: Alan Coopersmith <alan.coopersmith@oracle.com>
Date:   Fri Apr 12 23:36:13 2013 -0700

    integer overflow in XResQueryClients() [CVE-2013-1988 1/2]
    
    The CARD32 rep.num_clients needs to be bounds checked before multiplying
    by sizeof(XResClient) to avoid integer overflow leading to underallocation
    and writing data from the network past the end of the allocated buffer.
    
    Reported-by: Ilja Van Sprundel <ivansprundel@ioactive.com>
    Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>

diff --git a/src/XRes.c b/src/XRes.c
index 1ab1db8..c989985 100644
--- a/src/XRes.c
+++ b/src/XRes.c
@@ -130,7 +130,12 @@ Status XResQueryClients (
     }
 
     if(rep.num_clients) {
-        if((clnts = Xmalloc(sizeof(XResClient) * rep.num_clients))) {
+        if (rep.num_clients < (INT_MAX / sizeof(XResClient)))
+            clnts = Xmalloc(sizeof(XResClient) * rep.num_clients);
+        else
+            clnts = NULL;
+
+        if (clnts != NULL) {
             xXResClient scratch;
             int i;
 

commit 69457711050ac3a53859ef11790a7ac815cd7d94
Author: Alan Coopersmith <alan.coopersmith@oracle.com>
Date:   Sat Apr 13 10:34:22 2013 -0700

    Use _XEatDataWords to avoid overflow of rep.length shifting
    
    rep.length is a CARD32, so rep.length << 2 could overflow in 32-bit builds
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>

diff --git a/configure.ac b/configure.ac
index 90205cc..f68b689 100644
--- a/configure.ac
+++ b/configure.ac
@@ -50,6 +50,12 @@ XORG_CHECK_MALLOC_ZERO
 # Obtain compiler/linker options for depedencies
 PKG_CHECK_MODULES(XRES, x11 xext xextproto [resourceproto >= 1.2.0])
 
+# Check for _XEatDataWords function that may be patched into older Xlib release
+SAVE_LIBS="$LIBS"
+LIBS="$XRES_LIBS"
+AC_CHECK_FUNCS([_XEatDataWords])
+LIBS="$SAVE_LIBS"
+
 AC_CONFIG_FILES([Makefile
 		src/Makefile
 		man/Makefile
diff --git a/src/XRes.c b/src/XRes.c
index 1744196..1ab1db8 100644
--- a/src/XRes.c
+++ b/src/XRes.c
@@ -13,6 +13,18 @@
 #include <X11/extensions/XResproto.h>
 #include <X11/extensions/XRes.h>
 #include <assert.h>
+#include <limits.h>
+
+#ifndef HAVE__XEATDATAWORDS
+static inline void _XEatDataWords(Display *dpy, unsigned long n)
+{
+# ifndef LONG64
+    if (n >= (ULONG_MAX >> 2))
+        _XIOError(dpy);
+# endif
+    _XEatData (dpy, n << 2);
+}
+#endif
 
 static XExtensionInfo _xres_ext_info_data;
 static XExtensionInfo *xres_ext_info = &_xres_ext_info_data;
@@ -131,7 +143,7 @@ Status XResQueryClients (
             *num_clients = rep.num_clients;
             result = 1;
         } else {
-            _XEatData(dpy, rep.length << 2);
+            _XEatDataWords(dpy, rep.length);
         }
     }
 
@@ -183,7 +195,7 @@ Status XResQueryClientResources (
             *num_types = rep.num_types;
             result = 1;
         } else {
-            _XEatData(dpy, rep.length << 2);
+            _XEatDataWords(dpy, rep.length);
         }
     }
 

commit 83e7693515369d57dcd11c2bb1f03563f51bc500
Author: Alan Coopersmith <alan.coopersmith@oracle.com>
Date:   Fri Jan 18 23:06:20 2013 -0800

    Replace deprecated Automake INCLUDES variable with AM_CPPFLAGS
    
    Excerpt https://lists.gnu.org/archive/html/automake/2012-12/msg00038.html
    
      - Support for the long-deprecated INCLUDES variable will be removed
        altogether in Automake 1.14.  The AM_CPPFLAGS variable should be
        used instead.
    
    This variable was deprecated in Automake releases prior to 1.10, which is
    the current minimum level required to build X.
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>

diff --git a/src/Makefile.am b/src/Makefile.am
index fd508da..bf66d68 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -10,7 +10,7 @@ AM_CFLAGS = \
 	$(XRES_CFLAGS) \
 	$(MALLOC_ZERO_CFLAGS)
 
-INCLUDES = -I$(top_srcdir)/include
+AM_CPPFLAGS = -I$(top_srcdir)/include
 
 libXRes_la_LDFLAGS = -version-number 1:0:0 -no-undefined
 

commit d9324b7d07294bb18e4902596a1b8ee387188364
Author: Colin Walters <walters@verbum.org>
Date:   Wed Jan 4 17:37:06 2012 -0500

    autogen.sh: Implement GNOME Build API
    
    http://people.gnome.org/~walters/docs/build-api.txt
    
    Signed-off-by: Adam Jackson <ajax@redhat.com>

diff --git a/autogen.sh b/autogen.sh
index 904cd67..fc34bd5 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -9,4 +9,6 @@ cd $srcdir
 autoreconf -v --install || exit 1
 cd $ORIGDIR || exit $?
 
-$srcdir/configure --enable-maintainer-mode "$@"
+if test -z "$NOCONFIGURE"; then
+    $srcdir/configure "$@"
+fi

commit 6d1f115422cde2bfca4b69caa395345f3ac454e7
Author: Adam Jackson <ajax@redhat.com>
Date:   Tue Jan 15 14:28:48 2013 -0500

    configure: Remove AM_MAINTAINER_MODE
    
    Signed-off-by: Adam Jackson <ajax@redhat.com>

diff --git a/configure.ac b/configure.ac
index 0079857..90205cc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -36,7 +36,6 @@ AC_CONFIG_HEADERS([config.h])
 
 # Initialize Automake
 AM_INIT_AUTOMAKE([foreign dist-bzip2])
-AM_MAINTAINER_MODE
 
 # Initialize libtool
 AC_PROG_LIBTOOL

commit f44f4e265ec3ab7ef87d6d7009ec079ba4c49336
Author: Alan Coopersmith <alan.coopersmith@oracle.com>
Date:   Mon Apr 23 18:57:48 2012 -0700

    Bump version to 1.1.99.0 to reflect addition of 1.2 API
    
    As noted in configure.ac comment, we try to keep library version
    based on the protocol version number, so since the protocol skipped
    to 1.2, we'll do that with the library as well for simplicity's sake.
    
    Sets resourceproto requirement to version 1.2.0 since there were no
    intermediate/snapshot versions between 1.1.2 & 1.2.0.
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>

diff --git a/configure.ac b/configure.ac
index bc4e8a6..0079857 100644
--- a/configure.ac
+++ b/configure.ac
@@ -29,7 +29,7 @@ AC_PREREQ([2.60])
 # digit in the version number to track changes which don't affect the
 # protocol, so XRes version l.n.m corresponds to protocol version l.n
 #
-AC_INIT([libXres], [1.0.6],
+AC_INIT([libXres], [1.1.99.0],
         [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], [libXres])
 AC_CONFIG_SRCDIR([Makefile.am])
 AC_CONFIG_HEADERS([config.h])
@@ -48,12 +48,8 @@ XORG_MACROS_VERSION(1.8)
 XORG_DEFAULT_OPTIONS
 XORG_CHECK_MALLOC_ZERO
 
-# Check xres configuration, strip extra digits from package version to
-# find the required protocol version
-RES_VERSION=[`echo $VERSION | sed 's/^\([0-9][0-9]*\.[0-9][0-9]*\).*$/\1/'`]
-
 # Obtain compiler/linker options for depedencies
-PKG_CHECK_MODULES(XRES, x11 xext xextproto [resourceproto >= $RES_VERSION])
+PKG_CHECK_MODULES(XRES, x11 xext xextproto [resourceproto >= 1.2.0])
 
 AC_CONFIG_FILES([Makefile
 		src/Makefile

commit 01fc6f81f0a2935741dd1114aa3fa267d8be9095
Author: Erkki Seppälä <erkki.seppala@vincit.fi>
Date:   Wed Dec 15 13:48:09 2010 +0200

    Implemented second part of XResource extension v1.2: XResQueryResourceBytes
    
    Signed-off-by: Erkki Seppälä <erkki.seppala@vincit.fi>
    Reviewed-by: Rami Ylimäki <rami.ylimaki@vincit.fi>
    Reviewed-by: Tiago Vignatti <tiago.vignatti@nokia.com>
    Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>

diff --git a/include/X11/extensions/XRes.h b/include/X11/extensions/XRes.h
index b9759e3..1c81616 100644
--- a/include/X11/extensions/XRes.h
+++ b/include/X11/extensions/XRes.h
@@ -43,6 +43,24 @@ typedef struct {
   void         *value;
 } XResClientIdValue;
 
+typedef struct {
+  XID           resource;
+  Atom          type;
+} XResResourceIdSpec;
+
+typedef struct {
+  XResResourceIdSpec spec;
+  long          bytes;
+  long          ref_count;
+  long          use_count;
+} XResResourceSizeSpec;
+
+typedef struct {
+  XResResourceSizeSpec  size;
+  long                  num_cross_references;
+  XResResourceSizeSpec *cross_references;
+} XResResourceSizeValue;
+
 _XFUNCPROTOBEGIN
 
 /* v1.0 */
@@ -98,6 +116,20 @@ void XResClientIdsDestroy (
    XResClientIdValue  *client_ids
 );
 
+Status XResQueryResourceBytes (
+   Display            *dpy,
+   XID                 client,
+   long                num_specs,
+   XResResourceIdSpec *resource_specs, /* in */
+   long               *num_sizes,      /* out */
+   XResResourceSizeValue **sizes       /* out */
+);
+
+void XResResourceSizeValuesDestroy (
+   long                num_sizes,
+   XResResourceSizeValue *sizes
+);
+
 _XFUNCPROTOEND
 
 #endif /* _XRES_H */
diff --git a/src/XRes.c b/src/XRes.c
index 0781666..1744196 100644
--- a/src/XRes.c
+++ b/src/XRes.c
@@ -237,7 +237,7 @@ static Bool ReadClientValues(
     int c;
     for (c = 0; c < num_ids; ++c) {
         XResClientIdValue* client = client_ids + c;
-        CARD32 value;
+        long int value;
         _XRead32 (dpy, &value, 4);
         client->spec.client = value;
         _XRead32 (dpy, &value, 4);
@@ -344,3 +344,111 @@ pid_t XResGetClientPid(
         return (pid_t) -1;
     }
 }
+
+static Status ReadResourceSizeSpec(
+   Display               *dpy,
+   XResResourceSizeSpec  *size
+)
+{
+    long int value;
+    _XRead32(dpy, &value, 4);
+    size->spec.resource = value;
+    _XRead32(dpy, &value, 4);
+    size->spec.type = value;
+    _XRead32(dpy, &value, 4);
+    size->bytes = value;
+    _XRead32(dpy, &value, 4);
+    size->ref_count = value;
+    _XRead32(dpy, &value, 4);
+    size->use_count = value;
+    return 0;
+}
+
+static Status ReadResourceSizeValues(
+   Display                *dpy,
+   long                    num_sizes,
+   XResResourceSizeValue  *sizes)
+{
+    int c;
+    int d;
+    for (c = 0; c < num_sizes; ++c) {
+        long int num;
+        ReadResourceSizeSpec(dpy, &sizes[c].size);
+        _XRead32(dpy, &num, 4);
+        sizes[c].num_cross_references = num;
+        sizes[c].cross_references = num ? calloc(num, sizeof(*sizes[c].cross_references)) : NULL;
+        for (d = 0; d < num; ++d) {
+            ReadResourceSizeSpec(dpy, &sizes[c].cross_references[d]);
+        }
+    }
+    return Success;
+}
+
+Status XResQueryResourceBytes (
+   Display            *dpy,
+   XID                 client,
+   long                num_specs,
+   XResResourceIdSpec *resource_specs, /* in */
+   long               *num_sizes, /* out */
+   XResResourceSizeValue **sizes /* out */
+)
+{
+    XExtDisplayInfo *info = find_display (dpy);
+    xXResQueryResourceBytesReq *req;
+    xXResQueryResourceBytesReply rep;
+    int c;
+
+    *num_sizes = 0;
+
+    XResCheckExtension (dpy, info, 0);
+
+    LockDisplay (dpy);
+    GetReq (XResQueryResourceBytes, req);
+    req->reqType = info->codes->major_opcode;
+    req->XResReqType = X_XResQueryResourceBytes;
+    req->length += num_specs * 2; /* 2 longs per client id spec */
+    req->client = client;
+    req->numSpecs = num_specs;
+
+    for (c = 0; c < num_specs; ++c) {
+        Data32(dpy, &resource_specs[c].resource, 4);
+        Data32(dpy, &resource_specs[c].type, 4);
+    }
+
+    *num_sizes = 0;
+    *sizes = NULL;
+
+    if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) {
+        goto error;
+    }
+
+    *sizes = calloc(rep.numSizes, sizeof(**sizes));
+    *num_sizes = rep.numSizes;
+
+    if (ReadResourceSizeValues(dpy, *num_sizes, *sizes) != Success) {
+        goto error;
+    }
+
+    UnlockDisplay (dpy);
+    SyncHandle ();
+    return Success;
+
+ error:
+    XResResourceSizeValuesDestroy(*num_sizes, *sizes);
+
+    UnlockDisplay (dpy);
+    SyncHandle ();
+    return !Success;
+}
+
+void XResResourceSizeValuesDestroy (
+   long                num_sizes,
+   XResResourceSizeValue *sizes
+)
+{
+    int c;
+    for (c = 0; c < num_sizes; ++c) {
+        free(sizes[c].cross_references);
+    }
+    free(sizes);
+}

commit 0f38938a27df1f865dcdda35f4d2ef191092ba42
Author: Erkki Seppälä <erkki.seppala@vincit.fi>
Date:   Mon Nov 29 12:43:51 2010 +0200

    Implemented first part of XResource extension v1.2: XResQueryClientIds
    
    Signed-off-by: Erkki Seppälä <erkki.seppala@vincit.fi>
    Reviewed-by: Rami Ylimäki <rami.ylimaki@vincit.fi>
    Reviewed-by: Tiago Vignatti <tiago.vignatti@nokia.com>
    Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>

diff --git a/include/X11/extensions/XRes.h b/include/X11/extensions/XRes.h
index ed4b2b8..b9759e3 100644
--- a/include/X11/extensions/XRes.h
+++ b/include/X11/extensions/XRes.h
@@ -7,6 +7,8 @@
 
 #include <X11/Xfuncproto.h>
 
+/* v1.0 */
+
 typedef struct {
   XID resource_base;
   XID resource_mask;
@@ -17,8 +19,33 @@ typedef struct {
   unsigned int count;
 } XResType;
 
+/* v1.2 */
+
+typedef enum {
+  XRES_CLIENT_ID_XID,
+  XRES_CLIENT_ID_PID,
+  XRES_CLIENT_ID_NR
+} XResClientIdType;
+
+typedef enum {
+  XRES_CLIENT_ID_XID_MASK = 1 << XRES_CLIENT_ID_XID,
+  XRES_CLIENT_ID_PID_MASK = 1 << XRES_CLIENT_ID_PID
+} XResClientIdMask;
+
+typedef struct {
+  XID           client;
+  unsigned int  mask;
+} XResClientIdSpec;
+
+typedef struct {
+  XResClientIdSpec spec;
+  long          length;
+  void         *value;
+} XResClientIdValue;
+
 _XFUNCPROTOBEGIN
 
+/* v1.0 */
 
 Bool XResQueryExtension (
    Display *dpy,
@@ -51,6 +78,26 @@ Status XResQueryClientPixmapBytes (
    unsigned long *bytes
 );
 
+/* v1.2 */
+
+Status XResQueryClientIds (
+   Display            *dpy,
+   long                num_specs,
+   XResClientIdSpec   *client_specs,   /* in */
+   long               *num_ids,        /* out */
+   XResClientIdValue **client_ids      /* out */
+);
+
+XResClientIdType XResGetClientIdType(XResClientIdValue* value);
+
+/* return -1 if no pid associated to the value */
+pid_t XResGetClientPid(XResClientIdValue* value);
+
+void XResClientIdsDestroy (
+   long                num_ids,
+   XResClientIdValue  *client_ids
+);
+
 _XFUNCPROTOEND
 
 #endif /* _XRES_H */
diff --git a/src/XRes.c b/src/XRes.c
index 6091c96..0781666 100644
--- a/src/XRes.c
+++ b/src/XRes.c
@@ -12,7 +12,7 @@
 #include <X11/extensions/extutil.h>
 #include <X11/extensions/XResproto.h>
 #include <X11/extensions/XRes.h>
-
+#include <assert.h>
 
 static XExtensionInfo _xres_ext_info_data;
 static XExtensionInfo *xres_ext_info = &_xres_ext_info_data;
@@ -228,3 +228,119 @@ Status XResQueryClientPixmapBytes (
     return 1;
 }
 
+static Bool ReadClientValues(
+   Display              *dpy,
+   long                 num_ids,
+   XResClientIdValue   *client_ids /* out */
+)
+{
+    int c;
+    for (c = 0; c < num_ids; ++c) {
+        XResClientIdValue* client = client_ids + c;
+        CARD32 value;
+        _XRead32 (dpy, &value, 4);
+        client->spec.client = value;
+        _XRead32 (dpy, &value, 4);
+        client->spec.mask = value;
+        _XRead32 (dpy, &value, 4);
+        client->length = value;
+        client->value = malloc(client->length);
+        _XRead32 (dpy, client->value, client->length);
+    }
+    return True;
+}
+
+Status XResQueryClientIds (
+   Display            *dpy,
+   long                num_specs,
+   XResClientIdSpec   *client_specs,   /* in */
+   long               *num_ids,        /* out */
+   XResClientIdValue **client_ids      /* out */
+)
+{
+    XExtDisplayInfo *info = find_display (dpy);
+    xXResQueryClientIdsReq *req;
+    xXResQueryClientIdsReply rep;
+    int c;
+
+    *num_ids = 0;
+
+    XResCheckExtension (dpy, info, 0);
+    LockDisplay (dpy);
+    GetReq (XResQueryClientIds, req);
+    req->reqType = info->codes->major_opcode;
+    req->XResReqType = X_XResQueryClientIds;
+    req->length += num_specs * 2; /* 2 longs per client id spec */
+    req->numSpecs = num_specs;
+
+    for (c = 0; c < num_specs; ++c) {
+        Data32(dpy, &client_specs[c].client, 4);
+        Data32(dpy, &client_specs[c].mask, 4);
+    }
+
+    if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) {
+        goto error;
+    }
+
+    *client_ids = calloc(rep.numIds, sizeof(**client_ids));
+    *num_ids = rep.numIds;
+
+    if (!ReadClientValues(dpy, *num_ids, *client_ids)) {
+        goto error;
+    }
+
+    UnlockDisplay (dpy);
+    SyncHandle ();
+    return Success;
+
+ error:
+    XResClientIdsDestroy (*num_ids, *client_ids);
+    *client_ids = NULL;
+
+    UnlockDisplay (dpy);
+    SyncHandle ();
+    return !Success;
+}
+
+void XResClientIdsDestroy (
+   long                num_ids,
+   XResClientIdValue  *client_ids
+)
+{
+    int c;
+    for (c = 0; c < num_ids; ++c) {
+        free(client_ids[c].value);
+    }
+    free(client_ids);
+}
+
+XResClientIdType XResGetClientIdType(
+    XResClientIdValue* value
+)
+{
+    int bit;
+    XResClientIdType idType = 0;
+    Bool found = False;
+    for (bit = 0; bit < XRES_CLIENT_ID_NR; ++bit) {
+        if (value->spec.mask & (1 << bit)) {
+            assert(!found);
+            found = True;
+            idType = bit;
+        }
+    }
+
+    assert(found);
+
+    return idType;
+}
+
+pid_t XResGetClientPid(
+    XResClientIdValue* value
+)
+{
+    if (value->spec.mask & XRES_CLIENT_ID_PID_MASK && value->length >= 4) {
+        return (pid_t) * (CARD32*) value->value;
+    } else {
+        return (pid_t) -1;
+    }
+}


Reply to: