Commit 26453b84732da870f5695ee347970b337cfea9c1

Ran Benita 2017-12-12T14:30:21

keymap: fix NULL dereference when dumping the default fallback type The default fallback type uses type->level_names = NULL but the keymap-dump code was not checking this case. Instead of adding more workarounds and possible bugs (e.g. previous commit), let's just keep the number of level names separately. This has the additional advantage retains extraneous level name if someone adds them for some reason. Signed-off-by: Ran Benita <ran234@gmail.com>

diff --git a/src/keymap.h b/src/keymap.h
index 1093e47..c15052b 100644
--- a/src/keymap.h
+++ b/src/keymap.h
@@ -253,6 +253,7 @@ struct xkb_key_type {
     xkb_atom_t name;
     struct xkb_mods mods;
     xkb_level_index_t num_levels;
+    unsigned int num_level_names;
     xkb_atom_t *level_names;
     unsigned int num_entries;
     struct xkb_key_type_entry *entries;
diff --git a/src/xkbcomp/keymap-dump.c b/src/xkbcomp/keymap-dump.c
index d05a410..2ed591c 100644
--- a/src/xkbcomp/keymap-dump.c
+++ b/src/xkbcomp/keymap-dump.c
@@ -228,7 +228,7 @@ write_types(struct xkb_keymap *keymap, struct buf *buf)
                                            entry->preserve.mods));
         }
 
-        for (xkb_level_index_t n = 0; n < type->num_levels; n++)
+        for (xkb_level_index_t n = 0; n < type->num_level_names; n++)
             if (type->level_names[n])
                 write_buf(buf, "\t\tlevel_name[Level%u]= \"%s\";\n", n + 1,
                           xkb_atom_text(keymap->ctx, type->level_names[n]));
diff --git a/src/xkbcomp/types.c b/src/xkbcomp/types.c
index 4696086..e85b67e 100644
--- a/src/xkbcomp/types.c
+++ b/src/xkbcomp/types.c
@@ -693,6 +693,7 @@ CopyKeyTypesToKeymap(struct xkb_keymap *keymap, KeyTypesInfo *info)
         type->num_entries = 0;
         type->name = xkb_atom_intern_literal(keymap->ctx, "default");
         type->level_names = NULL;
+        type->num_level_names = 0;
     }
     else {
         for (unsigned i = 0; i < num_types; i++) {
@@ -702,10 +703,8 @@ CopyKeyTypesToKeymap(struct xkb_keymap *keymap, KeyTypesInfo *info)
             type->name = def->name;
             type->mods.mods = def->mods;
             type->num_levels = def->num_levels;
-            darray_steal(def->level_names,
-                         &type->level_names, NULL);
-            darray_steal(def->entries,
-                         &type->entries, &type->num_entries);
+            darray_steal(def->level_names, &type->level_names, &type->num_level_names);
+            darray_steal(def->entries, &type->entries, &type->num_entries);
         }
     }