| File: | XISelEv.c |
| Location: | line 79, column 12 |
| Description: | Call to 'calloc' has an allocation size of 0 bytes |
| 1 | /************************************************************ | |||
| 2 | ||||
| 3 | Copyright 2009 Red Hat, Inc. | |||
| 4 | ||||
| 5 | Permission to use, copy, modify, distribute, and sell this software and its | |||
| 6 | documentation for any purpose is hereby granted without fee, provided that | |||
| 7 | the above copyright notice appear in all copies and that both that | |||
| 8 | copyright notice and this permission notice appear in supporting | |||
| 9 | documentation. | |||
| 10 | ||||
| 11 | The above copyright notice and this permission notice shall be included in | |||
| 12 | all copies or substantial portions of the Software. | |||
| 13 | ||||
| 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||
| 17 | AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN | |||
| 18 | AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |||
| 19 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||
| 20 | ||||
| 21 | Except as contained in this notice, the name of the author shall not be | |||
| 22 | used in advertising or otherwise to promote the sale, use or other dealings | |||
| 23 | in this Software without prior written authorization from the author. | |||
| 24 | ||||
| 25 | */ | |||
| 26 | ||||
| 27 | /*********************************************************************** | |||
| 28 | * | |||
| 29 | * XISelectEvent - Select for XI2 events. | |||
| 30 | * | |||
| 31 | */ | |||
| 32 | ||||
| 33 | #ifdef HAVE_CONFIG_H1 | |||
| 34 | #include <config.h> | |||
| 35 | #endif | |||
| 36 | ||||
| 37 | #include <stdint.h> | |||
| 38 | #include <X11/Xlibint.h> | |||
| 39 | #include <X11/extensions/XI2proto.h> | |||
| 40 | #include <X11/extensions/XInput2.h> | |||
| 41 | #include <X11/extensions/extutil.h> | |||
| 42 | #include <X11/extensions/ge.h> | |||
| 43 | #include <X11/extensions/geproto.h> | |||
| 44 | #include "XIint.h" | |||
| 45 | #include <limits.h> | |||
| 46 | ||||
| 47 | int | |||
| 48 | XISelectEvents(Display* dpy, Window win, XIEventMask* masks, int num_masks) | |||
| 49 | { | |||
| 50 | XIEventMask *current; | |||
| 51 | xXISelectEventsReq *req; | |||
| 52 | xXIEventMask mask; | |||
| 53 | int i; | |||
| 54 | int len = 0; | |||
| 55 | int r = Success0; | |||
| 56 | int max_mask_len = 0; | |||
| 57 | char *buff; | |||
| 58 | ||||
| 59 | XExtDisplayInfo *info = XInput_find_display(dpy); | |||
| 60 | LockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->lock_display )(dpy); | |||
| 61 | if (_XiCheckExtInit(dpy, XInput_2_07, info) == -1) { | |||
| ||||
| 62 | r = NoSuchExtension1; | |||
| 63 | goto out_unlocked; | |||
| 64 | } | |||
| 65 | ||||
| 66 | for (i = 0; i < num_masks; i++) { | |||
| 67 | current = &masks[i]; | |||
| 68 | if (current->mask_len > INT_MAX2147483647 - 3 || | |||
| 69 | (current->mask_len + 3)/4 >= 0xffff) { | |||
| 70 | r = -1; | |||
| 71 | goto out; | |||
| 72 | } | |||
| 73 | if (current->mask_len > max_mask_len) | |||
| 74 | max_mask_len = current->mask_len; | |||
| 75 | } | |||
| 76 | ||||
| 77 | /* max_mask_len is in bytes, but we need 4-byte units on the wire, | |||
| 78 | * and they need to be padded with 0 */ | |||
| 79 | buff = calloc(4, ((max_mask_len + 3)/4)); | |||
| ||||
| 80 | if (!buff) { | |||
| 81 | r = -1; | |||
| 82 | goto out; | |||
| 83 | } | |||
| 84 | ||||
| 85 | GetReq(XISelectEvents, req)req = (xXISelectEventsReq *) _XGetRequest(dpy, 46, 12); | |||
| 86 | ||||
| 87 | req->reqType = info->codes->major_opcode; | |||
| 88 | req->ReqType = X_XISelectEvents46; | |||
| 89 | req->win = win; | |||
| 90 | req->num_masks = num_masks; | |||
| 91 | ||||
| 92 | /* get the right length */ | |||
| 93 | for (i = 0; i < num_masks; i++) | |||
| 94 | { | |||
| 95 | len++; | |||
| 96 | current = &masks[i]; | |||
| 97 | len += (current->mask_len + 3)/4; | |||
| 98 | } | |||
| 99 | ||||
| 100 | SetReqLen(req, len, len)req->length += len; | |||
| 101 | ||||
| 102 | for (i = 0; i < num_masks; i++) | |||
| 103 | { | |||
| 104 | current = &masks[i]; | |||
| 105 | mask.deviceid = current->deviceid; | |||
| 106 | mask.mask_len = (current->mask_len + 3)/4; | |||
| 107 | ||||
| 108 | memset(buff, 0, max_mask_len)__builtin___memset_chk (buff, 0, max_mask_len, __builtin_object_size (buff, 0)); | |||
| 109 | memcpy(buff, current->mask, current->mask_len)__builtin___memcpy_chk (buff, current->mask, current->mask_len , __builtin_object_size (buff, 0)); | |||
| 110 | Data(dpy, (char*)&mask, sizeof(xXIEventMask)){ if (dpy->bufptr + (sizeof(xXIEventMask)) <= dpy->bufmax ) { __builtin___memcpy_chk (dpy->bufptr, (char*)&mask, (int)sizeof(xXIEventMask), __builtin_object_size (dpy->bufptr , 0)); dpy->bufptr += ((sizeof(xXIEventMask)) + 3) & ~ 3; } else _XSend(dpy, (char*)&mask, sizeof(xXIEventMask)) ;}; | |||
| 111 | Data(dpy, buff, mask.mask_len * 4){ if (dpy->bufptr + (mask.mask_len * 4) <= dpy->bufmax ) { __builtin___memcpy_chk (dpy->bufptr, buff, (int)mask.mask_len * 4, __builtin_object_size (dpy->bufptr, 0)); dpy->bufptr += ((mask.mask_len * 4) + 3) & ~3; } else _XSend(dpy, buff , mask.mask_len * 4);}; | |||
| 112 | } | |||
| 113 | ||||
| 114 | free(buff); | |||
| 115 | out: | |||
| 116 | UnlockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->unlock_display )(dpy); | |||
| 117 | out_unlocked: | |||
| 118 | SyncHandle()if (dpy->synchandler) (*dpy->synchandler)(dpy); | |||
| 119 | return r; | |||
| 120 | ||||
| 121 | } | |||
| 122 | ||||
| 123 | XIEventMask* | |||
| 124 | XIGetSelectedEvents(Display* dpy, Window win, int *num_masks_return) | |||
| 125 | { | |||
| 126 | unsigned int i, len = 0; | |||
| 127 | unsigned char *mask; | |||
| 128 | XIEventMask *mask_out = NULL((void*)0); | |||
| 129 | xXIEventMask *mask_in = NULL((void*)0), *mi; | |||
| 130 | xXIGetSelectedEventsReq *req; | |||
| 131 | xXIGetSelectedEventsReply reply; | |||
| 132 | XExtDisplayInfo *info = XInput_find_display(dpy); | |||
| 133 | size_t rbytes; | |||
| 134 | ||||
| 135 | *num_masks_return = -1; | |||
| 136 | LockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->lock_display )(dpy); | |||
| 137 | if (_XiCheckExtInit(dpy, XInput_2_07, info) == -1) | |||
| 138 | goto out_unlocked; | |||
| 139 | ||||
| 140 | GetReq(XIGetSelectedEvents, req)req = (xXIGetSelectedEventsReq *) _XGetRequest(dpy, 60, 8); | |||
| 141 | ||||
| 142 | req->reqType = info->codes->major_opcode; | |||
| 143 | req->ReqType = X_XIGetSelectedEvents60; | |||
| 144 | req->win = win; | |||
| 145 | ||||
| 146 | if (!_XReply(dpy, (xReply *) &reply, 0, xFalse0)) | |||
| 147 | goto out; | |||
| 148 | ||||
| 149 | if (reply.num_masks == 0) | |||
| 150 | { | |||
| 151 | *num_masks_return = 0; | |||
| 152 | goto out; | |||
| 153 | } | |||
| 154 | ||||
| 155 | if (reply.length < (INT_MAX2147483647 >> 2)) { | |||
| 156 | rbytes = (unsigned long) reply.length << 2; | |||
| 157 | mask_in = Xmalloc(rbytes)malloc(((rbytes) == 0 ? 1 : (rbytes))); | |||
| 158 | } | |||
| 159 | if (!mask_in) { | |||
| 160 | _XEatDataWords(dpy, reply.length); | |||
| 161 | goto out; | |||
| 162 | } | |||
| 163 | ||||
| 164 | _XRead(dpy, (char*)mask_in, rbytes); | |||
| 165 | ||||
| 166 | /* | |||
| 167 | * This function takes interleaved xXIEventMask structs & masks off | |||
| 168 | * the wire, such as this 3 mask reply: | |||
| 169 | * [struct a][masks a][struct b][masks b][struct c][masks c] | |||
| 170 | * And generates a memory buffer to be returned to callers in which | |||
| 171 | * they are not interleaved, so that callers can treat the returned | |||
| 172 | * pointer as a simple array of XIEventMask structs, such as: | |||
| 173 | * [struct a][struct b][struct c][masks a][masks b][masks c] | |||
| 174 | */ | |||
| 175 | len = reply.num_masks * sizeof(XIEventMask); | |||
| 176 | ||||
| 177 | for (i = 0, mi = mask_in; i < reply.num_masks; i++) | |||
| 178 | { | |||
| 179 | unsigned int mask_bytes = mi->mask_len * 4; | |||
| 180 | len += mask_bytes; | |||
| 181 | if (len > INT_MAX2147483647) | |||
| 182 | goto out; | |||
| 183 | if ((sizeof(xXIEventMask) + mask_bytes) > rbytes) | |||
| 184 | goto out; | |||
| 185 | rbytes -= (sizeof(xXIEventMask) + mask_bytes); | |||
| 186 | mi = (xXIEventMask*)((char*)mi + mask_bytes); | |||
| 187 | mi++; | |||
| 188 | } | |||
| 189 | ||||
| 190 | mask_out = Xmalloc(len)malloc(((len) == 0 ? 1 : (len))); | |||
| 191 | if (!mask_out) | |||
| 192 | goto out; | |||
| 193 | ||||
| 194 | mi = mask_in; | |||
| 195 | mask = (unsigned char*)&mask_out[reply.num_masks]; | |||
| 196 | for (i = 0; i < reply.num_masks; i++) | |||
| 197 | { | |||
| 198 | mask_out[i].deviceid = mi->deviceid; | |||
| 199 | mask_out[i].mask_len = mi->mask_len * 4; | |||
| 200 | mask_out[i].mask = mask; | |||
| 201 | memcpy(mask_out[i].mask, &mi[1], mask_out[i].mask_len)__builtin___memcpy_chk (mask_out[i].mask, &mi[1], mask_out [i].mask_len, __builtin_object_size (mask_out[i].mask, 0)); | |||
| 202 | mask += mask_out[i].mask_len; | |||
| 203 | mi = (xXIEventMask*)((char*)mi + mi->mask_len * 4); | |||
| 204 | mi++; | |||
| 205 | } | |||
| 206 | ||||
| 207 | *num_masks_return = reply.num_masks; | |||
| 208 | ||||
| 209 | out: | |||
| 210 | Xfree(mask_in)free((mask_in)); | |||
| 211 | ||||
| 212 | UnlockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->unlock_display )(dpy); | |||
| 213 | ||||
| 214 | out_unlocked: | |||
| 215 | SyncHandle()if (dpy->synchandler) (*dpy->synchandler)(dpy); | |||
| 216 | ||||
| 217 | return mask_out; | |||
| 218 | } |