diff options
-rw-r--r-- | src/irc/irc_client.cpp | 26 | ||||
-rw-r--r-- | src/irc/irc_client.hpp | 167 |
2 files changed, 103 insertions, 90 deletions
diff --git a/src/irc/irc_client.cpp b/src/irc/irc_client.cpp index 4e8385c..6ab19b7 100644 --- a/src/irc/irc_client.cpp +++ b/src/irc/irc_client.cpp @@ -150,14 +150,26 @@ void IrcClient::parse_in_buffer(const size_t) // Call the standard callback (if any), associated with the command // name that we just received. - auto cb = irc_callbacks.find(message.command); - if (cb != irc_callbacks.end()) + auto it = irc_callbacks.find(message.command); + if (it != irc_callbacks.end()) { - try { - (this->*(cb->second))(message); - } catch (const std::exception& e) { - log_error("Unhandled exception: " << e.what()); - } + const auto& limits = it->second.second; + // Check that the Message is well formed before actually calling + // the callback. limits.first is the min number of arguments, + // second is the max + if (message.arguments.size() < limits.first || + (limits.second > 0 && message.arguments.size() > limits.second)) + log_warning("Invalid number of arguments for IRC command “" << message.command << + "”: " << message.arguments.size()); + else + { + const auto& cb = it->second.first; + try { + (this->*(cb))(message); + } catch (const std::exception& e) { + log_error("Unhandled exception: " << e.what()); + } + } } else { diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index 0d1604d..a3f69a0 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -336,90 +336,91 @@ private: */ typedef void (IrcClient::*irc_callback_t)(const IrcMessage&); -static const std::unordered_map<std::string, irc_callback_t> irc_callbacks = { - {"NOTICE", &IrcClient::on_notice}, - {"002", &IrcClient::forward_server_message}, - {"003", &IrcClient::forward_server_message}, - {"005", &IrcClient::on_isupport_message}, - {"RPL_LISTSTART", &IrcClient::on_rpl_liststart}, - {"321", &IrcClient::on_rpl_liststart}, - {"RPL_LIST", &IrcClient::on_rpl_list}, - {"322", &IrcClient::on_rpl_list}, - {"RPL_LISTEND", &IrcClient::on_rpl_listend}, - {"323", &IrcClient::on_rpl_listend}, - {"RPL_MOTDSTART", &IrcClient::empty_motd}, - {"375", &IrcClient::empty_motd}, - {"RPL_MOTD", &IrcClient::on_motd_line}, - {"372", &IrcClient::on_motd_line}, - {"RPL_MOTDEND", &IrcClient::send_motd}, - {"376", &IrcClient::send_motd}, - {"JOIN", &IrcClient::on_channel_join}, - {"PRIVMSG", &IrcClient::on_channel_message}, - {"353", &IrcClient::set_and_forward_user_list}, - {"332", &IrcClient::on_topic_received}, - {"TOPIC", &IrcClient::on_topic_received}, - {"366", &IrcClient::on_channel_completely_joined}, - {"432", &IrcClient::on_erroneous_nickname}, - {"433", &IrcClient::on_nickname_conflict}, - {"438", &IrcClient::on_nickname_change_too_fast}, - {"001", &IrcClient::on_welcome_message}, - {"PART", &IrcClient::on_part}, - {"ERROR", &IrcClient::on_error}, - {"QUIT", &IrcClient::on_quit}, - {"NICK", &IrcClient::on_nick}, - {"MODE", &IrcClient::on_mode}, - {"PING", &IrcClient::send_pong_command}, - {"PONG", &IrcClient::on_pong}, - {"KICK", &IrcClient::on_kick}, +static const std::unordered_map<std::string, + std::pair<irc_callback_t, std::pair<std::size_t, std::size_t>>> irc_callbacks = { + {"NOTICE", {&IrcClient::on_notice, {2, 0}}}, + {"002", {&IrcClient::forward_server_message, {2, 0}}}, + {"003", {&IrcClient::forward_server_message, {2, 0}}}, + {"005", {&IrcClient::on_isupport_message, {0, 0}}}, + {"RPL_LISTSTART", {&IrcClient::on_rpl_liststart, {0, 0}}}, + {"321", {&IrcClient::on_rpl_liststart, {0, 0}}}, + {"RPL_LIST", {&IrcClient::on_rpl_list, {0, 0}}}, + {"322", {&IrcClient::on_rpl_list, {0, 0}}}, + {"RPL_LISTEND", {&IrcClient::on_rpl_listend, {0, 0}}}, + {"323", {&IrcClient::on_rpl_listend, {0, 0}}}, + {"RPL_MOTDSTART", {&IrcClient::empty_motd, {0, 0}}}, + {"375", {&IrcClient::empty_motd, {0, 0}}}, + {"RPL_MOTD", {&IrcClient::on_motd_line, {2, 0}}}, + {"372", {&IrcClient::on_motd_line, {2, 0}}}, + {"RPL_MOTDEND", {&IrcClient::send_motd, {0, 0}}}, + {"376", {&IrcClient::send_motd, {0, 0}}}, + {"JOIN", {&IrcClient::on_channel_join, {1, 0}}}, + {"PRIVMSG", {&IrcClient::on_channel_message, {2, 0}}}, + {"353", {&IrcClient::set_and_forward_user_list, {4, 0}}}, + {"332", {&IrcClient::on_topic_received, {2, 0}}}, + {"TOPIC", {&IrcClient::on_topic_received, {2, 0}}}, + {"366", {&IrcClient::on_channel_completely_joined, {2, 0}}}, + {"432", {&IrcClient::on_erroneous_nickname, {2, 0}}}, + {"433", {&IrcClient::on_nickname_conflict, {2, 0}}}, + {"438", {&IrcClient::on_nickname_change_too_fast, {2, 0}}}, + {"001", {&IrcClient::on_welcome_message, {1, 0}}}, + {"PART", {&IrcClient::on_part, {1, 0}}}, + {"ERROR", {&IrcClient::on_error, {1, 0}}}, + {"QUIT", {&IrcClient::on_quit, {0, 0}}}, + {"NICK", {&IrcClient::on_nick, {1, 0}}}, + {"MODE", {&IrcClient::on_mode, {1, 0}}}, + {"PING", {&IrcClient::send_pong_command, {1, 0}}}, + {"PONG", {&IrcClient::on_pong, {0, 0}}}, + {"KICK", {&IrcClient::on_kick, {3, 0}}}, - {"401", &IrcClient::on_generic_error}, - {"402", &IrcClient::on_generic_error}, - {"403", &IrcClient::on_generic_error}, - {"404", &IrcClient::on_generic_error}, - {"405", &IrcClient::on_generic_error}, - {"406", &IrcClient::on_generic_error}, - {"407", &IrcClient::on_generic_error}, - {"408", &IrcClient::on_generic_error}, - {"409", &IrcClient::on_generic_error}, - {"410", &IrcClient::on_generic_error}, - {"411", &IrcClient::on_generic_error}, - {"412", &IrcClient::on_generic_error}, - {"414", &IrcClient::on_generic_error}, - {"421", &IrcClient::on_generic_error}, - {"422", &IrcClient::on_generic_error}, - {"423", &IrcClient::on_generic_error}, - {"424", &IrcClient::on_generic_error}, - {"431", &IrcClient::on_generic_error}, - {"436", &IrcClient::on_generic_error}, - {"441", &IrcClient::on_generic_error}, - {"442", &IrcClient::on_generic_error}, - {"443", &IrcClient::on_generic_error}, - {"444", &IrcClient::on_generic_error}, - {"446", &IrcClient::on_generic_error}, - {"451", &IrcClient::on_generic_error}, - {"461", &IrcClient::on_generic_error}, - {"462", &IrcClient::on_generic_error}, - {"463", &IrcClient::on_generic_error}, - {"464", &IrcClient::on_generic_error}, - {"465", &IrcClient::on_generic_error}, - {"467", &IrcClient::on_generic_error}, - {"470", &IrcClient::on_generic_error}, - {"471", &IrcClient::on_generic_error}, - {"472", &IrcClient::on_generic_error}, - {"473", &IrcClient::on_generic_error}, - {"474", &IrcClient::on_generic_error}, - {"475", &IrcClient::on_generic_error}, - {"476", &IrcClient::on_generic_error}, - {"477", &IrcClient::on_generic_error}, - {"481", &IrcClient::on_generic_error}, - {"482", &IrcClient::on_generic_error}, - {"483", &IrcClient::on_generic_error}, - {"484", &IrcClient::on_generic_error}, - {"485", &IrcClient::on_generic_error}, - {"487", &IrcClient::on_generic_error}, - {"491", &IrcClient::on_generic_error}, - {"501", &IrcClient::on_generic_error}, - {"502", &IrcClient::on_generic_error}, + {"401", {&IrcClient::on_generic_error, {2, 0}}}, + {"402", {&IrcClient::on_generic_error, {2, 0}}}, + {"403", {&IrcClient::on_generic_error, {2, 0}}}, + {"404", {&IrcClient::on_generic_error, {2, 0}}}, + {"405", {&IrcClient::on_generic_error, {2, 0}}}, + {"406", {&IrcClient::on_generic_error, {2, 0}}}, + {"407", {&IrcClient::on_generic_error, {2, 0}}}, + {"408", {&IrcClient::on_generic_error, {2, 0}}}, + {"409", {&IrcClient::on_generic_error, {2, 0}}}, + {"410", {&IrcClient::on_generic_error, {2, 0}}}, + {"411", {&IrcClient::on_generic_error, {2, 0}}}, + {"412", {&IrcClient::on_generic_error, {2, 0}}}, + {"414", {&IrcClient::on_generic_error, {2, 0}}}, + {"421", {&IrcClient::on_generic_error, {2, 0}}}, + {"422", {&IrcClient::on_generic_error, {2, 0}}}, + {"423", {&IrcClient::on_generic_error, {2, 0}}}, + {"424", {&IrcClient::on_generic_error, {2, 0}}}, + {"431", {&IrcClient::on_generic_error, {2, 0}}}, + {"436", {&IrcClient::on_generic_error, {2, 0}}}, + {"441", {&IrcClient::on_generic_error, {2, 0}}}, + {"442", {&IrcClient::on_generic_error, {2, 0}}}, + {"443", {&IrcClient::on_generic_error, {2, 0}}}, + {"444", {&IrcClient::on_generic_error, {2, 0}}}, + {"446", {&IrcClient::on_generic_error, {2, 0}}}, + {"451", {&IrcClient::on_generic_error, {2, 0}}}, + {"461", {&IrcClient::on_generic_error, {2, 0}}}, + {"462", {&IrcClient::on_generic_error, {2, 0}}}, + {"463", {&IrcClient::on_generic_error, {2, 0}}}, + {"464", {&IrcClient::on_generic_error, {2, 0}}}, + {"465", {&IrcClient::on_generic_error, {2, 0}}}, + {"467", {&IrcClient::on_generic_error, {2, 0}}}, + {"470", {&IrcClient::on_generic_error, {2, 0}}}, + {"471", {&IrcClient::on_generic_error, {2, 0}}}, + {"472", {&IrcClient::on_generic_error, {2, 0}}}, + {"473", {&IrcClient::on_generic_error, {2, 0}}}, + {"474", {&IrcClient::on_generic_error, {2, 0}}}, + {"475", {&IrcClient::on_generic_error, {2, 0}}}, + {"476", {&IrcClient::on_generic_error, {2, 0}}}, + {"477", {&IrcClient::on_generic_error, {2, 0}}}, + {"481", {&IrcClient::on_generic_error, {2, 0}}}, + {"482", {&IrcClient::on_generic_error, {2, 0}}}, + {"483", {&IrcClient::on_generic_error, {2, 0}}}, + {"484", {&IrcClient::on_generic_error, {2, 0}}}, + {"485", {&IrcClient::on_generic_error, {2, 0}}}, + {"487", {&IrcClient::on_generic_error, {2, 0}}}, + {"491", {&IrcClient::on_generic_error, {2, 0}}}, + {"501", {&IrcClient::on_generic_error, {2, 0}}}, + {"502", {&IrcClient::on_generic_error, {2, 0}}}, }; #endif // IRC_CLIENT_INCLUDED |