From: Daniel Stone Date: Sun, 5 Nov 2006 00:47:59 +0000 (+0200) Subject: XkbCopyKeymap: don't iterate broken types, or dereference null pointers X-Git-Url: http://gitweb.freedesktop.org/?p=xorg/xserver.git;a=commitdiff;h=389275d240e4ba19d62fda0f138a45c7ecb245ff XkbCopyKeymap: don't iterate broken types, or dereference null pointers Don't iterate invalid destination types (>= num_types) when coping key types. Don't free key_aliases if it's NULL (theoretical, but sure). Make sure dst's label_font gets allocated if it's NULL. (Thanks, Chris Lee.) --- --- a/xkb/xkbUtils.c +++ b/xkb/xkbUtils.c @@ -1047,34 +1047,40 @@ XkbCopyKeymap(XkbDescPtr src, XkbDescPtr } } - if (src->map->types) { - if (src->map->size_types > dst->map->size_types) { - if (dst->map->types) { + if (src->map->types && src->map->num_types) { + if (src->map->num_types > dst->map->size_types || + !dst->map->types || !dst->map->size_types) { + if (dst->map->types && dst->map->size_types) { tmp = xrealloc(dst->map->types, - src->map->size_types * sizeof(XkbKeyTypeRec)); + src->map->num_types * sizeof(XkbKeyTypeRec)); if (!tmp) return FALSE; dst->map->types = tmp; bzero(dst->map->types + - (dst->map->size_types * sizeof(XkbKeyTypeRec)), - (src->map->size_types - dst->map->size_types) * + (dst->map->num_types * sizeof(XkbKeyTypeRec)), + (src->map->num_types - dst->map->size_types) * sizeof(XkbKeyTypeRec)); } else { - tmp = xcalloc(src->map->size_types, sizeof(XkbKeyTypeRec)); + tmp = xcalloc(src->map->num_types, sizeof(XkbKeyTypeRec)); if (!tmp) return FALSE; dst->map->types = tmp; } } - 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; + else if (src->map->num_types < dst->map->num_types && + dst->map->types) { + for (i = src->map->num_types, dtype = (dst->map->types + i); + i < dst->map->num_types; i++, dtype++) { + if (dtype->level_names) + xfree(dtype->level_names); + dtype->level_names = NULL; + dtype->num_levels = 0; + if (dtype->map_count) { + if (dtype->map) + xfree(dtype->map); + if (dtype->preserve) + xfree(dtype->preserve); } } } @@ -1082,16 +1088,18 @@ XkbCopyKeymap(XkbDescPtr src, XkbDescPtr stype = src->map->types; dtype = dst->map->types; for (i = 0; i < src->map->num_types; i++, dtype++, stype++) { - if (stype->num_levels) { + if (stype->num_levels && stype->level_names) { if (stype->num_levels != dtype->num_levels && - dtype->num_levels && dtype->level_names) { + dtype->num_levels && dtype->level_names && + i < dst->map->num_types) { tmp = xrealloc(dtype->level_names, stype->num_levels * sizeof(Atom)); if (!tmp) continue; dtype->level_names = tmp; } - else if (!dtype->num_levels || !dtype->level_names) { + else if (!dtype->num_levels || !dtype->level_names || + i >= dst->map->num_types) { tmp = xalloc(stype->num_levels * sizeof(Atom)); if (!tmp) continue; @@ -1102,7 +1110,8 @@ XkbCopyKeymap(XkbDescPtr src, XkbDescPtr stype->num_levels * sizeof(Atom)); } else { - if (dtype->num_levels && dtype->level_names) + if (dtype->num_levels && dtype->level_names && + i < dst->map->num_types) xfree(dtype->level_names); dtype->num_levels = 0; dtype->level_names = NULL; @@ -1114,15 +1123,17 @@ XkbCopyKeymap(XkbDescPtr src, XkbDescPtr if (stype->map_count) { if (stype->map) { if (stype->map_count != dtype->map_count && - dtype->map_count && dtype->map) { + dtype->map_count && dtype->map && + i < dst->map->num_types) { tmp = xrealloc(dtype->map, stype->map_count * sizeof(XkbKTMapEntryRec)); if (!tmp) return FALSE; dtype->map = tmp; - } - else if (!dtype->map_count || !dtype->map) { + } + else if (!dtype->map_count || !dtype->map || + i >= dst->map->num_types) { tmp = xalloc(stype->map_count * sizeof(XkbKTMapEntryRec)); if (!tmp) @@ -1136,7 +1147,8 @@ XkbCopyKeymap(XkbDescPtr src, XkbDescPtr if (stype->preserve) { if (stype->map_count != dtype->map_count && - dtype->map_count && dtype->preserve) { + dtype->map_count && dtype->preserve && + i < dst->map->num_types) { tmp = xrealloc(dtype->preserve, stype->map_count * sizeof(XkbModsRec)); @@ -1144,7 +1156,8 @@ XkbCopyKeymap(XkbDescPtr src, XkbDescPtr return FALSE; dtype->preserve = tmp; } - else if (!dtype->preserve || !dtype->map_count) { + else if (!dtype->preserve || !dtype->map_count || + i >= dst->map->num_types) { tmp = xalloc(stype->map_count * sizeof(XkbModsRec)); if (!tmp) @@ -1179,14 +1192,14 @@ XkbCopyKeymap(XkbDescPtr src, XkbDescPtr xfree(dtype->level_names); if (dtype->map && dtype->map_count) xfree(dtype->map); - if (dtype->preserve && dtype->preserve) + if (dtype->preserve && dtype->map_count) xfree(dtype->preserve); } xfree(dst->map->types); dst->map->types = NULL; } } - dst->map->size_types = src->map->size_types; + dst->map->size_types = src->map->num_types; dst->map->num_types = src->map->num_types; if (src->map->modmap) { @@ -1957,7 +1970,7 @@ XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst->geom->num_key_aliases = dst->geom->sz_key_aliases; } else { - if (dst->geom->sz_key_aliases) { + if (dst->geom->sz_key_aliases && dst->geom->key_aliases) { xfree(dst->geom->key_aliases); dst->geom->key_aliases = NULL; } @@ -1967,13 +1980,16 @@ XkbCopyKeymap(XkbDescPtr src, XkbDescPtr /* font */ if (src->geom->label_font) { - if (strlen(src->geom->label_font) != + if (!dst->geom->label_font) { + tmp = xalloc(strlen(src->geom->label_font)); + if (!tmp) + return FALSE; + dst->geom->label_font = tmp; + } + else if (strlen(src->geom->label_font) != strlen(dst->geom->label_font)) { - if (dst->geom->label_font) - tmp = xrealloc(dst->geom->label_font, - strlen(src->geom->label_font)); - else - tmp = xalloc(strlen(src->geom->label_font)); + tmp = xrealloc(dst->geom->label_font, + strlen(src->geom->label_font)); if (!tmp) return FALSE; dst->geom->label_font = tmp;