| File: | src/ModMap.c |
| Location: | line 161, column 35 |
| Description: | Array access (via field 'modifiermap') results in a null pointer dereference |
| 1 | /* | |||
| 2 | ||||
| 3 | Copyright 1986, 1998 The Open Group | |||
| 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 | OPEN GROUP 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 Open Group 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 Open Group. | |||
| 24 | ||||
| 25 | */ | |||
| 26 | ||||
| 27 | #ifdef HAVE_CONFIG_H1 | |||
| 28 | #include <config.h> | |||
| 29 | #endif | |||
| 30 | #include "Xlibint.h" | |||
| 31 | #include <limits.h> | |||
| 32 | ||||
| 33 | XModifierKeymap * | |||
| 34 | XGetModifierMapping(register Display *dpy) | |||
| 35 | { | |||
| 36 | xGetModifierMappingReply rep; | |||
| 37 | register xReq *req; | |||
| 38 | unsigned long nbytes; | |||
| 39 | XModifierKeymap *res; | |||
| 40 | ||||
| 41 | LockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->lock_display )(dpy); | |||
| 42 | GetEmptyReq(GetModifierMapping, req)req = (xReq *) _XGetRequest(dpy, 119, 4); | |||
| 43 | (void) _XReply (dpy, (xReply *)&rep, 0, xFalse0); | |||
| 44 | ||||
| 45 | if (rep.length < (INT_MAX2147483647 >> 2)) { | |||
| 46 | nbytes = (unsigned long)rep.length << 2; | |||
| 47 | res = Xmalloc(sizeof (XModifierKeymap))malloc(((sizeof (XModifierKeymap)) == 0 ? 1 : (sizeof (XModifierKeymap )))); | |||
| 48 | if (res) | |||
| 49 | res->modifiermap = Xmalloc (nbytes)malloc(((nbytes) == 0 ? 1 : (nbytes))); | |||
| 50 | } else | |||
| 51 | res = NULL((void*)0); | |||
| 52 | if ((! res) || (! res->modifiermap)) { | |||
| 53 | Xfree(res)free((res)); | |||
| 54 | res = (XModifierKeymap *) NULL((void*)0); | |||
| 55 | _XEatDataWords(dpy, rep.length); | |||
| 56 | } else { | |||
| 57 | _XReadPad(dpy, (char *) res->modifiermap, (long) nbytes); | |||
| 58 | res->max_keypermod = rep.numKeyPerModifier; | |||
| 59 | } | |||
| 60 | ||||
| 61 | UnlockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->unlock_display )(dpy); | |||
| 62 | SyncHandle()if (dpy->synchandler) (*dpy->synchandler)(dpy); | |||
| 63 | return (res); | |||
| 64 | } | |||
| 65 | ||||
| 66 | /* | |||
| 67 | * Returns: | |||
| 68 | * MappingSuccess (0) Success | |||
| 69 | * MappingBusy (1) Busy - one or more old or new modifiers are down | |||
| 70 | * MappingFailed (2) Failed - one or more new modifiers unacceptable | |||
| 71 | */ | |||
| 72 | int | |||
| 73 | XSetModifierMapping( | |||
| 74 | register Display *dpy, | |||
| 75 | register XModifierKeymap *modifier_map) | |||
| 76 | { | |||
| 77 | register xSetModifierMappingReq *req; | |||
| 78 | xSetModifierMappingReply rep; | |||
| 79 | int mapSize = modifier_map->max_keypermod << 3; /* 8 modifiers */ | |||
| 80 | ||||
| 81 | LockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->lock_display )(dpy); | |||
| 82 | GetReq(SetModifierMapping, req)req = (xSetModifierMappingReq *) _XGetRequest(dpy, 118, 4); | |||
| 83 | req->length += mapSize >> 2; | |||
| 84 | req->numKeyPerModifier = modifier_map->max_keypermod; | |||
| 85 | ||||
| 86 | Data(dpy, modifier_map->modifiermap, mapSize){ if (dpy->bufptr + (mapSize) <= dpy->bufmax) { __builtin___memcpy_chk (dpy->bufptr, modifier_map->modifiermap, (int)mapSize, __builtin_object_size (dpy->bufptr, 0)); dpy->bufptr += ((mapSize) + 3) & ~3; } else _XSend(dpy, modifier_map-> modifiermap, mapSize);}; | |||
| 87 | ||||
| 88 | (void) _XReply(dpy, (xReply *) & rep, | |||
| 89 | (SIZEOF(xSetModifierMappingReply)32 - SIZEOF(xReply)32) >> 2, xTrue1); | |||
| 90 | UnlockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->unlock_display )(dpy); | |||
| 91 | SyncHandle()if (dpy->synchandler) (*dpy->synchandler)(dpy); | |||
| 92 | return (rep.success); | |||
| 93 | } | |||
| 94 | ||||
| 95 | XModifierKeymap * | |||
| 96 | XNewModifiermap(int keyspermodifier) | |||
| 97 | { | |||
| 98 | XModifierKeymap *res = Xmalloc((sizeof (XModifierKeymap)))malloc((((sizeof (XModifierKeymap))) == 0 ? 1 : ((sizeof (XModifierKeymap ))))); | |||
| 99 | if (res) { | |||
| 100 | res->max_keypermod = keyspermodifier; | |||
| 101 | res->modifiermap = (keyspermodifier > 0 ? | |||
| 102 | Xmalloc(8 * keyspermodifier)malloc(((8 * keyspermodifier) == 0 ? 1 : (8 * keyspermodifier ))) | |||
| 103 | : (KeyCode *) NULL((void*)0)); | |||
| 104 | if (keyspermodifier && (res->modifiermap == NULL((void*)0))) { | |||
| 105 | Xfree(res)free((res)); | |||
| 106 | return (XModifierKeymap *) NULL((void*)0); | |||
| 107 | } | |||
| 108 | } | |||
| 109 | return (res); | |||
| 110 | } | |||
| 111 | ||||
| 112 | ||||
| 113 | int | |||
| 114 | XFreeModifiermap(XModifierKeymap *map) | |||
| 115 | { | |||
| 116 | if (map) { | |||
| 117 | Xfree(map->modifiermap)free((map->modifiermap)); | |||
| 118 | Xfree(map)free((map)); | |||
| 119 | } | |||
| 120 | return 1; | |||
| 121 | } | |||
| 122 | ||||
| 123 | XModifierKeymap * | |||
| 124 | XInsertModifiermapEntry(XModifierKeymap *map, | |||
| 125 | #if NeedWidePrototypes1 | |||
| 126 | unsigned int keycode, | |||
| 127 | #else | |||
| 128 | KeyCode keycode, | |||
| 129 | #endif | |||
| 130 | int modifier) | |||
| 131 | { | |||
| 132 | XModifierKeymap *newmap; | |||
| 133 | int i, | |||
| 134 | row = modifier * map->max_keypermod, | |||
| 135 | newrow, | |||
| 136 | lastrow; | |||
| 137 | ||||
| 138 | for (i=0; i<map->max_keypermod; i++) { | |||
| ||||
| 139 | if (map->modifiermap[ row+i ] == keycode) | |||
| 140 | return(map); /* already in the map */ | |||
| 141 | if (map->modifiermap[ row+i ] == 0) { | |||
| 142 | map->modifiermap[ row+i ] = keycode; | |||
| 143 | return(map); /* we added it without stretching the map */ | |||
| 144 | } | |||
| 145 | } | |||
| 146 | ||||
| 147 | /* stretch the map */ | |||
| 148 | if ((newmap = XNewModifiermap(map->max_keypermod+1)) == NULL((void*)0)) | |||
| 149 | return (XModifierKeymap *) NULL((void*)0); | |||
| 150 | newrow = row = 0; | |||
| 151 | lastrow = newmap->max_keypermod * 8; | |||
| 152 | while (newrow < lastrow) { | |||
| 153 | for (i=0; i<map->max_keypermod; i++) | |||
| 154 | newmap->modifiermap[ newrow+i ] = map->modifiermap[ row+i ]; | |||
| 155 | newmap->modifiermap[ newrow+i ] = 0; | |||
| 156 | row += map->max_keypermod; | |||
| 157 | newrow += newmap->max_keypermod; | |||
| 158 | } | |||
| 159 | (void) XFreeModifiermap(map); | |||
| 160 | newrow = newmap->max_keypermod * modifier + newmap->max_keypermod - 1; | |||
| 161 | newmap->modifiermap[ newrow ] = keycode; | |||
| ||||
| 162 | return(newmap); | |||
| 163 | } | |||
| 164 | ||||
| 165 | XModifierKeymap * | |||
| 166 | XDeleteModifiermapEntry(XModifierKeymap *map, | |||
| 167 | #if NeedWidePrototypes1 | |||
| 168 | unsigned int keycode, | |||
| 169 | #else | |||
| 170 | KeyCode keycode, | |||
| 171 | #endif | |||
| 172 | int modifier) | |||
| 173 | { | |||
| 174 | int i, | |||
| 175 | row = modifier * map->max_keypermod; | |||
| 176 | ||||
| 177 | for (i=0; i<map->max_keypermod; i++) { | |||
| 178 | if (map->modifiermap[ row+i ] == keycode) | |||
| 179 | map->modifiermap[ row+i ] = 0; | |||
| 180 | } | |||
| 181 | /* should we shrink the map?? */ | |||
| 182 | return (map); | |||
| 183 | } |