diff options
| author | Daniel Friesel <derf@finalrewind.org> | 2017-08-10 20:37:06 +0200 | 
|---|---|---|
| committer | Daniel Friesel <derf@finalrewind.org> | 2017-08-10 20:37:06 +0200 | 
| commit | b7cf37bcd0e6480a6a80246725dc84ec290bde9b (patch) | |
| tree | 4e8ee4e64014adaebc3dbe4a80fd825d47229fa7 | |
| parent | 0c5ed69263a38b0b9188c83633bd1f48f65df396 (diff) | |
Fix segfault in feh_event_handle_keypress for certain key inputs
Turns out that it is undefined behaviour to pass a value to isctype functions
which does not fit inside a char. Closes #312
| -rw-r--r-- | src/keyevents.c | 13 | 
1 files changed, 11 insertions, 2 deletions
| diff --git a/src/keyevents.c b/src/keyevents.c index 3932804..1905ea5 100644 --- a/src/keyevents.c +++ b/src/keyevents.c @@ -42,6 +42,15 @@ static void feh_set_kb(fehkey *key, unsigned int s0, unsigned int y0, unsigned  	key->keysyms[2] = y2;  } +static inline int ignore_space(int keysym) { +	/* +	 * Passing values which do not find inside a signed 8bit char to isprint, +	 * isspace and the likes is undefined behaviour... which glibc (for some +	 * values) implements as a segmentation fault. So let's not do that. +	 */ +	return ((keysym <= 127) && (keysym >= -128) && isprint(keysym) && !isspace(keysym)); +} +  static void feh_set_parse_kb_partial(fehkey *key, int index, char *ks) {  	char *cur = ks;  	int mod = 0; @@ -73,7 +82,7 @@ static void feh_set_parse_kb_partial(fehkey *key, int index, char *ks) {  	}  	key->keysyms[index] = XStringToKeysym(cur); -	if (isprint(key->keysyms[index]) && !isspace(key->keysyms[index])) +	if (ignore_space(key->keysyms[index]))  		mod &= ~ShiftMask;  	key->keystates[index] = mod; @@ -278,7 +287,7 @@ void feh_event_handle_keypress(XEvent * ev)  	XLookupString(&ev->xkey, (char *) kbuf, sizeof(kbuf), &keysym, NULL);  	state = kev->state & (ControlMask | ShiftMask | Mod1Mask | Mod4Mask); -	if (isprint(keysym) && !isspace(keysym)) +	if (ignore_space(keysym))  		state &= ~ShiftMask;  	/* menus are showing, so this is a menu control keypress */ | 
