types: refactor CopyKeyTypesToKeymap So it's OOM-safe and doesn't clobber keymap on failure. Signed-off-by: Ran Benita <ran234@gmail.com>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
diff --git a/src/xkbcomp/types.c b/src/xkbcomp/types.c
index fd62dba..f8d7e7f 100644
--- a/src/xkbcomp/types.c
+++ b/src/xkbcomp/types.c
@@ -673,23 +673,20 @@ HandleKeyTypesFile(KeyTypesInfo *info, XkbFile *file, enum merge_mode merge)
static bool
CopyKeyTypesToKeymap(struct xkb_keymap *keymap, KeyTypesInfo *info)
{
- keymap->types_section_name = strdup_safe(info->name);
- XkbEscapeMapName(keymap->types_section_name);
-
- keymap->mods = info->mods;
+ unsigned num_types;
+ struct xkb_key_type *types;
- keymap->num_types = darray_size(info->types);
- if (keymap->num_types == 0)
- keymap->num_types = 1;
-
- keymap->types = calloc(keymap->num_types, sizeof(*keymap->types));
+ num_types = darray_empty(info->types) ? 1 : darray_size(info->types);
+ types = calloc(num_types, sizeof(*types));
+ if (!types)
+ return false;
/*
* If no types were specified, a default unnamed one-level type is
* used for all keys.
*/
if (darray_empty(info->types)) {
- struct xkb_key_type *type = &keymap->types[0];
+ struct xkb_key_type *type = &types[0];
type->mods.mods = 0;
type->num_levels = 1;
@@ -697,24 +694,28 @@ CopyKeyTypesToKeymap(struct xkb_keymap *keymap, KeyTypesInfo *info)
type->num_entries = 0;
type->name = xkb_atom_intern_literal(keymap->ctx, "default");
type->level_names = NULL;
-
- return true;
}
-
- for (unsigned i = 0; i < keymap->num_types; i++) {
- KeyTypeInfo *def = &darray_item(info->types, i);
- struct xkb_key_type *type = &keymap->types[i];
-
- type->mods.mods = def->mods;
- type->num_levels = def->num_levels;
- type->entries = darray_mem(def->entries, 0);
- type->num_entries = darray_size(def->entries);
- darray_init(def->entries);
- type->name = def->name;
- type->level_names = darray_mem(def->level_names, 0);
- darray_init(def->level_names);
+ else {
+ for (unsigned i = 0; i < num_types; i++) {
+ KeyTypeInfo *def = &darray_item(info->types, i);
+ struct xkb_key_type *type = &types[i];
+
+ type->mods.mods = def->mods;
+ type->num_levels = def->num_levels;
+ type->entries = darray_mem(def->entries, 0);
+ type->num_entries = darray_size(def->entries);
+ darray_init(def->entries);
+ type->name = def->name;
+ type->level_names = darray_mem(def->level_names, 0);
+ darray_init(def->level_names);
+ }
}
+ keymap->types_section_name = strdup_safe(info->name);
+ XkbEscapeMapName(keymap->types_section_name);
+ keymap->num_types = num_types;
+ keymap->types = types;
+ keymap->mods = info->mods;
return true;
}