diff options
-rw-r--r-- | ChangeLog.adoc | 1 | ||||
-rw-r--r-- | src/plugins/irc/irc-protocol.c | 57 | ||||
-rw-r--r-- | tests/unit/plugins/irc/test-irc-protocol.cpp | 11 |
3 files changed, 45 insertions, 24 deletions
diff --git a/ChangeLog.adoc b/ChangeLog.adoc index 980ba0397..471210425 100644 --- a/ChangeLog.adoc +++ b/ChangeLog.adoc @@ -26,6 +26,7 @@ New features:: Bug fixes:: * api: fix search of option when the section is not given in functions config_search_option and config_search_section_option + * irc: fix parsing of CAP message when there is no prefix (issue #1707) * irc: fix parsing of TAGMSG message when there is a colon before the channel [[v3.3]] diff --git a/src/plugins/irc/irc-protocol.c b/src/plugins/irc/irc-protocol.c index 624a126df..55ce92c36 100644 --- a/src/plugins/irc/irc-protocol.c +++ b/src/plugins/irc/irc-protocol.c @@ -715,6 +715,9 @@ irc_protocol_cap_sync (struct t_irc_server *server, int sasl) * Callback for the IRC message "CAP": client capability. * * Message looks like: + * CAP * LS :identify-msg multi-prefix sasl + * CAP * ACK :sasl + * CAP * NAK :sasl * :server CAP * LS :identify-msg multi-prefix sasl * :server CAP * ACK :sasl * :server CAP * NAK :sasl @@ -725,24 +728,26 @@ IRC_PROTOCOL_CALLBACK(cap) char *ptr_caps, **caps_supported, **caps_added, **caps_removed; char **caps_enabled, *pos_value, *str_name, **str_caps; char str_msg_auth[512], **str_caps_enabled, **str_caps_disabled; - int num_caps_supported, num_caps_added, num_caps_removed; + int arg_cmd, num_caps_supported, num_caps_added, num_caps_removed; int num_caps_enabled, sasl_to_do, sasl_mechanism; int i, timeout, last_reply; - IRC_PROTOCOL_MIN_ARGS(4); + arg_cmd = (argv[0][0] == ':') ? 1 : 0; + + IRC_PROTOCOL_MIN_ARGS(arg_cmd + 3); - if (strcmp (argv[3], "LS") == 0) + if (strcmp (argv[arg_cmd + 2], "LS") == 0) { - if (argc > 4) + if (argc > arg_cmd + 3) { - if (argc > 5 && (strcmp (argv[4], "*") == 0)) + if (argc > arg_cmd + 4 && (strcmp (argv[arg_cmd + 3], "*") == 0)) { - ptr_caps = argv_eol[5]; + ptr_caps = argv_eol[arg_cmd + 4]; last_reply = 0; } else { - ptr_caps = argv_eol[4]; + ptr_caps = argv_eol[arg_cmd + 3]; last_reply = 1; } @@ -814,18 +819,18 @@ IRC_PROTOCOL_CALLBACK(cap) weechat_string_free_split (caps_supported); } } - else if (strcmp (argv[3], "LIST") == 0) + else if (strcmp (argv[arg_cmd + 2], "LIST") == 0) { - if (argc > 4) + if (argc > arg_cmd + 3) { - if (argc > 5 && (strcmp (argv[4], "*") == 0)) + if (argc > arg_cmd + 4 && (strcmp (argv[arg_cmd + 3], "*") == 0)) { - ptr_caps = argv_eol[5]; + ptr_caps = argv_eol[arg_cmd + 4]; last_reply = 0; } else { - ptr_caps = argv_eol[4]; + ptr_caps = argv_eol[arg_cmd + 3]; last_reply = 1; } @@ -893,11 +898,12 @@ IRC_PROTOCOL_CALLBACK(cap) weechat_string_free_split (caps_enabled); } } - else if (strcmp (argv[3], "ACK") == 0) + else if (strcmp (argv[arg_cmd + 2], "ACK") == 0) { - if (argc > 4) + if (argc > arg_cmd + 3) { - ptr_caps = (argv_eol[4][0] == ':') ? argv_eol[4] + 1 : argv_eol[4]; + ptr_caps = (argv_eol[arg_cmd + 3][0] == ':') ? + argv_eol[arg_cmd + 3] + 1 : argv_eol[arg_cmd + 3]; sasl_to_do = 0; str_caps_enabled = weechat_string_dyn_alloc (128); @@ -996,11 +1002,12 @@ IRC_PROTOCOL_CALLBACK(cap) } } } - else if (strcmp (argv[3], "NAK") == 0) + else if (strcmp (argv[arg_cmd + 2], "NAK") == 0) { - if (argc > 4) + if (argc > arg_cmd + 3) { - ptr_caps = (argv_eol[4][0] == ':') ? argv_eol[4] + 1 : argv_eol[4]; + ptr_caps = (argv_eol[arg_cmd + 3][0] == ':') ? + argv_eol[arg_cmd + 3] + 1 : argv_eol[arg_cmd + 3]; weechat_printf_date_tags ( server->buffer, date, NULL, _("%s%s: client capability, refused: %s"), @@ -1009,11 +1016,12 @@ IRC_PROTOCOL_CALLBACK(cap) irc_server_sendf (server, 0, NULL, "CAP END"); } } - else if (strcmp (argv[3], "NEW") == 0) + else if (strcmp (argv[arg_cmd + 2], "NEW") == 0) { - if (argc > 4) + if (argc > arg_cmd + 3) { - ptr_caps = (argv_eol[4][0] == ':') ? argv_eol[4] + 1 : argv_eol[4]; + ptr_caps = (argv_eol[arg_cmd + 3][0] == ':') ? + argv_eol[arg_cmd + 3] + 1 : argv_eol[arg_cmd + 3]; weechat_printf_date_tags ( server->buffer, date, NULL, _("%s%s: client capability, now available: %s"), @@ -1056,11 +1064,12 @@ IRC_PROTOCOL_CALLBACK(cap) irc_protocol_cap_sync (server, 0); } } - else if (strcmp (argv[3], "DEL") == 0) + else if (strcmp (argv[arg_cmd + 2], "DEL") == 0) { - if (argc > 4) + if (argc > arg_cmd + 3) { - ptr_caps = (argv_eol[4][0] == ':') ? argv_eol[4] + 1 : argv_eol[4]; + ptr_caps = (argv_eol[arg_cmd + 3][0] == ':') ? + argv_eol[arg_cmd + 3] + 1 : argv_eol[arg_cmd + 3]; weechat_printf_date_tags ( server->buffer, date, NULL, _("%s%s: client capability, removed: %s"), diff --git a/tests/unit/plugins/irc/test-irc-protocol.cpp b/tests/unit/plugins/irc/test-irc-protocol.cpp index 67776fc80..22577a5e6 100644 --- a/tests/unit/plugins/irc/test-irc-protocol.cpp +++ b/tests/unit/plugins/irc/test-irc-protocol.cpp @@ -538,9 +538,20 @@ TEST(IrcProtocolWithServer, cap) server_recv (":server 001 alice"); /* not enough arguments */ + server_recv ("CAP"); + server_recv ("CAP *"); server_recv (":server CAP"); server_recv (":server CAP *"); + server_recv ("CAP * LS :identify-msg multi-prefix sasl"); + server_recv ("CAP * LS * :identify-msg multi-prefix sasl"); + server_recv ("CAP * LIST :identify-msg multi-prefix sasl"); + server_recv ("CAP * LIST * :identify-msg multi-prefix sasl"); + server_recv ("CAP * NEW :identify-msg multi-prefix sasl"); + server_recv ("CAP * DEL :identify-msg multi-prefix sasl"); + server_recv ("CAP * ACK :sasl"); + server_recv ("CAP * NAK :sasl"); + server_recv (":server CAP * LS :identify-msg multi-prefix sasl"); server_recv (":server CAP * LS * :identify-msg multi-prefix sasl"); server_recv (":server CAP * LIST :identify-msg multi-prefix sasl"); |