summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/XISelEv.c25
1 files changed, 19 insertions, 6 deletions
diff --git a/src/XISelEv.c b/src/XISelEv.c
index f871222..0471bef 100644
--- a/src/XISelEv.c
+++ b/src/XISelEv.c
@@ -42,6 +42,7 @@ in this Software without prior written authorization from the author.
#include <X11/extensions/ge.h>
#include <X11/extensions/geproto.h>
#include "XIint.h"
+#include <limits.h>
int
XISelectEvents(Display* dpy, Window win, XIEventMask* masks, int num_masks)
@@ -101,13 +102,14 @@ out:
XIEventMask*
XIGetSelectedEvents(Display* dpy, Window win, int *num_masks_return)
{
- int i, len = 0;
+ unsigned int i, len = 0;
unsigned char *mask;
XIEventMask *mask_out = NULL;
xXIEventMask *mask_in = NULL, *mi;
xXIGetSelectedEventsReq *req;
xXIGetSelectedEventsReply reply;
XExtDisplayInfo *info = XInput_find_display(dpy);
+ size_t rbytes;
*num_masks_return = -1;
LockDisplay(dpy);
@@ -129,11 +131,16 @@ XIGetSelectedEvents(Display* dpy, Window win, int *num_masks_return)
goto out;
}
- mask_in = Xmalloc(reply.length * 4);
- if (!mask_in)
+ if (reply.length < (INT_MAX >> 2)) {
+ rbytes = (unsigned long) reply.length << 2;
+ mask_in = Xmalloc(rbytes);
+ }
+ if (!mask_in) {
+ _XEatDataWords(dpy, reply.length);
goto out;
+ }
- _XRead(dpy, (char*)mask_in, reply.length * 4);
+ _XRead(dpy, (char*)mask_in, rbytes);
/*
* This function takes interleaved xXIEventMask structs & masks off
@@ -148,8 +155,14 @@ XIGetSelectedEvents(Display* dpy, Window win, int *num_masks_return)
for (i = 0, mi = mask_in; i < reply.num_masks; i++)
{
- len += mi->mask_len * 4;
- mi = (xXIEventMask*)((char*)mi + mi->mask_len * 4);
+ unsigned int mask_bytes = mi->mask_len * 4;
+ len += mask_bytes;
+ if (len > INT_MAX)
+ goto out;
+ if ((sizeof(xXIEventMask) + mask_bytes) > rbytes)
+ goto out;
+ rbytes -= (sizeof(xXIEventMask) + mask_bytes);
+ mi = (xXIEventMask*)((char*)mi + mask_bytes);
mi++;
}