xkbcomp: where a keysym cannot be resolved, set it to NoSymbol

Where resolve_keysym fails we warn but use the otherwise uninitialized variable
as our keysym. That later ends up in the keymap as random garbage hex value.

Simplest test case, set this in the 'us' keymap:
    key <TLDE>               {      [        xyz ] };

And without this patch we get random garbage:
./build/xkbcli-compile-keymap --layout us | grep TLDE:
    key <TLDE>               {      [      0x018a5cf0 ] };

With this patch, we now get NoSymbol:
./build/xkbcli-compile-keymap --layout us | grep TLDE:
    key <TLDE>               {      [        NoSymbol ] };
master
Peter Hutterer 2020-10-19 10:49:37 +10:00
parent 21e640fbc7
commit afdc9ceee7
3 changed files with 71 additions and 3 deletions

View File

@ -726,8 +726,10 @@ KeySyms : OBRACE KeySymList CBRACE
KeySym : IDENT
{
if (!resolve_keysym($1, &$$))
if (!resolve_keysym($1, &$$)) {
parser_warn(param, "unrecognized keysym \"%s\"", $1);
$$ = XKB_KEY_NoSymbol;
}
free($1);
}
| SECTION { $$ = XKB_KEY_section; }

14
test/data/symbols/garbage Normal file
View File

@ -0,0 +1,14 @@
default alphanumeric_keys
xkb_symbols "garbage" {
include "us"
name[Group1]= "My garbage Layout";
// The garbage keysym will *not* override the corresponding symbol from the
// 'us' layout
key <TLDE> { [ keysym_is_garbage, exclam ] };
// AE13 is unused by 'us', use it to avoid fallback to the 'us' definition.
// Define with 2 levels but first level is a garbage symbol.
key <AE13> { [ keysym_is_garbage, asciitilde ] };
};

View File

@ -31,8 +31,51 @@
#include "test.h"
int
main(void)
static void
test_garbage_key(void)
{
struct xkb_context *context = test_get_context(0);
struct xkb_keymap *keymap;
xkb_keycode_t kc;
int nsyms;
const xkb_keysym_t *syms;
const xkb_layout_index_t first_layout = 0;
xkb_level_index_t nlevels;
assert(context);
keymap = test_compile_rules(context, NULL, NULL, "garbage", NULL, NULL);
assert(keymap);
/* TLDE uses the 'us' sym on the first level and is thus [grave, exclam] */
kc = xkb_keymap_key_by_name(keymap, "TLDE");
assert(kc != XKB_KEYCODE_INVALID);
nlevels = xkb_keymap_num_levels_for_key(keymap, kc, first_layout);
assert(nlevels == 2);
nsyms = xkb_keymap_key_get_syms_by_level(keymap, kc, first_layout, 0, &syms);
assert(nsyms == 1);
assert(*syms == XKB_KEY_grave); /* fallback from 'us' */
nsyms = xkb_keymap_key_get_syms_by_level(keymap, kc, first_layout, 1, &syms);
assert(nsyms == 1);
assert(*syms == XKB_KEY_exclam);
/* AE13 has no 'us' fallback and ends up as [NoSymbol, asciitilde] */
kc = xkb_keymap_key_by_name(keymap, "AE13");
assert(kc != XKB_KEYCODE_INVALID);
nlevels = xkb_keymap_num_levels_for_key(keymap, kc, first_layout);
assert(nlevels == 2);
nsyms = xkb_keymap_key_get_syms_by_level(keymap, kc, first_layout, 0, &syms);
assert(nsyms == 0);
nsyms = xkb_keymap_key_get_syms_by_level(keymap, kc, first_layout, 1, &syms);
assert(nsyms == 1);
assert(*syms == XKB_KEY_asciitilde);
xkb_keymap_unref(keymap);
xkb_context_unref(context);
}
static void
test_keymap(void)
{
struct xkb_context *context = test_get_context(0);
struct xkb_keymap *keymap;
@ -105,3 +148,12 @@ main(void)
xkb_keymap_unref(keymap);
xkb_context_unref(context);
}
int
main(void)
{
test_garbage_key();
test_keymap();
return 0;
}