From aea58025194811d9a92ad7a8d708476e43a4816e Mon Sep 17 00:00:00 2001 From: Nei Date: Thu, 4 Jan 2018 22:29:29 +0000 Subject: [PATCH] Merge branch 'security' into 'master' Security Closes GL#18, GL#19, GL#20, GL#21 See merge request irssi/irssi!29 (cherry picked from commit 9df3d92598108b6e68fcc5521cd1fab8462d7ec5) --- src/core/misc.c | 7 +++++-- src/core/special-vars.c | 4 ++++ src/fe-common/core/completion.c | 18 ++++++++++++------ src/irc/core/channel-events.c | 8 +++++++- 4 files changed, 28 insertions(+), 9 deletions(-) diff --git a/src/core/misc.c b/src/core/misc.c index 0b2d8e77..6608ef76 100644 --- a/src/core/misc.c +++ b/src/core/misc.c @@ -707,8 +707,11 @@ int expand_escape(const char **data) *data += 2; return strtol(digit, NULL, 16); case 'c': - /* control character (\cA = ^A) */ - (*data)++; + /* check for end of string */ + if ((*data)[1] == '\0') + return 0; + /* control character (\cA = ^A) */ + (*data)++; return i_toupper(**data) - 64; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': diff --git a/src/core/special-vars.c b/src/core/special-vars.c index aaf8da8f..f254c200 100644 --- a/src/core/special-vars.c +++ b/src/core/special-vars.c @@ -384,6 +384,7 @@ char *parse_special(char **cmd, SERVER_REC *server, void *item, } nest_free = FALSE; nest_value = NULL; +#if 0 /* this code is disabled due to security issues until it is fixed */ if (**cmd == '(' && (*cmd)[1] != '\0') { /* subvariable */ int toplevel = nested_orig_cmd == NULL; @@ -412,6 +413,9 @@ char *parse_special(char **cmd, SERVER_REC *server, void *item, if (toplevel) nested_orig_cmd = NULL; } +#else + if (nested_orig_cmd) nested_orig_cmd = NULL; +#endif if (**cmd != '{') brackets = FALSE; diff --git a/src/fe-common/core/completion.c b/src/fe-common/core/completion.c index a97adc21..1059bd6c 100644 --- a/src/fe-common/core/completion.c +++ b/src/fe-common/core/completion.c @@ -186,12 +186,18 @@ char *word_complete(WINDOW_REC *window, const char *line, int *pos, int erase, i char *old; old = linestart; - linestart = *linestart == '\0' ? - g_strdup(word) : - g_strdup_printf("%s%c%s", - /* do not accidentally duplicate the word separator */ - line == wordstart - 1 ? "" : linestart, - old_wordstart[-1], word); + /* we want to move word into linestart */ + if (*linestart == '\0') { + linestart = g_strdup(word); + } else { + GString *str = g_string_new(linestart); + if (old_wordstart[-1] != str->str[str->len - 1]) { + /* do not accidentally duplicate the word separator */ + g_string_append_c(str, old_wordstart[-1]); + } + g_string_append(str, word); + linestart = g_string_free(str, FALSE); + } g_free(old); g_free(word); diff --git a/src/irc/core/channel-events.c b/src/irc/core/channel-events.c index b0bddab2..46bbd5fa 100644 --- a/src/irc/core/channel-events.c +++ b/src/irc/core/channel-events.c @@ -138,7 +138,13 @@ static void channel_change_topic(IRC_SERVER_REC *server, const char *channel, g_free_not_null(chanrec->topic_by); chanrec->topic_by = g_strdup(setby); - chanrec->topic_time = settime; + if (chanrec->topic_by == NULL) { + /* ensure invariant topic_time > 0 <=> topic_by != NULL. + this could be triggered by a topic command without sender */ + chanrec->topic_time = 0; + } else { + chanrec->topic_time = settime; + } signal_emit("channel topic changed", 1, chanrec); }