summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorent Le Coz <louiz@louiz.org>2015-09-06 18:55:48 +0200
committerFlorent Le Coz <louiz@louiz.org>2015-09-06 18:55:48 +0200
commit4cfcc79114d89096219039104674d35ca1aba5ca (patch)
tree11a0ab2d042dd4770c2f612523ac4a196c23e527
parentc3309d0acfedaed867ae1bc14cd7a65fe5be1419 (diff)
downloadbiboumi-4cfcc79114d89096219039104674d35ca1aba5ca.tar.gz
biboumi-4cfcc79114d89096219039104674d35ca1aba5ca.tar.bz2
biboumi-4cfcc79114d89096219039104674d35ca1aba5ca.tar.xz
biboumi-4cfcc79114d89096219039104674d35ca1aba5ca.zip
Check the number of argument of every IRC command received from the server
Each IrcClient callback has a max and min size of argument, we call the callback only if the parsed message has a correct number of arguments, otherwise it is ignored (with a warning logged).
-rw-r--r--src/irc/irc_client.cpp26
-rw-r--r--src/irc/irc_client.hpp167
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