diff options
author | ailin-nemui <ailin-nemui@users.noreply.github.com> | 2018-02-01 10:21:31 +0100 |
---|---|---|
committer | ailin-nemui <ailin-nemui@users.noreply.github.com> | 2018-02-01 10:21:31 +0100 |
commit | 12360fb2c06b8f11db6a7348426851fac8de8a93 (patch) | |
tree | 638514aa54f617396692b498b0b602c5561cbb8a /src/fe-common/core | |
parent | 6d42c4f949ab7d3d403d2f31d6a816961a180e2b (diff) | |
download | irssi-12360fb2c06b8f11db6a7348426851fac8de8a93.zip |
protect theme recursion
Diffstat (limited to 'src/fe-common/core')
-rw-r--r-- | src/fe-common/core/themes.c | 54 |
1 files changed, 36 insertions, 18 deletions
diff --git a/src/fe-common/core/themes.c b/src/fe-common/core/themes.c index 6692985b..99dc90bc 100644 --- a/src/fe-common/core/themes.c +++ b/src/fe-common/core/themes.c @@ -400,12 +400,15 @@ char *theme_format_expand_get(THEME_REC *theme, const char **format) return ret; } +static char *theme_format_expand_data_rec(THEME_REC *theme, const char **format, + theme_rm_col default_fg, theme_rm_col default_bg, + theme_rm_col *save_last_fg, theme_rm_col *save_last_bg, + int flags, GTree *block_list); + /* expand a single {abstract ...data... } */ -static char *theme_format_expand_abstract(THEME_REC *theme, - const char **formatp, - theme_rm_col *last_fg, - theme_rm_col *last_bg, - int flags) +static char *theme_format_expand_abstract(THEME_REC *theme, const char **formatp, + theme_rm_col *last_fg, theme_rm_col *last_bg, int flags, + GTree *block_list) { GString *str; const char *p, *format; @@ -439,12 +442,20 @@ static char *theme_format_expand_abstract(THEME_REC *theme, } *formatp = format+len; + if (block_list == NULL) { + block_list = g_tree_new_full((GCompareDataFunc) g_strcmp0, NULL, g_free, NULL); + } else { + g_tree_ref(block_list); + } + /* get the abstract data */ data = g_hash_table_lookup(theme->abstracts, abstract); - g_free(abstract); - if (data == NULL) { + if (data == NULL || g_tree_lookup(block_list, abstract) != NULL) { /* unknown abstract, just display the data */ data = "$0-"; + g_free(abstract); + } else { + g_tree_insert(block_list, abstract, abstract); } abstract = g_strdup(data); @@ -488,18 +499,17 @@ static char *theme_format_expand_abstract(THEME_REC *theme, /* abstract may itself contain abstracts or replaces */ p = abstract; - ret = theme_format_expand_data(theme, &p, default_fg, default_bg, - last_fg, last_bg, - flags | EXPAND_FLAG_LASTCOLOR_ARG); + ret = theme_format_expand_data_rec(theme, &p, default_fg, default_bg, last_fg, last_bg, + flags | EXPAND_FLAG_LASTCOLOR_ARG, block_list); g_free(abstract); + g_tree_unref(block_list); return ret; } -/* expand the data part in {abstract data} */ -char *theme_format_expand_data(THEME_REC *theme, const char **format, - theme_rm_col default_fg, theme_rm_col default_bg, - theme_rm_col *save_last_fg, theme_rm_col *save_last_bg, - int flags) +static char *theme_format_expand_data_rec(THEME_REC *theme, const char **format, + theme_rm_col default_fg, theme_rm_col default_bg, + theme_rm_col *save_last_fg, theme_rm_col *save_last_bg, + int flags, GTree *block_list) { GString *str; char *ret, *abstract; @@ -545,9 +555,8 @@ char *theme_format_expand_data(THEME_REC *theme, const char **format, break; /* error */ /* get a single {...} */ - abstract = theme_format_expand_abstract(theme, format, - &last_fg, &last_bg, - recurse_flags); + abstract = theme_format_expand_abstract(theme, format, &last_fg, &last_bg, + recurse_flags, block_list); if (abstract != NULL) { g_string_append(str, abstract); g_free(abstract); @@ -565,6 +574,15 @@ char *theme_format_expand_data(THEME_REC *theme, const char **format, return ret; } +/* expand the data part in {abstract data} */ +char *theme_format_expand_data(THEME_REC *theme, const char **format, theme_rm_col default_fg, + theme_rm_col default_bg, theme_rm_col *save_last_fg, + theme_rm_col *save_last_bg, int flags) +{ + return theme_format_expand_data_rec(theme, format, default_fg, default_bg, save_last_bg, + save_last_bg, flags, NULL); +} + #define IS_OLD_FORMAT(code, last_fg, last_bg) \ (((code) == 'n' && (last_fg) == 'n' && (last_bg) == 'n') || \ ((code) != 'n' && ((code) == (last_fg) || (code) == (last_bg)))) |