keysym: properly handle overflow in 0x keysym names
Relatedly, strtoul allows a lot of unwanted stuff (spaces, +/- sign, thousand seperators), we really ought not use it. But that's for another time. Signed-off-by: Ran Benita <ran@unusedvar.com>master
parent
1638409b22
commit
1c0e28ad26
16
src/keysym.c
16
src/keysym.c
|
@ -96,7 +96,7 @@ xkb_keysym_from_name(const char *name, enum xkb_keysym_flags flags)
|
|||
{
|
||||
const struct name_keysym *entry = NULL;
|
||||
char *tmp;
|
||||
xkb_keysym_t val;
|
||||
unsigned long val;
|
||||
bool icase = (flags & XKB_KEYSYM_CASE_INSENSITIVE);
|
||||
|
||||
if (flags & ~XKB_KEYSYM_CASE_INSENSITIVE)
|
||||
|
@ -174,24 +174,28 @@ xkb_keysym_from_name(const char *name, enum xkb_keysym_flags flags)
|
|||
}
|
||||
|
||||
if (*name == 'U' || (icase && *name == 'u')) {
|
||||
errno = 0;
|
||||
val = strtoul(&name[1], &tmp, 16);
|
||||
if (tmp && *tmp != '\0')
|
||||
if ((tmp && *tmp != '\0') || errno != 0)
|
||||
return XKB_KEY_NoSymbol;
|
||||
|
||||
if (val < 0x20 || (val > 0x7e && val < 0xa0))
|
||||
return XKB_KEY_NoSymbol;
|
||||
if (val < 0x100)
|
||||
return val;
|
||||
return (xkb_keysym_t) val;
|
||||
if (val > 0x10ffff)
|
||||
return XKB_KEY_NoSymbol;
|
||||
return val | 0x01000000;
|
||||
return (xkb_keysym_t) val | 0x01000000;
|
||||
}
|
||||
else if (name[0] == '0' && (name[1] == 'x' || (icase && name[1] == 'X'))) {
|
||||
errno = 0;
|
||||
val = strtoul(&name[2], &tmp, 16);
|
||||
if (tmp && *tmp != '\0')
|
||||
if ((tmp && *tmp != '\0') || errno != 0)
|
||||
return XKB_KEY_NoSymbol;
|
||||
if (val > UINT32_MAX)
|
||||
return XKB_KEY_NoSymbol;
|
||||
|
||||
return val;
|
||||
return (xkb_keysym_t) val;
|
||||
}
|
||||
|
||||
/* Stupid inconsistency between the headers and XKeysymDB: the former has
|
||||
|
|
|
@ -145,6 +145,10 @@ main(void)
|
|||
assert(test_string("THORN", 0x00de));
|
||||
assert(test_string("Thorn", 0x00de));
|
||||
assert(test_string("thorn", 0x00fe));
|
||||
/* Max keysym. */
|
||||
assert(test_string("0xffffffff", 0xffffffff));
|
||||
/* Outside range. */
|
||||
assert(test_string("0x100000000", XKB_KEY_NoSymbol));
|
||||
|
||||
assert(test_keysym(0x1008FF56, "XF86Close"));
|
||||
assert(test_keysym(0x0, "NoSymbol"));
|
||||
|
|
Loading…
Reference in New Issue