[Fix] Clean up Filtered/MessageString functions (#1311)

This solves the OOB issue pointed out in #1304 and cleans up the code a
bit so it should be less error prone
This commit is contained in:
Michael Cook (mackal) 2021-03-29 03:18:03 -04:00 committed by GitHub
parent 049fe55c7f
commit f51bc4daaf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 39 additions and 69 deletions

View File

@ -3247,7 +3247,7 @@ struct TraderClick_Struct{
}; };
struct FormattedMessage_Struct{ struct FormattedMessage_Struct{
uint32 unknown0; uint32 unknown0; // 1 means from world server
uint32 string_id; uint32 string_id;
uint32 type; uint32 type;
char message[0]; char message[0];
@ -3255,7 +3255,7 @@ struct FormattedMessage_Struct{
struct SimpleMessage_Struct{ struct SimpleMessage_Struct{
uint32 string_id; uint32 string_id;
uint32 color; uint32 color;
uint32 unknown8; uint32 unknown8; // 1 means from world server
}; };
struct GuildMemberUpdate_Struct { struct GuildMemberUpdate_Struct {

View File

@ -3161,53 +3161,37 @@ void Client::MessageString(uint32 type, uint32 string_id, const char* message1,
if (GetFilter(FilterDamageShields) == FilterHide && type == Chat::DamageShield) if (GetFilter(FilterDamageShields) == FilterHide && type == Chat::DamageShield)
return; return;
int i = 0, argcount = 0, length = 0; if (type == Chat::Emote)
char *bufptr = nullptr; type = 4;
const char *message_arg[9] = {0};
if(type==Chat::Emote) if (!message1) {
type=4;
if(!message1)
{
MessageString(type, string_id); // use the simple message instead MessageString(type, string_id); // use the simple message instead
return; return;
} }
message_arg[i++] = message1; const char *message_arg[] = {
message_arg[i++] = message2; message1, message2, message3, message4, message5,
message_arg[i++] = message3; message6, message7, message8, message9
message_arg[i++] = message4; };
message_arg[i++] = message5;
message_arg[i++] = message6;
message_arg[i++] = message7;
message_arg[i++] = message8;
message_arg[i++] = message9;
for(; message_arg[argcount]; ++argcount) SerializeBuffer buf(20);
length += strlen(message_arg[argcount]) + 1; buf.WriteInt32(0); // unknown
buf.WriteInt32(string_id);
length += 1; buf.WriteInt32(type);
for (auto &m : message_arg) {
auto outapp = new EQApplicationPacket(OP_FormattedMessage, sizeof(FormattedMessage_Struct) + length); if (m == nullptr)
FormattedMessage_Struct *fm = (FormattedMessage_Struct *)outapp->pBuffer; break;
fm->string_id = string_id; buf.WriteString(m);
fm->type = type;
bufptr = fm->message;
for(i = 0; i < argcount; i++)
{
strcpy(bufptr, message_arg[i]);
bufptr += strlen(message_arg[i]) + 1;
} }
// since we're moving the pointer the 0 offset is correct buf.WriteInt8(0); // prevent oob in packet translation, maybe clean that up sometime
bufptr[0] = '\0';
if(distance>0) auto outapp = std::make_unique<EQApplicationPacket>(OP_FormattedMessage, buf);
entity_list.QueueCloseClients(this,outapp,false,distance);
if (distance > 0)
entity_list.QueueCloseClients(this, outapp.get(), false, distance);
else else
QueuePacket(outapp); QueuePacket(outapp.get());
safe_delete(outapp);
} }
void Client::MessageString(const CZClientMessageString_Struct* msg) void Client::MessageString(const CZClientMessageString_Struct* msg)
@ -3297,10 +3281,6 @@ void Client::FilteredMessageString(Mob *sender, uint32 type, eqFilterType filter
if (!FilteredMessageCheck(sender, filter)) if (!FilteredMessageCheck(sender, filter))
return; return;
int i = 0, argcount = 0, length = 0;
char *bufptr = nullptr;
const char *message_arg[9] = {0};
if (type == Chat::Emote) if (type == Chat::Emote)
type = 4; type = 4;
@ -3309,36 +3289,26 @@ void Client::FilteredMessageString(Mob *sender, uint32 type, eqFilterType filter
return; return;
} }
message_arg[i++] = message1; const char *message_arg[] = {
message_arg[i++] = message2; message1, message2, message3, message4, message5,
message_arg[i++] = message3; message6, message7, message8, message9
message_arg[i++] = message4; };
message_arg[i++] = message5;
message_arg[i++] = message6;
message_arg[i++] = message7;
message_arg[i++] = message8;
message_arg[i++] = message9;
for (; message_arg[argcount]; ++argcount) SerializeBuffer buf(20);
length += strlen(message_arg[argcount]) + 1; buf.WriteInt32(0); // unknown
buf.WriteInt32(string_id);
length += 1; buf.WriteInt32(type);
for (auto &m : message_arg) {
auto outapp = new EQApplicationPacket(OP_FormattedMessage, sizeof(FormattedMessage_Struct) + length); if (m == nullptr)
FormattedMessage_Struct *fm = (FormattedMessage_Struct *)outapp->pBuffer; break;
fm->string_id = string_id; buf.WriteString(m);
fm->type = type;
bufptr = fm->message;
for (i = 0; i < argcount; i++) {
strcpy(bufptr, message_arg[i]);
bufptr += strlen(message_arg[i]) + 1;
} }
// since we're moving the pointer the 0 offset is correct buf.WriteInt8(0); // prevent oob in packet translation, maybe clean that up sometime
bufptr[0] = '\0';
QueuePacket(outapp); auto outapp = std::make_unique<EQApplicationPacket>(OP_FormattedMessage, buf);
safe_delete(outapp);
QueuePacket(outapp.get());
} }
void Client::Tell_StringID(uint32 string_id, const char *who, const char *message) void Client::Tell_StringID(uint32 string_id, const char *who, const char *message)