summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRan Benita <ran234@gmail.com>2014-07-26 22:34:05 +0300
committerRan Benita <ran234@gmail.com>2014-07-26 22:46:01 +0300
commit7ec00933c178942b04f4716882132f7971db7d26 (patch)
tree1921e2917351694f2f7357eb05158712ea8adf89
parentf5182bbd7415bfa99d78a7865d67a56f770447a0 (diff)
downloadlibxkbcommon-7ec00933c178942b04f4716882132f7971db7d26.tar.gz
libxkbcommon-7ec00933c178942b04f4716882132f7971db7d26.tar.bz2
libxkbcommon-7ec00933c178942b04f4716882132f7971db7d26.zip
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 <ran234@gmail.com>
-rw-r--r--src/xkbcomp/parser.y10
1 files changed, 10 insertions, 0 deletions
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 <file> XkbFile XkbMapConfigList XkbMapConfig
%type <file> XkbCompositeMap
+%destructor { FreeStmt((ParseCommon *) $$); }
+ <any> <expr> <var> <vmod> <interp> <keyType> <syms> <modMask> <groupCompat>
+ <ledMap> <ledName> <keyCode> <keyAlias>
+/* The destructor also runs on the start symbol when the parser *succeeds*.
+ * The `if` here catches this case. */
+%destructor { if (!param->rtrn) FreeXkbFile($$); } <file>
+%destructor { free($$); } <str>
+
%%
/*
@@ -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) {