Properly counting group name lengths and fixed a crash on server create when the group creation process failed

This commit is contained in:
WolverinDEV 2021-04-28 18:32:00 +02:00
parent 8710f0c31b
commit 25d57ce825
5 changed files with 44 additions and 20 deletions

View File

@ -2,6 +2,7 @@
#include <log/LogUtils.h>
#include <misc/memtracker.h>
#include <misc/sassert.h>
#include <misc/utf8.h>
#include "misc/rnd.h"
#include "src/VirtualServer.h"
#include "src/client/ConnectedClient.h"
@ -426,8 +427,8 @@ bool ServerChannelTree::validateChannelNames() {
}
*/
for(const auto &channel : this->channels()){
auto name_length = count_characters(channel->name());
for(const auto &channel : this->channels()) {
auto name_length = utf8::count_characters(channel->name());
if(name_length > 40) {
logError(this->getServerId(), "Channel {} loaded an invalid name from the database (name to long). Cutting channel name");
channel->properties()[property::CHANNEL_NAME] = channel->name().substr(0, 40); //FIXME count UTF8

View File

@ -8,6 +8,7 @@
#include <src/build.h>
#include <Properties.h>
#include <src/client/command_handler/helpers.h>
#include <misc/utf8.h>
#include "src/channel/ClientChannelView.h"
#include "SpeakingClient.h"
#include "src/InstanceHandler.h"
@ -100,20 +101,21 @@ command_result SpeakingClient::applyClientInitParameters(Command &cmd) {
/* That's ok */
continue;
} else if(key == "client_nickname") {
auto name = cmd[key].string();
if (count_characters(name) < 3) {
auto name_length = utf8::count_characters(cmd[key].string());
if (name_length < 3) {
return command_result{error::parameter_invalid, "client_nickname"};
}
if (count_characters(name) > 30) {
if (name_length > 30) {
return command_result{error::parameter_invalid, "client_nickname"};
}
/* The unique of the name will be checked when registering the client at the target server */
this->properties()[property::CLIENT_NICKNAME] = name;
this->properties()[property::CLIENT_NICKNAME] = cmd[key].string();
} else if(key == "client_nickname_phonetic") {
auto name = cmd["client_nickname_phonetic"].string();
if (count_characters(name) > 30) {
auto name_length = utf8::count_characters(name);
if (name_length < 0 || name_length > 30) {
return command_result{error::parameter_invalid, "client_nickname_phonetic"};
}
this->properties()[property::CLIENT_NICKNAME_PHONETIC] = name;

View File

@ -25,6 +25,7 @@
#include <log/LogUtils.h>
#include <misc/base64.h>
#include <misc/digest.h>
#include <misc/utf8.h>
using namespace std::chrono;
using namespace std;
@ -886,8 +887,8 @@ ts::command_result ConnectedClient::execute_channel_edit(ChannelId& channel_id,
case property::CHANNEL_NAME:
case property::CHANNEL_NAME_PHONETIC: {
auto length = count_characters(value);
if(length > 40) {
auto length = utf8::count_characters(value);
if(length < 0 || length > 40) {
/* max channel name length is 40 */
return ts::command_result{error::parameter_invalid, std::string{property::describe(property).name}};
}

View File

@ -26,6 +26,7 @@
#include <misc/hex.h>
#include <misc/rnd.h>
#include <bbcode/bbcodes.h>
#include <misc/utf8.h>
using namespace std::chrono;
using namespace std;
@ -346,16 +347,19 @@ command_result ConnectedClient::handleCommandClientPoke(Command &cmd) {
if(clients.size() > 1) {
auto max_clients = this->calculate_permission(permission::i_client_poke_max_clients, 0);
if(!permission::v2::permission_granted(clients.size(), max_clients))
if(!permission::v2::permission_granted(clients.size(), max_clients)) {
return command_result{permission::i_client_poke_max_clients};
}
}
auto message = cmd["msg"].string();
if(count_characters(message) > ts::config::server::limits::poke_message_length)
if(utf8::count_characters(message) > ts::config::server::limits::poke_message_length) {
return command_result{error::parameter_invalid_size, "msg"};
}
for(auto& client : clients)
for(auto& client : clients) {
client->notifyClientPoke(this->ref(), message);
}
return command_result{std::forward<command_result_bulk>(result)};
}
@ -535,7 +539,10 @@ command_result ConnectedClient::handleCommandClientEdit(Command &cmd, const std:
}
string value = cmd["client_description"].string();
if (count_characters(value) > 200) return command_result{error::parameter_invalid, "Invalid description length. A maximum of 200 characters is allowed!"};
auto value_length = utf8::count_characters(value);
if (value_length < 0 || value_length > 200) {
return command_result{error::parameter_invalid, "Invalid description length. A maximum of 200 characters is allowed!"};
}
} else if (info == property::CLIENT_IS_TALKER) {
ACTION_REQUIRES_PERMISSION(permission::b_client_set_flag_talker, 1, client->getChannelId());
cmd["client_is_talker"] = cmd["client_is_talker"].as<bool>();
@ -554,8 +561,13 @@ command_result ConnectedClient::handleCommandClientEdit(Command &cmd, const std:
}
string name = cmd["client_nickname"].string();
if (count_characters(name) < 3) return command_result{error::parameter_invalid, "Invalid name length. A minimum of 3 characters is required!"};
if (count_characters(name) > 30) return command_result{error::parameter_invalid, "Invalid name length. A maximum of 30 characters is allowed!"};
auto name_length = utf8::count_characters(name);
if (name_length < 3) {
return command_result{error::parameter_invalid, "Invalid name length. A minimum of 3 characters is required!"};
}
if (name_length > 30) {
return command_result{error::parameter_invalid, "Invalid name length. A maximum of 30 characters is allowed!"};
}
if (!permission::v2::permission_granted(1, this->calculate_permission(permission::b_client_ignore_bans, client->getClientId()))) {
auto banRecord = serverInstance->banManager()->findBanByName(this->getServerId(), name);
@ -587,7 +599,10 @@ command_result ConnectedClient::handleCommandClientEdit(Command &cmd, const std:
}
string name = cmd["client_nickname_phonetic"].string();
if (count_characters(name) > 30) return command_result{error::parameter_invalid, "Invalid name length. A maximum of 30 characters is allowed!"};
auto name_length = utf8::count_characters(name);
if (name_length < 0 || name_length > 30) {
return command_result{error::parameter_invalid, "Invalid name length. A maximum of 30 characters is allowed!"};
}
} else if(info == property::CLIENT_PLAYER_VOLUME) {
if(client->getType() != ClientType::CLIENT_MUSIC) return command_result{error::client_invalid_type};
if(client->properties()[property::CLIENT_OWNER] != this->getClientDatabaseId()) {

View File

@ -2,10 +2,12 @@
// Created by WolverinDEV on 03/03/2020.
//
#include <string>
#include <misc/utf8.h>
#include <log/LogUtils.h>
#include "./GroupManager.h"
#include "../InstanceHandler.h"
constexpr static auto kGroupMaxNameLength{40};
using namespace ts::server::groups;
GroupManager::GroupManager(sql::SqlManager *sql, ServerId server_id, std::shared_ptr<GroupManager> parent)
@ -161,9 +163,10 @@ void AbstractGroupManager::reset_groups(std::map<GroupId, GroupId> &mapping) {
case GroupCopyResult::UNKNOWN_SOURCE_GROUP:
case GroupCopyResult::DATABASE_ERROR:
logCritical(this->server_id(), "Failed to copy template group {}: {}", group->group_id(), (uint8_t) result);
break;
continue;
}
assert(created_group);
logTrace(this->server_id(), "Copied template group {}. New id: {}", group->group_id(), created_group->group_id());
mapping[group->group_id()] = created_group->group_id();
}
@ -269,9 +272,10 @@ std::shared_ptr<Group> AbstractGroupManager::find_group_by_name_(GroupCalculateM
}
GroupCreateResult AbstractGroupManager::create_group_(GroupType type, const std::string &name, std::shared_ptr<Group>& result) {
if(name.empty()) {
auto name_length = utf8::count_characters(name);
if(name_length <= 0) {
return GroupCreateResult::NAME_TOO_SHORT;
} else if(name.length() > 30) {
} else if(name_length > kGroupMaxNameLength) {
return GroupCreateResult::NAME_TOO_LONG;
}
@ -377,7 +381,8 @@ GroupCopyResult AbstractGroupManager::copy_group_permissions_(GroupId source, Gr
GroupRenameResult AbstractGroupManager::rename_group_(GroupId group_id, const std::string &name) {
std::lock_guard manage_lock{this->group_manage_mutex_};
if(name.empty() || name.length() > 40) {
auto name_length = utf8::count_characters(name);
if(name_length <= 0 || name_length > kGroupMaxNameLength) {
return GroupRenameResult::NAME_INVALID;
}