From f612082f5d9490db4f462071513cdc1b3992e2db Mon Sep 17 00:00:00 2001 From: Uleat Date: Mon, 12 Jan 2015 01:42:27 -0500 Subject: [PATCH] Fix for OP_FormattedMessage text link server crashes --- changelog.txt | 3 +++ common/patches/rof.cpp | 12 +++++++----- common/patches/rof2.cpp | 12 +++++++----- common/patches/sod.cpp | 12 +++++++----- common/patches/sof.cpp | 12 +++++++----- common/patches/titanium.cpp | 12 +++++++----- common/patches/underfoot.cpp | 12 +++++++----- zone/client.cpp | 25 +++++++++++++++++-------- 8 files changed, 62 insertions(+), 38 deletions(-) diff --git a/changelog.txt b/changelog.txt index 51350d4a1..8ad64ad30 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,8 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- +== 01/12/2015 == +Uleat: Fix for OP_FormattedMessage text link server crashes + == 01/11/2015 == Uleat: Added text link translators for OP_TaskDescription (Ti thru UF..RoF+ in-work) diff --git a/common/patches/rof.cpp b/common/patches/rof.cpp index e8f6aa4b9..2ccac0803 100644 --- a/common/patches/rof.cpp +++ b/common/patches/rof.cpp @@ -877,7 +877,6 @@ namespace RoF unsigned char *__emu_buffer = in->pBuffer; - uint32 old_message_size = in->size - sizeof(FormattedMessage_Struct); std::string old_message_array[9]; char *old_message_ptr = (char *)__emu_buffer + sizeof(FormattedMessage_Struct); @@ -885,6 +884,7 @@ namespace RoF for (int i = 0; i < 9; ++i) { old_message_array[i] = old_message_ptr; old_message_ptr += old_message_array[i].length() + 1; + if (old_message_array[i].length() == 0) { break; } } uint32 new_message_size = 0; @@ -893,9 +893,10 @@ namespace RoF for (int i = 0; i < 9; ++i) { ServerToRoFTextLink(new_message_array[i], old_message_array[i]); new_message_size += (new_message_array[i].length() + 1); + if (new_message_array[i].length() == 0) { break; } } - in->size = sizeof(FormattedMessage_Struct) + new_message_size + 1; + in->size = sizeof(FormattedMessage_Struct) + new_message_size; in->pBuffer = new unsigned char[in->size]; char *OutBuffer = (char *)in->pBuffer; @@ -904,9 +905,10 @@ namespace RoF VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->string_id); VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->type); - for (int i = 0; i < 9; ++i) { VARSTRUCT_ENCODE_STRING(OutBuffer, new_message_array[i].c_str()); } - - VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, 0); + for (int i = 0; i < 9; ++i) { + VARSTRUCT_ENCODE_STRING(OutBuffer, new_message_array[i].c_str()); + if (new_message_array[i].length() == 0) { break; } + } delete[] __emu_buffer; dest->FastQueuePacket(&in, ack_req); diff --git a/common/patches/rof2.cpp b/common/patches/rof2.cpp index 4b1213277..10798be82 100644 --- a/common/patches/rof2.cpp +++ b/common/patches/rof2.cpp @@ -943,7 +943,6 @@ namespace RoF2 unsigned char *__emu_buffer = in->pBuffer; - uint32 old_message_size = in->size - sizeof(FormattedMessage_Struct); std::string old_message_array[9]; char *old_message_ptr = (char *)__emu_buffer + sizeof(FormattedMessage_Struct); @@ -951,6 +950,7 @@ namespace RoF2 for (int i = 0; i < 9; ++i) { old_message_array[i] = old_message_ptr; old_message_ptr += old_message_array[i].length() + 1; + if (old_message_array[i].length() == 0) { break; } } uint32 new_message_size = 0; @@ -959,9 +959,10 @@ namespace RoF2 for (int i = 0; i < 9; ++i) { ServerToRoF2TextLink(new_message_array[i], old_message_array[i]); new_message_size += (new_message_array[i].length() + 1); + if (new_message_array[i].length() == 0) { break; } } - in->size = sizeof(FormattedMessage_Struct) + new_message_size + 1; + in->size = sizeof(FormattedMessage_Struct) + new_message_size; in->pBuffer = new unsigned char[in->size]; char *OutBuffer = (char *)in->pBuffer; @@ -970,9 +971,10 @@ namespace RoF2 VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->string_id); VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->type); - for (int i = 0; i < 9; ++i) { VARSTRUCT_ENCODE_STRING(OutBuffer, new_message_array[i].c_str()); } - - VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, 0); + for (int i = 0; i < 9; ++i) { + VARSTRUCT_ENCODE_STRING(OutBuffer, new_message_array[i].c_str()); + if (new_message_array[i].length() == 0) { break; } + } delete[] __emu_buffer; dest->FastQueuePacket(&in, ack_req); diff --git a/common/patches/sod.cpp b/common/patches/sod.cpp index b3f60fb34..3938e238f 100644 --- a/common/patches/sod.cpp +++ b/common/patches/sod.cpp @@ -646,7 +646,6 @@ namespace SoD unsigned char *__emu_buffer = in->pBuffer; - uint32 old_message_size = in->size - sizeof(FormattedMessage_Struct); std::string old_message_array[9]; char *old_message_ptr = (char *)__emu_buffer + sizeof(FormattedMessage_Struct); @@ -654,6 +653,7 @@ namespace SoD for (int i = 0; i < 9; ++i) { old_message_array[i] = old_message_ptr; old_message_ptr += old_message_array[i].length() + 1; + if (old_message_array[i].length() == 0) { break; } } uint32 new_message_size = 0; @@ -662,9 +662,10 @@ namespace SoD for (int i = 0; i < 9; ++i) { ServerToSoDTextLink(new_message_array[i], old_message_array[i]); new_message_size += (new_message_array[i].length() + 1); + if (new_message_array[i].length() == 0) { break; } } - in->size = sizeof(FormattedMessage_Struct) + new_message_size + 1; + in->size = sizeof(FormattedMessage_Struct) + new_message_size; in->pBuffer = new unsigned char[in->size]; char *OutBuffer = (char *)in->pBuffer; @@ -673,9 +674,10 @@ namespace SoD VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->string_id); VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->type); - for (int i = 0; i < 9; ++i) { VARSTRUCT_ENCODE_STRING(OutBuffer, new_message_array[i].c_str()); } - - VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, 0); + for (int i = 0; i < 9; ++i) { + VARSTRUCT_ENCODE_STRING(OutBuffer, new_message_array[i].c_str()); + if (new_message_array[i].length() == 0) { break; } + } delete[] __emu_buffer; dest->FastQueuePacket(&in, ack_req); diff --git a/common/patches/sof.cpp b/common/patches/sof.cpp index e2d46a3ab..a9c5c0ea2 100644 --- a/common/patches/sof.cpp +++ b/common/patches/sof.cpp @@ -633,7 +633,6 @@ namespace SoF unsigned char *__emu_buffer = in->pBuffer; - uint32 old_message_size = in->size - sizeof(FormattedMessage_Struct); std::string old_message_array[9]; char *old_message_ptr = (char *)__emu_buffer + sizeof(FormattedMessage_Struct); @@ -641,6 +640,7 @@ namespace SoF for (int i = 0; i < 9; ++i) { old_message_array[i] = old_message_ptr; old_message_ptr += old_message_array[i].length() + 1; + if (old_message_array[i].length() == 0) { break; } } uint32 new_message_size = 0; @@ -649,9 +649,10 @@ namespace SoF for (int i = 0; i < 9; ++i) { ServerToSoFTextLink(new_message_array[i], old_message_array[i]); new_message_size += (new_message_array[i].length() + 1); + if (new_message_array[i].length() == 0) { break; } } - in->size = sizeof(FormattedMessage_Struct) + new_message_size + 1; + in->size = sizeof(FormattedMessage_Struct) + new_message_size; in->pBuffer = new unsigned char[in->size]; char *OutBuffer = (char *)in->pBuffer; @@ -660,9 +661,10 @@ namespace SoF VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->string_id); VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->type); - for (int i = 0; i < 9; ++i) { VARSTRUCT_ENCODE_STRING(OutBuffer, new_message_array[i].c_str()); } - - VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, 0); + for (int i = 0; i < 9; ++i) { + VARSTRUCT_ENCODE_STRING(OutBuffer, new_message_array[i].c_str()); + if (new_message_array[i].length() == 0) { break; } + } delete[] __emu_buffer; dest->FastQueuePacket(&in, ack_req); diff --git a/common/patches/titanium.cpp b/common/patches/titanium.cpp index 52b849176..500e5f128 100644 --- a/common/patches/titanium.cpp +++ b/common/patches/titanium.cpp @@ -492,7 +492,6 @@ namespace Titanium unsigned char *__emu_buffer = in->pBuffer; - uint32 old_message_size = in->size - sizeof(FormattedMessage_Struct); std::string old_message_array[9]; char *old_message_ptr = (char *)__emu_buffer + sizeof(FormattedMessage_Struct); @@ -500,6 +499,7 @@ namespace Titanium for (int i = 0; i < 9; ++i) { old_message_array[i] = old_message_ptr; old_message_ptr += old_message_array[i].length() + 1; + if (old_message_array[i].length() == 0) { break; } } uint32 new_message_size = 0; @@ -508,9 +508,10 @@ namespace Titanium for (int i = 0; i < 9; ++i) { ServerToTitaniumTextLink(new_message_array[i], old_message_array[i]); new_message_size += (new_message_array[i].length() + 1); + if (new_message_array[i].length() == 0) { break; } } - in->size = sizeof(FormattedMessage_Struct) + new_message_size + 1; + in->size = sizeof(FormattedMessage_Struct) + new_message_size; in->pBuffer = new unsigned char[in->size]; char *OutBuffer = (char *)in->pBuffer; @@ -519,9 +520,10 @@ namespace Titanium VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->string_id); VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->type); - for (int i = 0; i < 9; ++i) { VARSTRUCT_ENCODE_STRING(OutBuffer, new_message_array[i].c_str()); } - - VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, 0); + for (int i = 0; i < 9; ++i) { + VARSTRUCT_ENCODE_STRING(OutBuffer, new_message_array[i].c_str()); + if (new_message_array[i].length() == 0) { break; } + } delete[] __emu_buffer; dest->FastQueuePacket(&in, ack_req); diff --git a/common/patches/underfoot.cpp b/common/patches/underfoot.cpp index 426d70ef0..5a07fed7e 100644 --- a/common/patches/underfoot.cpp +++ b/common/patches/underfoot.cpp @@ -790,7 +790,6 @@ namespace Underfoot unsigned char *__emu_buffer = in->pBuffer; - uint32 old_message_size = in->size - sizeof(FormattedMessage_Struct); std::string old_message_array[9]; char *old_message_ptr = (char *)__emu_buffer + sizeof(FormattedMessage_Struct); @@ -798,6 +797,7 @@ namespace Underfoot for (int i = 0; i < 9; ++i) { old_message_array[i] = old_message_ptr; old_message_ptr += old_message_array[i].length() + 1; + if (old_message_array[i].length() == 0) { break; } } uint32 new_message_size = 0; @@ -806,9 +806,10 @@ namespace Underfoot for (int i = 0; i < 9; ++i) { ServerToUnderfootTextLink(new_message_array[i], old_message_array[i]); new_message_size += (new_message_array[i].length() + 1); + if (new_message_array[i].length() == 0) { break; } } - in->size = sizeof(FormattedMessage_Struct) + new_message_size + 1; + in->size = sizeof(FormattedMessage_Struct) + new_message_size; in->pBuffer = new unsigned char[in->size]; char *OutBuffer = (char *)in->pBuffer; @@ -817,9 +818,10 @@ namespace Underfoot VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->string_id); VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->type); - for (int i = 0; i < 9; ++i) { VARSTRUCT_ENCODE_STRING(OutBuffer, new_message_array[i].c_str()); } - - VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, 0); + for (int i = 0; i < 9; ++i) { + VARSTRUCT_ENCODE_STRING(OutBuffer, new_message_array[i].c_str()); + if (new_message_array[i].length() == 0) { break; } + } delete[] __emu_buffer; dest->FastQueuePacket(&in, ack_req); diff --git a/zone/client.cpp b/zone/client.cpp index d8c24d1ba..55775943c 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -2813,7 +2813,7 @@ void Client::Message_StringID(uint32 type, uint32 string_id, const char* message if (GetFilter(FilterDamageShields) == FilterHide && type == MT_DS) return; - int i, argcount, length; + int i = 0, argcount = 0, length = 0; char *bufptr; const char *message_arg[9] = {0}; @@ -2826,7 +2826,6 @@ void Client::Message_StringID(uint32 type, uint32 string_id, const char* message return; } - i = 0; message_arg[i++] = message1; message_arg[i++] = message2; message_arg[i++] = message3; @@ -2837,10 +2836,13 @@ void Client::Message_StringID(uint32 type, uint32 string_id, const char* message message_arg[i++] = message8; message_arg[i++] = message9; - for(argcount = length = 0; message_arg[argcount]; argcount++) + for(; message_arg[argcount]; ++argcount) length += strlen(message_arg[argcount]) + 1; - EQApplicationPacket* outapp = new EQApplicationPacket(OP_FormattedMessage, length+13); + if (length == 0) + length = 1; + + EQApplicationPacket* outapp = new EQApplicationPacket(OP_FormattedMessage, sizeof(FormattedMessage_Struct) + length); FormattedMessage_Struct *fm = (FormattedMessage_Struct *)outapp->pBuffer; fm->string_id = string_id; fm->type = type; @@ -2851,6 +2853,8 @@ void Client::Message_StringID(uint32 type, uint32 string_id, const char* message bufptr += strlen(message_arg[i]) + 1; } + if (argcount == 0) + bufptr = '\0'; if(distance>0) entity_list.QueueCloseClients(this,outapp,false,distance); @@ -2925,7 +2929,7 @@ void Client::FilteredMessage_StringID(Mob *sender, uint32 type, eqFilterType fil if (!FilteredMessageCheck(sender, filter)) return; - int i, argcount, length; + int i = 0, argcount = 0, length = 0; char *bufptr; const char *message_arg[9] = {0}; @@ -2937,7 +2941,6 @@ void Client::FilteredMessage_StringID(Mob *sender, uint32 type, eqFilterType fil return; } - i = 0; message_arg[i++] = message1; message_arg[i++] = message2; message_arg[i++] = message3; @@ -2948,10 +2951,13 @@ void Client::FilteredMessage_StringID(Mob *sender, uint32 type, eqFilterType fil message_arg[i++] = message8; message_arg[i++] = message9; - for (argcount = length = 0; message_arg[argcount]; argcount++) + for (; message_arg[argcount]; ++argcount) length += strlen(message_arg[argcount]) + 1; - EQApplicationPacket *outapp = new EQApplicationPacket(OP_FormattedMessage, length+13); + if (length == 0) + length = 1; + + EQApplicationPacket *outapp = new EQApplicationPacket(OP_FormattedMessage, sizeof(FormattedMessage_Struct) + length); FormattedMessage_Struct *fm = (FormattedMessage_Struct *)outapp->pBuffer; fm->string_id = string_id; fm->type = type; @@ -2961,6 +2967,9 @@ void Client::FilteredMessage_StringID(Mob *sender, uint32 type, eqFilterType fil bufptr += strlen(message_arg[i]) + 1; } + if (argcount == 0) + bufptr = '\0'; + QueuePacket(outapp); safe_delete(outapp); }