Fix memory leaks in key types compilation When there is no error the types are “stolen” and copied to the keymap. But when there is an error, `MergeIncludedKeyTypes` just return without “stealing” nor freeing the types. Fixed by explicitly freeing the key types. Fixed another leak in `HandleKeyTypeDef` that may occur if there is an error in parsing a type definition.
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
diff --git a/src/xkbcomp/types.c b/src/xkbcomp/types.c
index 34e1028..183aa50 100644
--- a/src/xkbcomp/types.c
+++ b/src/xkbcomp/types.c
@@ -118,6 +118,9 @@ static void
ClearKeyTypesInfo(KeyTypesInfo *info)
{
free(info->name);
+ KeyTypeInfo *type;
+ darray_foreach(type, info->types)
+ ClearKeyTypeInfo(type);
darray_free(info->types);
}
@@ -192,6 +195,7 @@ MergeIncludedKeyTypes(KeyTypesInfo *into, KeyTypesInfo *from,
if (darray_empty(into->types)) {
into->types = from->types;
+ /* Types stolen via shallow copy, so reinitialize the array */
darray_init(from->types);
}
else {
@@ -201,6 +205,9 @@ MergeIncludedKeyTypes(KeyTypesInfo *into, KeyTypesInfo *from,
if (!AddKeyType(into, type, false))
into->errorCount++;
}
+ /* Types were either shallow copied or reinitialized individually
+ in `AddKeyType`, so we only need to free the array */
+ darray_free(from->types);
}
}
@@ -630,16 +637,16 @@ HandleKeyTypeDef(KeyTypesInfo *info, KeyTypeDef *def, enum merge_mode merge)
.level_names = darray_new(),
};
- if (!HandleKeyTypeBody(info, def->body, &type)) {
- info->errorCount++;
- return false;
- }
-
- if (!AddKeyType(info, &type, true)) {
+ if (!HandleKeyTypeBody(info, def->body, &type) ||
+ !AddKeyType(info, &type, true))
+ {
info->errorCount++;
+ ClearKeyTypeInfo(&type);
return false;
}
+ /* Type has been either stolen via shallow copy or reinitialized in
+ `AddKeyType`: no need to free the arrays */
return true;
}