From a8ea7a1d3daa7bdcb877615ae0a252c189153bd2 Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Mon, 26 Jun 2017 16:45:16 +0100 Subject: parser: Don't set more maps when we don't have any If the scanner indicates that we might have something which looks like a map, but the parser in fact fails to create that map, we will try to access the map regardless. Stop doing that. testcase: 'xkb_keymap {' -> '#kb_keymap' Signed-off-by: Daniel Stone --- src/xkbcomp/parser.y | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/xkbcomp/parser.y b/src/xkbcomp/parser.y index b555bc2..296ce19 100644 --- a/src/xkbcomp/parser.y +++ b/src/xkbcomp/parser.y @@ -239,9 +239,9 @@ resolve_keysym(const char *name, xkb_keysym_t *sym_rtrn) */ XkbFile : XkbCompositeMap - { $$ = param->rtrn = $1; param->more_maps = true; } + { $$ = param->rtrn = $1; param->more_maps = !!param->rtrn; } | XkbMapConfig - { $$ = param->rtrn = $1; param->more_maps = true; YYACCEPT; } + { $$ = param->rtrn = $1; param->more_maps = !!param->rtrn; YYACCEPT; } | END_OF_FILE { $$ = param->rtrn = NULL; param->more_maps = false; } ; @@ -772,6 +772,7 @@ parse(struct xkb_context *ctx, struct scanner *scanner, const char *map) .scanner = scanner, .ctx = ctx, .rtrn = NULL, + .more_maps = false, }; /* -- cgit v1.2.1 From 96df3106d49438e442510c59acad306e94f3db4d Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Mon, 26 Jun 2017 17:12:29 +0100 Subject: xkbcomp: Don't crash on no-op modmask expressions If we have an expression of the form 'l1' in an interp section, we unconditionally try to dereference its args, even if it has none. Signed-off-by: Daniel Stone --- src/xkbcomp/compat.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/xkbcomp/compat.c b/src/xkbcomp/compat.c index 9ae26cd..bd587c8 100644 --- a/src/xkbcomp/compat.c +++ b/src/xkbcomp/compat.c @@ -264,7 +264,8 @@ ResolveStateAndPredicate(ExprDef *expr, enum xkb_match_operation *pred_rtrn, *pred_rtrn = MATCH_EXACTLY; if (expr->expr.op == EXPR_ACTION_DECL) { const char *pred_txt = xkb_atom_text(info->ctx, expr->action.name); - if (!LookupString(symInterpretMatchMaskNames, pred_txt, pred_rtrn)) { + if (!LookupString(symInterpretMatchMaskNames, pred_txt, pred_rtrn) || + !expr->action.args) { log_err(info->ctx, "Illegal modifier predicate \"%s\"; Ignored\n", pred_txt); return false; -- cgit v1.2.1 From 4e2ee9c3f6050d773f8bbe05bc0edb17f1ff8371 Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Mon, 26 Jun 2017 17:18:16 +0100 Subject: xkbcomp: Don't explode on invalid virtual modifiers testcase: 'virtualModifiers=LevelThreC' Signed-off-by: Daniel Stone --- src/xkbcomp/expr.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/xkbcomp/expr.c b/src/xkbcomp/expr.c index 5d43cba..91713da 100644 --- a/src/xkbcomp/expr.c +++ b/src/xkbcomp/expr.c @@ -101,6 +101,8 @@ LookupModMask(struct xkb_context *ctx, const void *priv, xkb_atom_t field, return false; str = xkb_atom_text(ctx, field); + if (!str) + return false; if (istreq(str, "all")) { *val_rtrn = MOD_REAL_MASK_ALL; -- cgit v1.2.1 From 38e1766bc6e20108948aec8a0b222a4bad0254e9 Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Mon, 26 Jun 2017 17:21:45 +0100 Subject: xkbcomp: Don't falsely promise from ExprResolveLhs Every user of ExprReturnLhs goes on to unconditionally dereference the field return, which can be NULL if xkb_intern_atom fails. Return false if this is the case, so we fail safely. testcase: splice geometry data into interp Signed-off-by: Daniel Stone --- src/xkbcomp/expr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xkbcomp/expr.c b/src/xkbcomp/expr.c index 91713da..b5ab717 100644 --- a/src/xkbcomp/expr.c +++ b/src/xkbcomp/expr.c @@ -42,7 +42,7 @@ ExprResolveLhs(struct xkb_context *ctx, const ExprDef *expr, *elem_rtrn = NULL; *field_rtrn = xkb_atom_text(ctx, expr->ident.ident); *index_rtrn = NULL; - return true; + return (*field_rtrn != NULL); case EXPR_FIELD_REF: *elem_rtrn = xkb_atom_text(ctx, expr->field_ref.element); *field_rtrn = xkb_atom_text(ctx, expr->field_ref.field); -- cgit v1.2.1 From ae7856db48be161cb336c44fd188253bc06dd5ae Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Mon, 26 Jun 2017 21:38:52 +0100 Subject: text: NULL-terminate SI mask names The list should have a NULL sentry. Add one. testcase: 'interpret KP_Delete+AnyOfOrNaneo(ll)' Signed-off-by: Daniel Stone --- src/text.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/text.c b/src/text.c index ec8bdf8..1a44de4 100644 --- a/src/text.c +++ b/src/text.c @@ -204,6 +204,7 @@ const LookupEntry symInterpretMatchMaskNames[] = { { "AnyOf", MATCH_ANY }, { "AllOf", MATCH_ALL }, { "Exactly", MATCH_EXACTLY }, + { NULL, 0 }, }; const char * -- cgit v1.2.1 From 4fcbc47059aa6c714fa87bc24115edcad86ca5bb Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Mon, 26 Jun 2017 21:49:49 +0100 Subject: darray: Don't call memcpy() on NULL The only time we could ever hit this was with count == 0, which seems unnecessarily pedantic. But OK. Signed-off-by: Daniel Stone --- src/darray.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/darray.h b/src/darray.h index e9da974..c30fd7d 100644 --- a/src/darray.h +++ b/src/darray.h @@ -104,7 +104,8 @@ typedef darray (unsigned long) darray_ulong; #define darray_from_items(arr, items, count) do { \ unsigned __count = (count); \ darray_resize(arr, __count); \ - memcpy((arr).item, items, __count * sizeof(*(arr).item)); \ + if (count != 0) \ + memcpy((arr).item, items, __count * sizeof(*(arr).item)); \ } while (0) #define darray_copy(arr_to, arr_from) \ -- cgit v1.2.1 From 5440aaa5222b02275b4fd982f5326c92c072982b Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Mon, 26 Jun 2017 21:52:27 +0100 Subject: Fix signed vs. unsigned confusion in name sanitisation Don't try to divide through a signed char when indexing an array, lest ye try to index off the start of it. Signed-off-by: Daniel Stone --- src/keymap-priv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/keymap-priv.c b/src/keymap-priv.c index 08945ca..fffb2fd 100644 --- a/src/keymap-priv.c +++ b/src/keymap-priv.c @@ -118,7 +118,8 @@ XkbEscapeMapName(char *name) return; while (*name) { - if (!(legal[*name / 8] & (1 << (*name % 8)))) + unsigned char c = *name; + if (!(legal[c / 8] & (1 << (c % 8)))) *name = '_'; name++; } -- cgit v1.2.1 From bb4909d2d8fa6b08155e449986a478101e2b2634 Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Mon, 30 Oct 2017 11:21:55 +0000 Subject: Fail expression lookup on invalid atoms If we fail atom lookup, then we should not claim that we successfully looked up the expression. Signed-off-by: Daniel Stone --- src/xkbcomp/expr.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/xkbcomp/expr.c b/src/xkbcomp/expr.c index b5ab717..b2567de 100644 --- a/src/xkbcomp/expr.c +++ b/src/xkbcomp/expr.c @@ -47,11 +47,15 @@ ExprResolveLhs(struct xkb_context *ctx, const ExprDef *expr, *elem_rtrn = xkb_atom_text(ctx, expr->field_ref.element); *field_rtrn = xkb_atom_text(ctx, expr->field_ref.field); *index_rtrn = NULL; - return true; + return (*elem_rtrn != NULL && *field_rtrn != NULL); case EXPR_ARRAY_REF: *elem_rtrn = xkb_atom_text(ctx, expr->array_ref.element); *field_rtrn = xkb_atom_text(ctx, expr->array_ref.field); *index_rtrn = expr->array_ref.entry; + if (expr->array_ref.element != XKB_ATOM_NONE && *elem_rtrn == NULL) + return false; + if (*field_rtrn == NULL) + return false; return true; default: break; -- cgit v1.2.1