Support all allowed channel prefixes
RFC 2812 specifies in §1.3 that “Channels names are strings (beginning with a '&', '#', '+' or '!' character) of length up to fifty (50) characters.” We previously only allowed the first two prefix characters, or any other one if the server overrides the list with ISUPPORT.
This commit is contained in:
+3
-2
@@ -41,8 +41,9 @@ IRC channels and IRC users have a local part formed like this:
|
|||||||
|
|
||||||
``name`` can be a channel name or an user nickname. The distinction between
|
``name`` can be a channel name or an user nickname. The distinction between
|
||||||
the two is based on the first character: by default, if the name starts with
|
the two is based on the first character: by default, if the name starts with
|
||||||
``'#'`` or ``'&'`` (but this can be overridden by the server, using the
|
``'&'``, ``'#'``, ``'+'`` or ``'!'`` (but this can be overridden by the server,
|
||||||
ISUPPORT extension) then it’s a channel name, otherwise this is a nickname.
|
using the ISUPPORT extension) then it’s a channel name, otherwise this is a
|
||||||
|
nickname.
|
||||||
|
|
||||||
There is two ways to address an IRC user, using a local part like this:
|
There is two ways to address an IRC user, using a local part like this:
|
||||||
``nickname`` % ``irc_server`` or by using the in-room address of the
|
``nickname`` % ``irc_server`` or by using the in-room address of the
|
||||||
|
|||||||
@@ -1160,7 +1160,7 @@ std::set<char> Bridge::get_chantypes(const std::string& hostname) const
|
|||||||
{
|
{
|
||||||
IrcClient* irc = this->find_irc_client(hostname);
|
IrcClient* irc = this->find_irc_client(hostname);
|
||||||
if (!irc)
|
if (!irc)
|
||||||
return {'#', '&'};
|
return {'&', '#', '+', '!'};
|
||||||
return irc->get_chantypes();
|
return irc->get_chantypes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -20,7 +20,7 @@ class Bridge;
|
|||||||
* It’s possible to have an empty-string server, but it makes no sense in
|
* It’s possible to have an empty-string server, but it makes no sense in
|
||||||
* biboumi’s context.
|
* biboumi’s context.
|
||||||
*
|
*
|
||||||
* Assuming the chantypes are '#' and '&':
|
* Assuming the chantypes are '&', '#', '+' and '!':
|
||||||
*
|
*
|
||||||
* #test%irc.example.org has :
|
* #test%irc.example.org has :
|
||||||
* - local: "#test" (the # is part of the name, it could very well be absent, or & (for example) instead)
|
* - local: "#test" (the # is part of the name, it could very well be absent, or & (for example) instead)
|
||||||
|
|||||||
@@ -155,7 +155,7 @@ IrcClient::IrcClient(std::shared_ptr<Poller>& poller, std::string hostname,
|
|||||||
bridge(bridge),
|
bridge(bridge),
|
||||||
welcomed(false),
|
welcomed(false),
|
||||||
chanmodes({"", "", "", ""}),
|
chanmodes({"", "", "", ""}),
|
||||||
chantypes({'#', '&'}),
|
chantypes({'&', '#', '+', '!'}),
|
||||||
tokens_bucket(this->get_throttle_limit(), 1s, [this]() {
|
tokens_bucket(this->get_throttle_limit(), 1s, [this]() {
|
||||||
if (message_queue.empty())
|
if (message_queue.empty())
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -482,7 +482,7 @@ void BiboumiComponent::handle_iq(const Stanza& stanza)
|
|||||||
|
|
||||||
// Depending on the 'to' jid in the request, we use one adhoc
|
// Depending on the 'to' jid in the request, we use one adhoc
|
||||||
// command handler or an other
|
// command handler or an other
|
||||||
Iid iid(to.local, {'#', '&'});
|
Iid iid(to.local, {'&', '#', '+', '!'});
|
||||||
AdhocCommandsHandler* adhoc_handler;
|
AdhocCommandsHandler* adhoc_handler;
|
||||||
if (to.local.empty())
|
if (to.local.empty())
|
||||||
adhoc_handler = &this->adhoc_commands_handler;
|
adhoc_handler = &this->adhoc_commands_handler;
|
||||||
@@ -532,7 +532,7 @@ void BiboumiComponent::handle_iq(const Stanza& stanza)
|
|||||||
const XmlNode* query;
|
const XmlNode* query;
|
||||||
if ((query = stanza.get_child("query", DISCO_INFO_NS)))
|
if ((query = stanza.get_child("query", DISCO_INFO_NS)))
|
||||||
{ // Disco info
|
{ // Disco info
|
||||||
Iid iid(to.local, {'#', '&'});
|
Iid iid(to.local, {'&', '#', '+', '!'});
|
||||||
const std::string node = query->get_tag("node");
|
const std::string node = query->get_tag("node");
|
||||||
if (to_str == this->served_hostname)
|
if (to_str == this->served_hostname)
|
||||||
{
|
{
|
||||||
@@ -736,7 +736,7 @@ bool BiboumiComponent::handle_mam_request(const Stanza& stanza)
|
|||||||
|
|
||||||
const XmlNode* query = stanza.get_child("query", MAM_NS);
|
const XmlNode* query = stanza.get_child("query", MAM_NS);
|
||||||
|
|
||||||
Iid iid(to.local, {'#', '&'});
|
Iid iid(to.local, {'&', '#', '+', '!'});
|
||||||
if (query && iid.type == Iid::Type::Channel && to.resource.empty())
|
if (query && iid.type == Iid::Type::Channel && to.resource.empty())
|
||||||
{
|
{
|
||||||
const std::string query_id = query->get_tag("queryid");
|
const std::string query_id = query->get_tag("queryid");
|
||||||
@@ -865,7 +865,7 @@ void BiboumiComponent::send_archived_message(const Database::MucLogLine& log_lin
|
|||||||
|
|
||||||
bool BiboumiComponent::handle_room_configuration_form_request(const std::string& from, const Jid& to, const std::string& id)
|
bool BiboumiComponent::handle_room_configuration_form_request(const std::string& from, const Jid& to, const std::string& id)
|
||||||
{
|
{
|
||||||
Iid iid(to.local, {'#', '&'});
|
Iid iid(to.local, {'&', '#', '+', '!'});
|
||||||
|
|
||||||
if (iid.type != Iid::Type::Channel || !to.resource.empty())
|
if (iid.type != Iid::Type::Channel || !to.resource.empty())
|
||||||
return false;
|
return false;
|
||||||
@@ -887,7 +887,7 @@ bool BiboumiComponent::handle_room_configuration_form_request(const std::string&
|
|||||||
|
|
||||||
bool BiboumiComponent::handle_room_configuration_form(const XmlNode& query, const std::string &from, const Jid &to, const std::string &id)
|
bool BiboumiComponent::handle_room_configuration_form(const XmlNode& query, const std::string &from, const Jid &to, const std::string &id)
|
||||||
{
|
{
|
||||||
Iid iid(to.local, {'#', '&'});
|
Iid iid(to.local, {'&', '#', '+', '!'});
|
||||||
|
|
||||||
if (iid.type != Iid::Type::Channel || !to.resource.empty())
|
if (iid.type != Iid::Type::Channel || !to.resource.empty())
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
+2
-2
@@ -47,7 +47,7 @@ namespace Catch
|
|||||||
|
|
||||||
TEST_CASE("Iid creation")
|
TEST_CASE("Iid creation")
|
||||||
{
|
{
|
||||||
const std::set<char> chantypes {'#', '&'};
|
const std::set<char> chantypes {'&', '#', '+', '!'};
|
||||||
Iid iid1("foo%irc.example.org", chantypes);
|
Iid iid1("foo%irc.example.org", chantypes);
|
||||||
CHECK(std::to_string(iid1) == "foo%irc.example.org");
|
CHECK(std::to_string(iid1) == "foo%irc.example.org");
|
||||||
CHECK(iid1.get_local() == "foo");
|
CHECK(iid1.get_local() == "foo");
|
||||||
@@ -95,7 +95,7 @@ TEST_CASE("Iid creation in fixed_server mode")
|
|||||||
{
|
{
|
||||||
Config::set("fixed_irc_server", "fixed.example.com", false);
|
Config::set("fixed_irc_server", "fixed.example.com", false);
|
||||||
|
|
||||||
const std::set<char> chantypes {'#', '&'};
|
const std::set<char> chantypes {'&', '#', '+', '!'};
|
||||||
Iid iid1("foo%irc.example.org", chantypes);
|
Iid iid1("foo%irc.example.org", chantypes);
|
||||||
CHECK(std::to_string(iid1) == "foo%irc.example.org");
|
CHECK(std::to_string(iid1) == "foo%irc.example.org");
|
||||||
CHECK(iid1.get_local() == "foo%irc.example.org");
|
CHECK(iid1.get_local() == "foo%irc.example.org");
|
||||||
|
|||||||
Reference in New Issue
Block a user