From 7ec00933c178942b04f4716882132f7971db7d26 Mon Sep 17 00:00:00 2001 From: Ran Benita Date: Sat, 26 Jul 2014 22:34:05 +0300 Subject: [PATCH] parser: don't leak AST nodes for discarded symbols If the parser has symbols on the stack, and then enters an error, it discards the symbols and fails. But their actions which allocate AST nodes had already ran. So we must free these to avoid leaks. We use %destructor declarations, see http://www.gnu.org/software/bison/manual/html_node/Destructor-Decl.html Note: byacc only supports %destructor when compiled with --enable-btyacc. Also, it doesn't support using the parse-param in the destructor. So we might revert this commit before the next release, or forget about byacc. https://github.com/xkbcommon/libxkbcommon/issues/8 Signed-off-by: Ran Benita --- src/xkbcomp/parser.y | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/xkbcomp/parser.y b/src/xkbcomp/parser.y index ad1a27b..1c212bb 100644 --- a/src/xkbcomp/parser.y +++ b/src/xkbcomp/parser.y @@ -216,6 +216,14 @@ resolve_keysym(const char *name, xkb_keysym_t *sym_rtrn) %type XkbFile XkbMapConfigList XkbMapConfig %type XkbCompositeMap +%destructor { FreeStmt((ParseCommon *) $$); } + + +/* The destructor also runs on the start symbol when the parser *succeeds*. + * The `if` here catches this case. */ +%destructor { if (!param->rtrn) FreeXkbFile($$); } +%destructor { free($$); } + %% /* @@ -770,6 +778,7 @@ parse(struct xkb_context *ctx, struct scanner *scanner, const char *map) struct parser_param param = { .scanner = scanner, .ctx = ctx, + .rtrn = NULL, }; /* @@ -799,6 +808,7 @@ parse(struct xkb_context *ctx, struct scanner *scanner, const char *map) FreeXkbFile(param.rtrn); } } + param.rtrn = NULL; } if (ret != 0) {