~singpolyma/biboumi

df2fe0bc4bf6240e47abf26ff88ffdfc9373f481 — louiz’ 2 years ago 063e6b1
Fix the parsing of IRC messages, especially with trailing spaces
M src/irc/irc_message.cpp => src/irc/irc_message.cpp +18 -21
@@ 1,33 1,30 @@
#include <irc/irc_message.hpp>
#include <iostream>

IrcMessage::IrcMessage(std::string&& line)
IrcMessage::IrcMessage(std::stringstream ss)
{
  std::string::size_type pos;

  // optional prefix
  if (line[0] == ':')
  if (ss.peek() == ':')
    {
      pos = line.find(' ');
      this->prefix = line.substr(1, pos - 1);
      line = line.substr(pos + 1, std::string::npos);
      ss.ignore();
      ss >> this->prefix;
    }
  // command
  pos = line.find(' ');
  this->command = line.substr(0, pos);
  line = line.substr(pos + 1, std::string::npos);
  // arguments
  do
  ss >> this->command;
  while (ss >> std::ws)
    {
      if (line[0] == ':')
      std::string arg;
      if (ss.peek() == ':')
        {
          ss.ignore();
          std::getline(ss, arg);
        }
      else
        {
          this->arguments.emplace_back(line.substr(1, std::string::npos));
          break ;
          ss >> arg;
          if (arg.empty())
            break;
        }
      pos = line.find(' ');
      this->arguments.emplace_back(line.substr(0, pos));
      line = line.substr(pos + 1, std::string::npos);
    } while (pos != std::string::npos);
      this->arguments.push_back(std::move(arg));
    }
}

IrcMessage::IrcMessage(std::string&& prefix,

M src/irc/irc_message.hpp => src/irc/irc_message.hpp +3 -1
@@ 4,11 4,13 @@
#include <vector>
#include <string>
#include <ostream>
#include <sstream>

class IrcMessage
{
public:
  IrcMessage(std::string&& line);
  IrcMessage(std::stringstream ss);
  IrcMessage(std::string str): IrcMessage{std::stringstream{str}} {}
  IrcMessage(std::string&& prefix, std::string&& command, std::vector<std::string>&& args);
  IrcMessage(std::string&& command, std::vector<std::string>&& args);
  ~IrcMessage() = default;

M tests/end_to_end/scenarios/multiple_channels_join.py => tests/end_to_end/scenarios/multiple_channels_join.py +4 -0
@@ 14,5 14,9 @@ scenario = (
    expect_self_join_presence(jid='{jid_one}/{resource_one}', chan="#foo", nick="{nick_one}"),
    expect_self_join_presence(jid='{jid_one}/{resource_one}', chan="#bar", nick="{nick_one}"),
    expect_self_join_presence(jid='{jid_one}/{resource_one}', chan="#baz", nick="{nick_one}"),

    send_stanza("<message from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}' type='groupchat'><subject>Le topic</subject></message>"),
    expect_stanza("/message"),

)


A tests/irc.cpp => tests/irc.cpp +43 -0
@@ 0,0 1,43 @@
#include "catch.hpp"

#include <irc/irc_message.hpp>

TEST_CASE("Basic IRC message parsing")
{
  IrcMessage m(":prefix COMMAND un deux trois");
  CHECK(m.prefix == "prefix");
  CHECK(m.command == "COMMAND");
  CHECK(m.arguments.size() == 3);
  CHECK(m.arguments[0] == "un");
  CHECK(m.arguments[1] == "deux");
  CHECK(m.arguments[2] == "trois");
}

TEST_CASE("Trailing space")
{
  IrcMessage m(":prefix COMMAND un deux trois ");
  CHECK(m.prefix == "prefix");
  CHECK(m.arguments.size() == 3);
  CHECK(m.arguments[0] == "un");
  CHECK(m.arguments[1] == "deux");
  CHECK(m.arguments[2] == "trois");
}

TEST_CASE("Message with :")
{
  IrcMessage m(":prefix COMMAND un :coucou les amis ");
  CHECK(m.prefix == "prefix");
  CHECK(m.arguments.size() == 2);
  CHECK(m.arguments[0] == "un");
  CHECK(m.arguments[1] == "coucou les amis ");
}

TEST_CASE("Message with empty :")
{
  IrcMessage m("COMMAND un deux :");
  CHECK(m.prefix == "");
  CHECK(m.arguments.size() == 3);
  CHECK(m.arguments[0] == "un");
  CHECK(m.arguments[1] == "deux");
  CHECK(m.arguments[2] == "");
}