forked from hiimgoodpack/brainlet-client
Add better escaping
This commit is contained in:
parent
2a4c54ad53
commit
1c52e0f370
1 changed files with 26 additions and 4 deletions
30
brainlet.h
30
brainlet.h
|
@ -73,7 +73,8 @@ namespace Brainlet {
|
||||||
State state = NOT_CONNECTED;
|
State state = NOT_CONNECTED;
|
||||||
|
|
||||||
static void onReceive(Client* client, std::string buffer);
|
static void onReceive(Client* client, std::string buffer);
|
||||||
void encode(std::string& string); ///< Encodes a string to a JSON value
|
void escapeJSON(std::string& string); ///< Escapes a string to a JSON value
|
||||||
|
void escapeOutput(std::string& string); ///< Escapes a string to output safely
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::function<void(Channel)> onNewChannel = nullptr;
|
std::function<void(Channel)> onNewChannel = nullptr;
|
||||||
|
@ -112,7 +113,7 @@ namespace Brainlet {
|
||||||
namespace Brainlet {
|
namespace Brainlet {
|
||||||
Client::Client(const std::string& domain) : domain(domain) {}
|
Client::Client(const std::string& domain) : domain(domain) {}
|
||||||
|
|
||||||
void Client::encode(std::string& string) {
|
void Client::escapeJSON(std::string& string) {
|
||||||
std::string result;
|
std::string result;
|
||||||
result.reserve(string.size());
|
result.reserve(string.size());
|
||||||
|
|
||||||
|
@ -131,6 +132,20 @@ namespace Brainlet {
|
||||||
|
|
||||||
string = std::move(result);
|
string = std::move(result);
|
||||||
}
|
}
|
||||||
|
void Client::escapeOutput(std::string& string) {
|
||||||
|
std::string result;
|
||||||
|
result.reserve(string.size());
|
||||||
|
|
||||||
|
std::for_each(string.begin(), string.end(), [&](const char character) {
|
||||||
|
switch (character) {
|
||||||
|
case '\b':
|
||||||
|
case '\x1f': result.push_back('?'); break;
|
||||||
|
default: result.push_back(character); break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
string = std::move(result);
|
||||||
|
}
|
||||||
void Client::processNextEvent() {
|
void Client::processNextEvent() {
|
||||||
socket->run_until(
|
socket->run_until(
|
||||||
// Stop in 250 microseconds
|
// Stop in 250 microseconds
|
||||||
|
@ -172,7 +187,9 @@ namespace Brainlet {
|
||||||
bool didError = value.get("error", true).asBool();
|
bool didError = value.get("error", true).asBool();
|
||||||
if (didError) {
|
if (didError) {
|
||||||
// TODO: Use exception
|
// TODO: Use exception
|
||||||
std::cerr << "Error while logging in: " << value.get("message", "Server did not specify error").asString() << "\n";
|
std::string error = value.get("message", "Server did not specify error").asString();
|
||||||
|
escapeOutput(error);
|
||||||
|
std::cerr << "Error while logging in: " << error << "\n";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -210,6 +227,7 @@ namespace Brainlet {
|
||||||
case NOT_CONNECTED: throw std::logic_error("Buffer was received while client is not connected");
|
case NOT_CONNECTED: throw std::logic_error("Buffer was received while client is not connected");
|
||||||
case WAIT_HELLO: {
|
case WAIT_HELLO: {
|
||||||
if (opcode != HELLO) {
|
if (opcode != HELLO) {
|
||||||
|
escapeOutput(buffer);
|
||||||
std::cerr << "Failed authentication: Expected HELLO packet, received: " << buffer << "\n";
|
std::cerr << "Failed authentication: Expected HELLO packet, received: " << buffer << "\n";
|
||||||
client->socket->close();
|
client->socket->close();
|
||||||
return;
|
return;
|
||||||
|
@ -225,6 +243,7 @@ namespace Brainlet {
|
||||||
}
|
}
|
||||||
case WAIT_ACK: {
|
case WAIT_ACK: {
|
||||||
if (opcode != YOO_ACK) {
|
if (opcode != YOO_ACK) {
|
||||||
|
escapeOutput(buffer);
|
||||||
std::cerr << "Failed authentication: Expected YOO_ACK packet, received: " << buffer << "\n";
|
std::cerr << "Failed authentication: Expected YOO_ACK packet, received: " << buffer << "\n";
|
||||||
client->socket->close();
|
client->socket->close();
|
||||||
return;
|
return;
|
||||||
|
@ -243,6 +262,7 @@ namespace Brainlet {
|
||||||
if (client->onNewChannel)
|
if (client->onNewChannel)
|
||||||
client->onNewChannel(channelObject);
|
client->onNewChannel(channelObject);
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
case READY: {
|
case READY: {
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
|
@ -260,15 +280,17 @@ namespace Brainlet {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
|
escapeOutput(buffer);
|
||||||
std::cerr << "Unknown opcode " << opcode << ". Buffer " << buffer << "\n";
|
std::cerr << "Unknown opcode " << opcode << ". Buffer " << buffer << "\n";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void Client::sendMessage(std::string message, std::string channelId) {
|
void Client::sendMessage(std::string message, std::string channelId) {
|
||||||
encode(message);
|
escapeJSON(message);
|
||||||
|
|
||||||
std::ostringstream bufferToSend;
|
std::ostringstream bufferToSend;
|
||||||
bufferToSend << ACTION_CREATE_MESSAGE << "@" << R"({"content":")" << message << R"(","channel":{"_id":")" << channelId << R"("}})";
|
bufferToSend << ACTION_CREATE_MESSAGE << "@" << R"({"content":")" << message << R"(","channel":{"_id":")" << channelId << R"("}})";
|
||||||
|
|
Reference in a new issue