Do not discard unread data from XGetWindowProperty
authorHuang Peng <shawn.p.huang@gmail.com>
Wed, 15 Oct 2008 14:17:53 +0000 (22:17 +0800)
committerHuang Peng <shawn.p.huang@gmail.com>
Wed, 15 Oct 2008 14:17:53 +0000 (22:17 +0800)
util/IMdkit/Xi18n.h
util/IMdkit/i18nUtil.c
util/IMdkit/i18nX.c

index aaf7768..e673f54 100644 (file)
@@ -149,6 +149,8 @@ typedef struct _Xi18nClient
      */
     int                sync;
     XIMPending  *pending;
+    /* property offset to read next data */
+    long        property_offset;
     void *trans_rec;           /* contains transport specific data  */
     struct _Xi18nClient *next;
 } Xi18nClient;
index 22a2376..c07de48 100644 (file)
@@ -70,6 +70,7 @@ Xi18nClient *_Xi18nNewClient(Xi18n i18n_core)
     client->sync = False;
     client->byte_order = '?';  /* initial value */
     memset (&client->pending, 0, sizeof (XIMPending *));
+    client->property_offset = 0;
     client->next = i18n_core->address.clients;
     i18n_core->address.clients = client;
 
index a5ba080..df0edec 100644 (file)
@@ -29,6 +29,7 @@ IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  
 ******************************************************************/
 
+#include <limits.h>
 #include <X11/Xlib.h>
 #include <X11/Xatom.h>
 #include "FrameMgr.h"
@@ -128,6 +129,7 @@ static unsigned char *ReadXIMMessage (XIMS ims,
     else if (ev->format == 32) {
         /* ClientMessage and WindowProperty */
         unsigned long length = (unsigned long) ev->data.l[0];
+       unsigned long get_length;
         Atom atom = (Atom) ev->data.l[1];
         int    return_code;
         Atom   actual_type_ret;
@@ -136,11 +138,20 @@ static unsigned char *ReadXIMMessage (XIMS ims,
         unsigned char *prop;
         unsigned long nitems;
 
+       /* Round up length to next 4 byte value. */
+       get_length = length + 3;
+       if (get_length > LONG_MAX)
+               get_length = LONG_MAX;
+       get_length /= 4;
+       if (get_length == 0) {
+               fprintf(stderr, "%s: invalid length 0\n", __FUNCTION__);
+               return NULL;
+       }
         return_code = XGetWindowProperty (i18n_core->address.dpy,
                                           x_client->accept_win,
                                           atom,
-                                          0L,
-                                          length,
+                                          client->property_offset / 4,
+                                          get_length,
                                           True,
                                           AnyPropertyType,
                                           &actual_type_ret,
@@ -151,15 +162,27 @@ static unsigned char *ReadXIMMessage (XIMS ims,
         if (return_code != Success || actual_format_ret == 0 || nitems == 0) {
             if (return_code == Success)
                 XFree (prop);
+           client->property_offset = 0;
             return (unsigned char *) NULL;
         }
-        if (length != nitems)
-            length = nitems;
-       if (actual_format_ret == 16)
-           length *= 2;
-       else if (actual_format_ret == 32)
-           length *= 4;
-
+       /* Update the offset to read next time as needed */
+       if (bytes_after_ret > 0)
+               client->property_offset += length;
+       else
+               client->property_offset = 0;
+       switch (actual_format_ret) {
+           case 8:
+           case 16:
+           case 32:
+                   length = nitems * actual_format_ret / 8;
+                   break;
+           default:
+                   fprintf(stderr, "%s: unknown property return format: %d\n",
+                           __FUNCTION__, actual_format_ret);
+                   XFree(prop);
+                   client->property_offset = 0;
+                   return NULL;
+       }
         /* if hit, it might be an error */
         if ((p = (unsigned char *) malloc (length)) == NULL)
             return (unsigned char *) NULL;