1
0
mirror of https://github.com/irssi/irssi.git synced 2024-11-03 04:27:19 -05:00

Merge pull request #294 from dequis/key-states-rescan-recursion-limit

Limit recursion depth of key/combo expansion in key_states_scan()
This commit is contained in:
dx 2015-10-02 07:22:48 -03:00
commit c3e4664870

View File

@ -31,6 +31,8 @@
#include "fe-windows.h" #include "fe-windows.h"
#include "printtext.h" #include "printtext.h"
#define MAX_EXPAND_RECURSION 100
GSList *keyinfos; GSList *keyinfos;
static GHashTable *keys, *default_keys; static GHashTable *keys, *default_keys;
@ -171,7 +173,7 @@ KEYINFO_REC *key_info_find(const char *id)
return NULL; return NULL;
} }
static int expand_key(const char *key, GSList **out); static int expand_key(const char *key, GSList **out, int *limit);
#define expand_out_char(out, c) \ #define expand_out_char(out, c) \
{ \ { \
@ -188,13 +190,17 @@ static int expand_key(const char *key, GSList **out);
g_slist_free(out); out = NULL; \ g_slist_free(out); out = NULL; \
} }
static int expand_combo(const char *start, const char *end, GSList **out) static int expand_combo(const char *start, const char *end, GSList **out, int *limit)
{ {
KEY_REC *rec; KEY_REC *rec;
KEYINFO_REC *info; KEYINFO_REC *info;
GSList *tmp, *tmp2, *list, *copy, *newout; GSList *tmp, *tmp2, *list, *copy, *newout;
char *str, *p; char *str, *p;
if ((*limit)-- < 0) {
return FALSE;
}
if (start == end) { if (start == end) {
/* single key */ /* single key */
expand_out_char(*out, *start); expand_out_char(*out, *start);
@ -229,7 +235,7 @@ static int expand_combo(const char *start, const char *end, GSList **out)
/* only one way to generate the combo, good */ /* only one way to generate the combo, good */
rec = list->data; rec = list->data;
g_slist_free(list); g_slist_free(list);
return expand_key(rec->key, out); return expand_key(rec->key, out, limit);
} }
/* multiple ways to generate the combo - /* multiple ways to generate the combo -
@ -244,7 +250,11 @@ static int expand_combo(const char *start, const char *end, GSList **out)
copy = g_slist_append(copy, g_string_new(str->str)); copy = g_slist_append(copy, g_string_new(str->str));
} }
if (!expand_key(rec->key, &copy)) { if (!expand_key(rec->key, &copy, limit)) {
if (*limit < 0) {
return FALSE;
}
/* illegal key combo, remove from list */ /* illegal key combo, remove from list */
expand_out_free(copy); expand_out_free(copy);
} else { } else {
@ -254,7 +264,11 @@ static int expand_combo(const char *start, const char *end, GSList **out)
rec = list->data; rec = list->data;
g_slist_free(list); g_slist_free(list);
if (!expand_key(rec->key, out)) { if (!expand_key(rec->key, out, limit)) {
if (*limit < 0) {
return FALSE;
}
/* illegal key combo, remove from list */ /* illegal key combo, remove from list */
expand_out_free(*out); expand_out_free(*out);
} }
@ -264,12 +278,16 @@ static int expand_combo(const char *start, const char *end, GSList **out)
} }
/* Expand key code - returns TRUE if successful. */ /* Expand key code - returns TRUE if successful. */
static int expand_key(const char *key, GSList **out) static int expand_key(const char *key, GSList **out, int *limit)
{ {
GSList *tmp; GSList *tmp;
const char *start; const char *start;
int last_hyphen; int last_hyphen;
if ((*limit)-- < 0) {
return FALSE;
}
/* meta-^W^Gf -> ^[-^W-^G-f */ /* meta-^W^Gf -> ^[-^W-^G-f */
start = NULL; last_hyphen = TRUE; start = NULL; last_hyphen = TRUE;
for (; *key != '\0'; key++) { for (; *key != '\0'; key++) {
@ -279,7 +297,7 @@ static int expand_key(const char *key, GSList **out)
continue; continue;
} }
if (!expand_combo(start, key-1, out)) if (!expand_combo(start, key-1, out, limit))
return FALSE; return FALSE;
expand_out_char(*out, '-'); expand_out_char(*out, '-');
start = NULL; start = NULL;
@ -332,7 +350,7 @@ static int expand_key(const char *key, GSList **out)
} }
if (start != NULL) if (start != NULL)
return expand_combo(start, key-1, out); return expand_combo(start, key-1, out, limit);
for (tmp = *out; tmp != NULL; tmp = tmp->next) { for (tmp = *out; tmp != NULL; tmp = tmp->next) {
GString *str = tmp->data; GString *str = tmp->data;
@ -346,12 +364,13 @@ static int expand_key(const char *key, GSList **out)
static void key_states_scan_key(const char *key, KEY_REC *rec) static void key_states_scan_key(const char *key, KEY_REC *rec)
{ {
GSList *tmp, *out; GSList *tmp, *out;
int limit = MAX_EXPAND_RECURSION;
if (g_strcmp0(rec->info->id, "key") == 0) if (g_strcmp0(rec->info->id, "key") == 0)
return; return;
out = g_slist_append(NULL, g_string_new(NULL)); out = g_slist_append(NULL, g_string_new(NULL));
if (expand_key(key, &out)) { if (expand_key(key, &out, &limit)) {
for (tmp = out; tmp != NULL; tmp = tmp->next) { for (tmp = out; tmp != NULL; tmp = tmp->next) {
GString *str = tmp->data; GString *str = tmp->data;