XkbCopyKeymap: fix various range issues
Fix a bunch of range issues caused by incorrect assumptions (e.g. that the design was at least halfway sensible), and copy types by hand, instead of just blindly memcpy()ing the lot, since it itself cleverly contains a ton of allocated pointers.
This commit is contained in:
parent
5fb8d947bb
commit
db1ab1bdb2
155
xkb/xkbUtils.c
155
xkb/xkbUtils.c
@ -28,6 +28,7 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||||||
#include <dix-config.h>
|
#include <dix-config.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "os.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
@ -1009,16 +1010,17 @@ XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool sendNotifies)
|
|||||||
if (src->map->syms) {
|
if (src->map->syms) {
|
||||||
if (src->map->size_syms != dst->map->size_syms) {
|
if (src->map->size_syms != dst->map->size_syms) {
|
||||||
if (dst->map->syms)
|
if (dst->map->syms)
|
||||||
tmp = xrealloc(dst->map->syms, src->map->size_syms);
|
tmp = xrealloc(dst->map->syms,
|
||||||
|
src->map->size_syms * sizeof(KeySym));
|
||||||
else
|
else
|
||||||
tmp = xalloc(src->map->size_syms);
|
tmp = xalloc(src->map->size_syms * sizeof(KeySym));
|
||||||
if (!tmp)
|
if (!tmp)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
dst->map->syms = tmp;
|
dst->map->syms = tmp;
|
||||||
|
|
||||||
}
|
}
|
||||||
memcpy(dst->map->syms, src->map->syms, src->map->size_syms);
|
memcpy(dst->map->syms, src->map->syms,
|
||||||
memcpy(dst->map->key_sym_map, src->map->key_sym_map,
|
src->map->size_syms * sizeof(KeySym));
|
||||||
src->map->size_syms);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (dst->map->syms) {
|
if (dst->map->syms) {
|
||||||
@ -1029,37 +1031,116 @@ XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool sendNotifies)
|
|||||||
dst->map->num_syms = src->map->num_syms;
|
dst->map->num_syms = src->map->num_syms;
|
||||||
dst->map->size_syms = src->map->size_syms;
|
dst->map->size_syms = src->map->size_syms;
|
||||||
|
|
||||||
if (src->map->types) {
|
if (src->map->key_sym_map) {
|
||||||
if (src->map->size_types != dst->map->size_types) {
|
if (src->max_key_code != dst->max_key_code) {
|
||||||
XkbKeyTypePtr stype = src->map->types;
|
if (dst->map->key_sym_map)
|
||||||
|
tmp = xrealloc(dst->map->key_sym_map,
|
||||||
if (dst->map->types)
|
(src->max_key_code + 1) *
|
||||||
tmp = xrealloc(dst->map->types, src->map->size_types);
|
sizeof(XkbSymMapRec));
|
||||||
else
|
else
|
||||||
tmp = xalloc(src->map->size_types);
|
tmp = xalloc((src->max_key_code + 1) *
|
||||||
|
sizeof(XkbSymMapRec));
|
||||||
|
if (!tmp)
|
||||||
|
return FALSE;
|
||||||
|
dst->map->key_sym_map = tmp;
|
||||||
|
}
|
||||||
|
memcpy(dst->map->key_sym_map, src->map->key_sym_map,
|
||||||
|
(src->max_key_code + 1) * sizeof(XkbSymMapRec));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (dst->map->key_sym_map) {
|
||||||
|
xfree(dst->map->key_sym_map);
|
||||||
|
dst->map->key_sym_map = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (src->map->types) {
|
||||||
|
if (src->map->size_types > dst->map->size_types) {
|
||||||
|
if (dst->map->types) {
|
||||||
|
tmp = xrealloc(dst->map->types,
|
||||||
|
src->map->size_types * sizeof(XkbKeyTypeRec));
|
||||||
|
bzero(dst->map->types +
|
||||||
|
(dst->map->size_types * sizeof(XkbKeyTypeRec)),
|
||||||
|
(src->map->size_types - dst->map->size_types) *
|
||||||
|
sizeof(XkbKeyTypeRec));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
tmp = xcalloc(src->map->size_types, sizeof(XkbKeyTypeRec));
|
||||||
|
}
|
||||||
if (!tmp)
|
if (!tmp)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
dst->map->types = tmp;
|
dst->map->types = tmp;
|
||||||
}
|
}
|
||||||
memcpy(dst->map->types, src->map->types, src->map->size_types);
|
else if (src->map->size_types < dst->map->size_types) {
|
||||||
|
if (dst->map->types) {
|
||||||
|
for (i = src->map->num_types, dtype = (dst->map->types + i);
|
||||||
|
i < dst->map->size_types; i++, dtype++) {
|
||||||
|
if (dtype->level_names)
|
||||||
|
xfree(dtype->level_names);
|
||||||
|
dtype->level_names = NULL;
|
||||||
|
dtype->num_levels = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
stype = src->map->types;
|
stype = src->map->types;
|
||||||
dtype = dst->map->types;
|
dtype = dst->map->types;
|
||||||
for (i = 0; i < dst->map->num_types; i++, dtype++, stype++) {
|
for (i = 0; i < dst->map->num_types; i++, dtype++, stype++) {
|
||||||
dtype->level_names = xalloc(dtype->num_levels * sizeof(Atom));
|
if (stype->num_levels != dtype->num_levels) {
|
||||||
if (!dtype->level_names)
|
if (dtype->level_names)
|
||||||
continue; /* don't return FALSE here, try to whack all the
|
tmp = xrealloc(dtype->level_names,
|
||||||
pointers we can, so we don't double-free when
|
stype->num_levels * sizeof(Atom));
|
||||||
going down. */
|
else
|
||||||
|
tmp = xalloc(stype->num_levels * sizeof(Atom));
|
||||||
|
if (!tmp)
|
||||||
|
continue; /* don't return FALSE here, try to whack
|
||||||
|
all the pointers we can, so we don't
|
||||||
|
double-free when going down. */
|
||||||
|
dtype->level_names = tmp;
|
||||||
|
dtype->num_levels = stype->num_levels;
|
||||||
|
}
|
||||||
memcpy(dtype->level_names, stype->level_names,
|
memcpy(dtype->level_names, stype->level_names,
|
||||||
dtype->num_levels * sizeof(Atom));
|
stype->num_levels * sizeof(Atom));
|
||||||
|
|
||||||
|
dtype->name = stype->name;
|
||||||
|
memcpy(&dtype->mods, &stype->mods, sizeof(XkbModsRec));
|
||||||
|
|
||||||
|
if (stype->map_count != dtype->map_count) {
|
||||||
|
if (dtype->map)
|
||||||
|
tmp = xrealloc(dtype->map,
|
||||||
|
stype->map_count *
|
||||||
|
sizeof(XkbKTMapEntryRec));
|
||||||
|
else
|
||||||
|
tmp = xalloc(stype->map_count *
|
||||||
|
sizeof(XkbKTMapEntryRec));
|
||||||
|
if (!tmp)
|
||||||
|
return FALSE;
|
||||||
|
dtype->map = tmp;
|
||||||
|
|
||||||
|
if (dtype->preserve)
|
||||||
|
tmp = xrealloc(dtype->preserve,
|
||||||
|
stype->map_count * sizeof(XkbModsRec));
|
||||||
|
else
|
||||||
|
tmp = xalloc(stype->map_count * sizeof(XkbModsRec));
|
||||||
|
if (!tmp)
|
||||||
|
return FALSE;
|
||||||
|
dtype->preserve = tmp;
|
||||||
|
}
|
||||||
|
dtype->map_count = stype->map_count;
|
||||||
|
memcpy(dtype->map, stype->map, stype->map_count *
|
||||||
|
sizeof(XkbKTMapEntryRec));
|
||||||
|
memcpy(dtype->preserve, stype->preserve, stype->map_count *
|
||||||
|
sizeof(XkbModsRec));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (dst->map->types) {
|
if (dst->map->types) {
|
||||||
for (i = 0, dtype = dst->map->types; i < dst->map->num_types;
|
for (i = 0, dtype = dst->map->types; i < dst->map->num_types;
|
||||||
i++, dtype++)
|
i++, dtype++) {
|
||||||
xfree(dtype->level_names);
|
xfree(dtype->level_names);
|
||||||
|
xfree(dtype->map);
|
||||||
|
xfree(dtype->preserve);
|
||||||
|
}
|
||||||
xfree(dst->map->types);
|
xfree(dst->map->types);
|
||||||
dst->map->types = NULL;
|
dst->map->types = NULL;
|
||||||
}
|
}
|
||||||
@ -1123,15 +1204,16 @@ XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool sendNotifies)
|
|||||||
if (src->server->acts) {
|
if (src->server->acts) {
|
||||||
if (src->server->size_acts != dst->server->size_acts) {
|
if (src->server->size_acts != dst->server->size_acts) {
|
||||||
if (dst->server->acts)
|
if (dst->server->acts)
|
||||||
tmp = xrealloc(dst->server->acts, src->server->size_acts);
|
tmp = xrealloc(dst->server->acts,
|
||||||
|
src->server->size_acts * sizeof(XkbAction));
|
||||||
else
|
else
|
||||||
tmp = xalloc(src->server->size_acts);
|
tmp = xalloc(src->server->size_acts * sizeof(XkbAction));
|
||||||
if (!tmp)
|
if (!tmp)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
dst->server->acts = tmp;
|
dst->server->acts = tmp;
|
||||||
}
|
}
|
||||||
memcpy(dst->server->acts, src->server->acts,
|
memcpy(dst->server->acts, src->server->acts,
|
||||||
src->server->size_acts);
|
src->server->size_acts * sizeof(XkbAction));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (dst->server->acts) {
|
if (dst->server->acts) {
|
||||||
@ -1140,19 +1222,23 @@ XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool sendNotifies)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
dst->server->size_acts = src->server->size_acts;
|
dst->server->size_acts = src->server->size_acts;
|
||||||
|
dst->server->num_acts = src->server->num_acts;
|
||||||
|
|
||||||
if (src->server->key_acts) {
|
if (src->server->key_acts) {
|
||||||
if (src->max_key_code != dst->max_key_code) {
|
if (src->max_key_code != dst->max_key_code) {
|
||||||
if (dst->server->key_acts)
|
if (dst->server->key_acts)
|
||||||
tmp = xrealloc(dst->server->key_acts, src->max_key_code + 1);
|
tmp = xrealloc(dst->server->key_acts,
|
||||||
|
(src->max_key_code + 1) *
|
||||||
|
sizeof(unsigned short));
|
||||||
else
|
else
|
||||||
tmp = xalloc(src->max_key_code + 1);
|
tmp = xalloc((src->max_key_code + 1) *
|
||||||
|
sizeof(unsigned short));
|
||||||
if (!tmp)
|
if (!tmp)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
dst->server->key_acts = tmp;
|
dst->server->key_acts = tmp;
|
||||||
}
|
}
|
||||||
memcpy(dst->server->key_acts, src->server->key_acts,
|
memcpy(dst->server->key_acts, src->server->key_acts,
|
||||||
src->max_key_code + 1);
|
(src->max_key_code + 1) * sizeof(unsigned short));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (dst->server->key_acts) {
|
if (dst->server->key_acts) {
|
||||||
@ -1188,15 +1274,17 @@ XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool sendNotifies)
|
|||||||
if (src->max_key_code != dst->max_key_code) {
|
if (src->max_key_code != dst->max_key_code) {
|
||||||
if (dst->server->vmodmap)
|
if (dst->server->vmodmap)
|
||||||
tmp = xrealloc(dst->server->vmodmap,
|
tmp = xrealloc(dst->server->vmodmap,
|
||||||
src->max_key_code + 1);
|
(src->max_key_code + 1) *
|
||||||
|
sizeof(unsigned short));
|
||||||
else
|
else
|
||||||
tmp = xalloc(src->max_key_code + 1);
|
tmp = xalloc((src->max_key_code + 1) *
|
||||||
|
sizeof(unsigned short));
|
||||||
if (!tmp)
|
if (!tmp)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
dst->server->vmodmap = tmp;
|
dst->server->vmodmap = tmp;
|
||||||
}
|
}
|
||||||
memcpy(dst->server->vmodmap, src->server->vmodmap,
|
memcpy(dst->server->vmodmap, src->server->vmodmap,
|
||||||
src->max_key_code + 1);
|
(src->max_key_code + 1) * sizeof(unsigned short));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (dst->server->vmodmap) {
|
if (dst->server->vmodmap) {
|
||||||
@ -1324,20 +1412,20 @@ XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool sendNotifies)
|
|||||||
/* compat */
|
/* compat */
|
||||||
if (src->compat) {
|
if (src->compat) {
|
||||||
if (src->compat->sym_interpret) {
|
if (src->compat->sym_interpret) {
|
||||||
if (src->compat->num_si != dst->compat->num_si) {
|
if (src->compat->size_si != dst->compat->size_si) {
|
||||||
if (dst->compat->sym_interpret)
|
if (dst->compat->sym_interpret)
|
||||||
tmp = xrealloc(dst->compat->sym_interpret,
|
tmp = xrealloc(dst->compat->sym_interpret,
|
||||||
src->compat->num_si *
|
src->compat->size_si *
|
||||||
sizeof(XkbSymInterpretRec));
|
sizeof(XkbSymInterpretRec));
|
||||||
else
|
else
|
||||||
tmp = xalloc(src->compat->num_si *
|
tmp = xalloc(src->compat->size_si *
|
||||||
sizeof(XkbSymInterpretRec));
|
sizeof(XkbSymInterpretRec));
|
||||||
if (!tmp)
|
if (!tmp)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
dst->compat->sym_interpret = tmp;
|
dst->compat->sym_interpret = tmp;
|
||||||
}
|
}
|
||||||
memcpy(dst->compat->sym_interpret, src->compat->sym_interpret,
|
memcpy(dst->compat->sym_interpret, src->compat->sym_interpret,
|
||||||
src->compat->num_si * sizeof(XkbSymInterpretRec));
|
src->compat->size_si * sizeof(XkbSymInterpretRec));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (dst->compat->sym_interpret) {
|
if (dst->compat->sym_interpret) {
|
||||||
@ -1346,6 +1434,7 @@ XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool sendNotifies)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
dst->compat->num_si = src->compat->num_si;
|
dst->compat->num_si = src->compat->num_si;
|
||||||
|
dst->compat->size_si = src->compat->size_si;
|
||||||
|
|
||||||
memcpy(dst->compat->groups, src->compat->groups,
|
memcpy(dst->compat->groups, src->compat->groups,
|
||||||
XkbNumKbdGroups * sizeof(XkbModsRec));
|
XkbNumKbdGroups * sizeof(XkbModsRec));
|
||||||
|
Loading…
Reference in New Issue
Block a user