diff options
-rw-r--r-- | docs/help/in/ison.in | 2 | ||||
-rw-r--r-- | src/core/network-openssl.c | 20 | ||||
-rw-r--r-- | src/fe-common/core/chat-completion.c | 55 | ||||
-rw-r--r-- | src/fe-common/core/themes.c | 2 | ||||
-rw-r--r-- | src/fe-text/gui-readline.c | 3 | ||||
-rw-r--r-- | src/fe-text/mainwindows.c | 91 | ||||
-rwxr-xr-x | utils/tap-test | 20 |
7 files changed, 155 insertions, 38 deletions
diff --git a/docs/help/in/ison.in b/docs/help/in/ison.in index c77e4c59..e9e54ee9 100644 --- a/docs/help/in/ison.in +++ b/docs/help/in/ison.in @@ -16,5 +16,5 @@ /ISON mike /ISON sarah bob -%9See also:%9 NOTIFY, WHOAS, WHOIS +%9See also:%9 NOTIFY, WHOWAS, WHOIS diff --git a/src/core/network-openssl.c b/src/core/network-openssl.c index c7ce4b43..9fddf073 100644 --- a/src/core/network-openssl.c +++ b/src/core/network-openssl.c @@ -46,6 +46,7 @@ #endif /* OpenSSL 1.1.0 also introduced some useful additions to the api */ +#if (OPENSSL_VERSION_NUMBER >= 0x10002000L) #if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined (LIBRESSL_VERSION_NUMBER) static int X509_STORE_up_ref(X509_STORE *vfy) { @@ -57,6 +58,7 @@ static int X509_STORE_up_ref(X509_STORE *vfy) return (n > 1) ? 1 : 0; } #endif +#endif /* ssl i/o channel object */ typedef struct @@ -72,7 +74,10 @@ typedef struct } GIOSSLChannel; static int ssl_inited = FALSE; +/* https://github.com/irssi/irssi/issues/820 */ +#if (OPENSSL_VERSION_NUMBER >= 0x10002000L) static X509_STORE *store = NULL; +#endif static void irssi_ssl_free(GIOChannel *handle) { @@ -379,7 +384,9 @@ static GIOFuncs irssi_ssl_channel_funcs = { gboolean irssi_ssl_init(void) { +#if (OPENSSL_VERSION_NUMBER >= 0x10002000L) int success; +#endif #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER) if (!OPENSSL_init_ssl(OPENSSL_INIT_SSL_DEFAULT, NULL)) { @@ -391,6 +398,8 @@ gboolean irssi_ssl_init(void) SSL_load_error_strings(); OpenSSL_add_all_algorithms(); #endif + +#if (OPENSSL_VERSION_NUMBER >= 0x10002000L) store = X509_STORE_new(); if (store == NULL) { g_error("Could not initialize OpenSSL: X509_STORE_new() failed"); @@ -404,6 +413,7 @@ gboolean irssi_ssl_init(void) store = NULL; /* Don't return an error; the user might have their own cafile/capath. */ } +#endif ssl_inited = TRUE; @@ -522,13 +532,21 @@ static GIOChannel *irssi_ssl_get_iochannel(GIOChannel *handle, int port, SERVER_ g_free(scafile); g_free(scapath); verify = TRUE; - } else if (store != NULL) { + } +#if (OPENSSL_VERSION_NUMBER >= 0x10002000L) + else if (store != NULL) { /* Make sure to increment the refcount every time the store is * used, that's essential not to get it free'd by OpenSSL when * the SSL_CTX is destroyed. */ X509_STORE_up_ref(store); SSL_CTX_set_cert_store(ctx, store); } +#else + else { + if (!SSL_CTX_set_default_verify_paths(ctx)) + g_warning("Could not load default certificates"); + } +#endif if(!(ssl = SSL_new(ctx))) { diff --git a/src/fe-common/core/chat-completion.c b/src/fe-common/core/chat-completion.c index 97cd0565..7ecdd4a2 100644 --- a/src/fe-common/core/chat-completion.c +++ b/src/fe-common/core/chat-completion.c @@ -639,6 +639,59 @@ static void complete_window_nicks(GList **list, WINDOW_REC *window, } } +/* Checks if a line is only nicks from autocompletion. + This lets us insert colons only at the beginning of a list + of nicks */ +static int only_nicks(const char *linestart) +{ + int i = 1; + char prev; + + // at the beginning of the line + if (*linestart == '\0') { + return TRUE; + } + + /* completion_char being a whole string introduces loads of edge cases + and can't be handled generally. Skip this case; we handled the + "beginning of line" case already */ + if (completion_char[1] != '\0') + return FALSE; + + /* This would make the completion char get inserted everywhere otherwise */ + if (*completion_char == ' ') + return FALSE; + + /* First ensure that the line is of the format "foo: bar: baz" + we check this by ensuring each space is preceded by a colon or + another space */ + while (linestart[i] != '\0') { + if (linestart[i] == ' ') { + prev = linestart[i - 1]; + if (prev != *completion_char && prev != ' ') + return FALSE; + } + i += 1; + } + + /* There's an edge case here, if we're completing something + like `foo: bar ba<tab>`, then the `linestart` line will end + at "bar", and we'll miss the space. Ensure that the end + of the line is a colon followed by an optional series of spaces */ + i -= 1; + while (i >= 0) { + if (linestart[i] == ' ') { + i--; + continue; + } else if (linestart[i] == *completion_char) { + return TRUE; + } else { + break; + } + } + return FALSE; +} + static void sig_complete_word(GList **list, WINDOW_REC *window, const char *word, const char *linestart, int *want_space) @@ -691,7 +744,7 @@ static void sig_complete_word(GList **list, WINDOW_REC *window, } else if (channel != NULL) { /* nick completion .. we could also be completing a nick after /MSG from nicks in channel */ - const char *suffix = *linestart != '\0' ? NULL : completion_char; + const char *suffix = only_nicks(linestart) ? completion_char : NULL; complete_window_nicks(list, window, word, suffix); } else if (window->level & MSGLEVEL_MSGS) { /* msgs window, complete /MSG nicks */ diff --git a/src/fe-common/core/themes.c b/src/fe-common/core/themes.c index cb1cce8f..6692985b 100644 --- a/src/fe-common/core/themes.c +++ b/src/fe-common/core/themes.c @@ -130,7 +130,7 @@ static char *theme_replace_expand(THEME_REC *theme, int index, abstract = rec->data; abstract = theme_format_expand_data(theme, (const char **) &abstract, default_fg, default_bg, - last_fg, last_bg, flags); + last_fg, last_bg, (flags | EXPAND_FLAG_IGNORE_REPLACES)); ret = parse_special_string(abstract, NULL, NULL, data, NULL, PARSE_FLAG_ONLY_ARGS); g_free(abstract); diff --git a/src/fe-text/gui-readline.c b/src/fe-text/gui-readline.c index b3a78396..88e827a7 100644 --- a/src/fe-text/gui-readline.c +++ b/src/fe-text/gui-readline.c @@ -1174,6 +1174,7 @@ void gui_readline_init(void) key_bind("key", NULL, "^H", "backspace", (SIGNAL_FUNC) key_combo); key_bind("key", NULL, "^?", "backspace", (SIGNAL_FUNC) key_combo); key_bind("key", NULL, "^I", "tab", (SIGNAL_FUNC) key_combo); + key_bind("key", NULL, "meta2-Z", "stab", (SIGNAL_FUNC) key_combo); /* meta */ key_bind("key", NULL, "^[", "meta", (SIGNAL_FUNC) key_combo); @@ -1278,7 +1279,7 @@ void gui_readline_init(void) /* line transmitting */ key_bind("send_line", "Execute the input line", "return", NULL, (SIGNAL_FUNC) key_send_line); - key_bind("word_completion_backward", "", NULL, NULL, (SIGNAL_FUNC) key_word_completion_backward); + key_bind("word_completion_backward", "Choose previous completion suggestion", "stab", NULL, (SIGNAL_FUNC) key_word_completion_backward); key_bind("word_completion", "Complete the current word", "tab", NULL, (SIGNAL_FUNC) key_word_completion); key_bind("erase_completion", "Remove the completion added by word_completion", "meta-k", NULL, (SIGNAL_FUNC) key_erase_completion); key_bind("check_replaces", "Check word replaces", NULL, NULL, (SIGNAL_FUNC) key_check_replaces); diff --git a/src/fe-text/mainwindows.c b/src/fe-text/mainwindows.c index 5f24674f..83a3e0cc 100644 --- a/src/fe-text/mainwindows.c +++ b/src/fe-text/mainwindows.c @@ -915,6 +915,8 @@ static int try_shrink_lower(MAIN_WINDOW_REC *window, int count) { MAIN_WINDOW_REC *shrink_win; + g_return_val_if_fail(count >= 0, FALSE); + shrink_win = mainwindows_find_lower(window); if (shrink_win != NULL) { int ok; @@ -959,6 +961,8 @@ static int try_shrink_upper(MAIN_WINDOW_REC *window, int count) { MAIN_WINDOW_REC *shrink_win; + g_return_val_if_fail(count >= 0, FALSE); + shrink_win = mainwindows_find_upper(window); if (shrink_win != NULL) { int ok; @@ -1063,6 +1067,8 @@ static int try_grow_upper(MAIN_WINDOW_REC *window, int count) static int mainwindow_shrink(MAIN_WINDOW_REC *window, int count, int resize_lower) { + g_return_val_if_fail(count >= 0, FALSE); + if (MAIN_WINDOW_TEXT_HEIGHT(window)-count < WINDOW_MIN_SIZE) return FALSE; @@ -1091,6 +1097,8 @@ static int try_rshrink_right(MAIN_WINDOW_REC *window, int count) { MAIN_WINDOW_REC *shrink_win; + g_return_val_if_fail(count >= 0, FALSE); + shrink_win = mainwindows_find_right(window, FALSE); if (shrink_win != NULL) { if (MAIN_WINDOW_TEXT_WIDTH(shrink_win)-count < NEW_WINDOW_WIDTH) { @@ -1111,6 +1119,8 @@ static int try_rshrink_left(MAIN_WINDOW_REC *window, int count) { MAIN_WINDOW_REC *shrink_win; + g_return_val_if_fail(count >= 0, FALSE); + shrink_win = mainwindows_find_left(window, FALSE); if (shrink_win != NULL) { if (MAIN_WINDOW_TEXT_WIDTH(shrink_win)-count < NEW_WINDOW_WIDTH) { @@ -1168,6 +1178,8 @@ static int try_rgrow_left(MAIN_WINDOW_REC *window, int count) static int mainwindow_rshrink(MAIN_WINDOW_REC *window, int count) { + g_return_val_if_fail(count >= 0, FALSE); + if (MAIN_WINDOW_TEXT_WIDTH(window)-count < NEW_WINDOW_WIDTH) return FALSE; @@ -1220,19 +1232,29 @@ void mainwindows_redraw_dirty(void) } } +static void mainwindow_grow_int(int count) +{ + if (count == 0) { + return; + } else if (count < 0) { + if (!mainwindow_shrink(WINDOW_MAIN(active_win), -count, FALSE)) { + printformat_window(active_win, MSGLEVEL_CLIENTNOTICE, TXT_WINDOW_TOO_SMALL); + } + } else { + if (!mainwindow_grow(WINDOW_MAIN(active_win), count, FALSE)) { + printformat_window(active_win, MSGLEVEL_CLIENTNOTICE, TXT_WINDOW_TOO_SMALL); + } + } +} + /* SYNTAX: WINDOW GROW [<lines>] */ static void cmd_window_grow(const char *data) { - MAIN_WINDOW_REC *window; int count; count = *data == '\0' ? 1 : atoi(data); - window = WINDOW_MAIN(active_win); - if (!mainwindow_grow(window, count, FALSE)) { - printformat_window(active_win, MSGLEVEL_CLIENTNOTICE, - TXT_WINDOW_TOO_SMALL); - } + mainwindow_grow_int(count); } /* SYNTAX: WINDOW SHRINK [<lines>] */ @@ -1241,16 +1263,14 @@ static void cmd_window_shrink(const char *data) int count; count = *data == '\0' ? 1 : atoi(data); - if (!mainwindow_shrink(WINDOW_MAIN(active_win), count, FALSE)) { - printformat_window(active_win, MSGLEVEL_CLIENTNOTICE, - TXT_WINDOW_TOO_SMALL); - } + if (count < -INT_MAX) count = -INT_MAX; + + mainwindow_grow_int(-count); } /* SYNTAX: WINDOW SIZE <lines> */ static void cmd_window_size(const char *data) { - char sizestr[MAX_INT_STRLEN]; int size; if (!is_numeric(data, 0)) return; @@ -1258,13 +1278,9 @@ static void cmd_window_size(const char *data) size -= WINDOW_MAIN(active_win)->height - WINDOW_MAIN(active_win)->statusbar_lines; - if (size == 0) return; + if (size < -INT_MAX) size = -INT_MAX; - ltoa(sizestr, size < 0 ? -size : size); - if (size < 0) - cmd_window_shrink(sizestr); - else - cmd_window_grow(sizestr); + mainwindow_grow_int(size); } /* SYNTAX: WINDOW BALANCE */ @@ -1393,6 +1409,11 @@ static void _cmd_window_show_opt(const char *data, int right) } parent = mainwindow_create(right); + if (parent == NULL) { + printformat_window(active_win, MSGLEVEL_CLIENTERROR, TXT_WINDOW_TOO_SMALL); + return; + } + parent->active = window; gui_window_reparent(window, parent); @@ -1415,16 +1436,29 @@ static void cmd_window_rshow(const char *data) _cmd_window_show_opt(data, TRUE); } +static void window_rgrow_int(int count) +{ + if (count == 0) { + return; + } else if (count < 0) { + if (!mainwindow_rshrink(WINDOW_MAIN(active_win), -count)) { + printformat_window(active_win, MSGLEVEL_CLIENTNOTICE, TXT_WINDOW_TOO_SMALL); + } + } else { + if (!mainwindow_rgrow(WINDOW_MAIN(active_win), count)) { + printformat_window(active_win, MSGLEVEL_CLIENTNOTICE, TXT_WINDOW_TOO_SMALL); + } + } +} + /* SYNTAX: WINDOW RGROW [<columns>] */ static void cmd_window_rgrow(const char *data) { int count; count = *data == '\0' ? 1 : atoi(data); - if (!mainwindow_rgrow(WINDOW_MAIN(active_win), count)) { - printformat_window(active_win, MSGLEVEL_CLIENTNOTICE, - TXT_WINDOW_TOO_SMALL); - } + + window_rgrow_int(count); } /* SYNTAX: WINDOW RSHRINK [<lines>] */ @@ -1433,29 +1467,22 @@ static void cmd_window_rshrink(const char *data) int count; count = *data == '\0' ? 1 : atoi(data); - if (!mainwindow_rshrink(WINDOW_MAIN(active_win), count)) { - printformat_window(active_win, MSGLEVEL_CLIENTNOTICE, - TXT_WINDOW_TOO_SMALL); - } + if (count < -INT_MAX) count = -INT_MAX; + + window_rgrow_int(-count); } /* SYNTAX: WINDOW RSIZE <columns> */ static void cmd_window_rsize(const char *data) { - char rsizestr[MAX_INT_STRLEN]; int rsize; if (!is_numeric(data, 0)) return; rsize = atoi(data); rsize -= MAIN_WINDOW_TEXT_WIDTH(WINDOW_MAIN(active_win)); - if (rsize == 0) return; - ltoa(rsizestr, rsize < 0 ? -rsize : rsize); - if (rsize < 0) - cmd_window_rshrink(rsizestr); - else - cmd_window_rgrow(rsizestr); + window_rgrow_int(rsize); } /* SYNTAX: WINDOW RBALANCE */ diff --git a/utils/tap-test b/utils/tap-test index 481e333e..b3ef8b04 100755 --- a/utils/tap-test +++ b/utils/tap-test @@ -2,4 +2,22 @@ # run a GTest in tap mode. The test binary is passed as $1 -$1 -k --tap +t="$1"; shift +if ${PKG_CONFIG:-pkg-config} --atleast-version 2.40 glib-2.0; then +exec "$t" -k --tap "$@" +else # GTest does not support tap yet + (((("$t" "$@"; echo $? >&3) | ${AM_TAP_AWK:-awk} ' +{ + if (/: /) { + i++ + ok = /: OK/ + sub(/:/, " #") + print (ok ? "ok " : "not ok ") i " " $0 + } else { + print "# " $0 + } +} END { + print 1 ".." i +} +' >&4) 3>&1) | (read xs; exit $xs)) 4>&1 +fi |