Commit cc5588c65b504c8815e3fc56bec90b6d9ae3db24

Daniel Stone 2012-03-29T17:39:11

Fail gracefully on failure to find component include If we can't find the component of the include file we're looking for, make sure we don't return success when we meant failure, segfault, or spectacularly leak everything. Tested with incorrect component includes for keycodes, compat, symbols, and types. Signed-off-by: Daniel Stone <daniel@fooishbar.org> Reported-by: David Herrmann <dh.herrmann@googlemail.com>

diff --git a/src/malloc.c b/src/malloc.c
index f63cf2c..80ebc69 100644
--- a/src/malloc.c
+++ b/src/malloc.c
@@ -346,10 +346,12 @@ XkbcFreeClientMap(struct xkb_desc * xkb)
     }
     free(map->types);
 
-    for (key = xkb->min_key_code; key < xkb->max_key_code; key++) {
-        free(map->key_sym_map[key].sym_index);
-        free(map->key_sym_map[key].num_syms);
-        free(map->key_sym_map[key].syms);
+    if (map->key_sym_map) {
+        for (key = xkb->min_key_code; key < xkb->max_key_code; key++) {
+            free(map->key_sym_map[key].sym_index);
+            free(map->key_sym_map[key].num_syms);
+            free(map->key_sym_map[key].syms);
+        }
     }
     free(map->key_sym_map);
 
diff --git a/src/xkbcomp/keymap.c b/src/xkbcomp/keymap.c
index df6fd36..3518902 100644
--- a/src/xkbcomp/keymap.c
+++ b/src/xkbcomp/keymap.c
@@ -46,7 +46,7 @@ CompileKeymap(struct xkb_context *context, XkbFile *file, unsigned merge)
     unsigned required, legal;
     unsigned mainType;
     const char *mainName;
-    LEDInfo *unbound = NULL;
+    LEDInfo *unbound = NULL, *next;
     struct xkb_desc *xkb = XkbcAllocKeyboard(context);
     struct {
         XkbFile *keycodes;
@@ -159,25 +159,25 @@ CompileKeymap(struct xkb_context *context, XkbFile *file, unsigned merge)
     }
 
     /* compile the sections we have in the file one-by-one, or fail. */
-    if (sections.keycodes != NULL &&
+    if (sections.keycodes == NULL ||
         !CompileKeycodes(sections.keycodes, xkb, MergeOverride))
     {
         ERROR("Failed to compile keycodes\n");
         goto err;
     }
-    if (sections.types != NULL &&
+    if (sections.types == NULL ||
         !CompileKeyTypes(sections.types, xkb, MergeOverride))
     {
         ERROR("Failed to compile key types\n");
         goto err;
     }
-    if (sections.compat != NULL &&
+    if (sections.compat == NULL ||
         !CompileCompatMap(sections.compat, xkb, MergeOverride, &unbound))
     {
         ERROR("Failed to compile compat map\n");
         goto err;
     }
-    if (sections.symbols != NULL &&
+    if (sections.symbols == NULL ||
         !CompileSymbols(sections.symbols, xkb, MergeOverride))
     {
         ERROR("Failed to compile symbols\n");
@@ -200,5 +200,10 @@ err:
     ACTION("Failed to compile keymap\n");
     if (xkb)
         xkb_map_unref(xkb);
+    while (unbound) {
+        next = (LEDInfo *) unbound->defs.next;
+        free(unbound);
+        unbound = next;
+    }
     return NULL;
 }
diff --git a/src/xkbcomp/symbols.c b/src/xkbcomp/symbols.c
index dfced04..9605324 100644
--- a/src/xkbcomp/symbols.c
+++ b/src/xkbcomp/symbols.c
@@ -954,10 +954,15 @@ HandleIncludeSymbols(IncludeStmt * stmt,
             else
             {
                 info->errorCount += 10;
+                FreeSymbolsInfo(&included);
                 return False;
             }
         }
     }
+    else if (stmt->next)
+    {
+        info->errorCount += included.errorCount;
+    }
     if (haveSelf)
         *info = included;
     else
@@ -2183,7 +2188,7 @@ CompileSymbols(XkbFile *file, struct xkb_desc * xkb, unsigned merge)
 
     if (info.nKeys == 0) {
         FreeSymbolsInfo(&info);
-        return True;
+        return False;
     }
 
     if (info.errorCount == 0)