Imported Upstream version 1.7.2
[platform/upstream/libXi.git] / src / XGetFCtl.c
index 2961034..2d71fab 100644 (file)
@@ -61,6 +61,7 @@ SOFTWARE.
 #include <X11/extensions/XInput.h>
 #include <X11/extensions/extutil.h>
 #include "XIint.h"
+#include <limits.h>
 
 XFeedbackState *
 XGetFeedbackControl(
@@ -68,8 +69,6 @@ XGetFeedbackControl(
     XDevice            *dev,
     int                        *num_feedbacks)
 {
-    int size = 0;
-    int nbytes, i;
     XFeedbackState *Feedback = NULL;
     XFeedbackState *Sav = NULL;
     xFeedbackState *f = NULL;
@@ -91,17 +90,28 @@ XGetFeedbackControl(
        goto out;
 
     if (rep.length > 0) {
+       unsigned long nbytes;
+       size_t size = 0;
+       int i;
+
        *num_feedbacks = rep.num_feedbacks;
-       nbytes = (long)rep.length << 2;
-       f = (xFeedbackState *) Xmalloc((unsigned)nbytes);
+
+       if (rep.length < (INT_MAX >> 2)) {
+           nbytes = rep.length << 2;
+           f = Xmalloc(nbytes);
+       }
        if (!f) {
-           _XEatData(dpy, (unsigned long)nbytes);
+           _XEatDataWords(dpy, rep.length);
            goto out;
        }
        sav = f;
        _XRead(dpy, (char *)f, nbytes);
 
        for (i = 0; i < *num_feedbacks; i++) {
+           if (f->length > nbytes)
+               goto out;
+           nbytes -= f->length;
+
            switch (f->class) {
            case KbdFeedbackClass:
                size += sizeof(XKbdFeedbackState);
@@ -115,7 +125,6 @@ XGetFeedbackControl(
            case StringFeedbackClass:
            {
                xStringFeedbackState *strf = (xStringFeedbackState *) f;
-
                size += sizeof(XStringFeedbackState) +
                    (strf->num_syms_supported * sizeof(KeySym));
            }
@@ -130,10 +139,12 @@ XGetFeedbackControl(
                size += f->length;
                break;
            }
+           if (size > INT_MAX)
+               goto out;
            f = (xFeedbackState *) ((char *)f + f->length);
        }
 
-       Feedback = (XFeedbackState *) Xmalloc((unsigned)size);
+       Feedback = Xmalloc(size);
        if (!Feedback)
            goto out;
 
@@ -181,18 +192,18 @@ XGetFeedbackControl(
            }
            case IntegerFeedbackClass:
            {
-               xIntegerFeedbackState *i;
+               xIntegerFeedbackState *ifs;
                XIntegerFeedbackState *I;
 
-               i = (xIntegerFeedbackState *) f;
+               ifs = (xIntegerFeedbackState *) f;
                I = (XIntegerFeedbackState *) Feedback;
 
-               I->class = i->class;
+               I->class = ifs->class;
                I->length = sizeof(XIntegerFeedbackState);
-               I->id = i->id;
-               I->resolution = i->resolution;
-               I->minVal = i->min_value;
-               I->maxVal = i->max_value;
+               I->id = ifs->id;
+               I->resolution = ifs->resolution;
+               I->minVal = ifs->min_value;
+               I->maxVal = ifs->max_value;
                break;
            }
            case StringFeedbackClass: