* Fixed public/guild chat message packets sending strings without zero-termination causing recent clients to display trailing junk on such messages (bugreport:5068).

- Changed memcpy to safestrncpy in message packets where overlong messages are truncated (thus loose zero-termination).
- Replaced dynamic allocation in clif_guild_message with buffer from stack.
- Fixed clif_disp_message not checking whether the message fits into provided buffer.

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@14975 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
ai4rei 2011-10-16 06:26:40 +00:00
parent b6e6bec3c6
commit 256fd34dab
3 changed files with 56 additions and 49 deletions

View File

@ -1,5 +1,10 @@
Date Added Date Added
2011/10/16
* Fixed public/guild chat message packets sending strings without zero-termination causing recent clients to display trailing junk on such messages (bugreport:5068). [Ai4rei]
- Changed memcpy to safestrncpy in message packets where overlong messages are truncated (thus loose zero-termination).
- Replaced dynamic allocation in clif_guild_message with buffer from stack.
- Fixed clif_disp_message not checking whether the message fits into provided buffer.
2011/10/15 2011/10/15
* Some readme clean-ups (related r14711). [Ai4rei] * Some readme clean-ups (related r14711). [Ai4rei]
- Normalized whitespace and made the html files validate properly. - Normalized whitespace and made the html files validate properly.

View File

@ -5028,7 +5028,7 @@ void clif_GlobalMessage(struct block_list* bl, const char* message)
WBUFW(buf,0)=0x8d; WBUFW(buf,0)=0x8d;
WBUFW(buf,2)=len+8; WBUFW(buf,2)=len+8;
WBUFL(buf,4)=bl->id; WBUFL(buf,4)=bl->id;
strncpy((char *) WBUFP(buf,8),message,len); safestrncpy((char *) WBUFP(buf,8),message,len);
clif_send((unsigned char *) buf,WBUFW(buf,2),bl,ALL_CLIENT); clif_send((unsigned char *) buf,WBUFW(buf,2),bl,ALL_CLIENT);
} }
@ -5037,7 +5037,7 @@ void clif_GlobalMessage(struct block_list* bl, const char* message)
*------------------------------------------*/ *------------------------------------------*/
void clif_MainChatMessage(const char* message) void clif_MainChatMessage(const char* message)
{ {
char buf[200]; uint8 buf[200];
int len; int len;
if(!message) if(!message)
@ -5051,8 +5051,8 @@ void clif_MainChatMessage(const char* message)
WBUFW(buf,0)=0x8d; WBUFW(buf,0)=0x8d;
WBUFW(buf,2)=len+8; WBUFW(buf,2)=len+8;
WBUFL(buf,4)=0; WBUFL(buf,4)=0;
strncpy((char *) WBUFP(buf,8),message,len); safestrncpy((char *) WBUFP(buf,8),message,len);
clif_send((unsigned char *) buf,WBUFW(buf,2),NULL,CHAT_MAINCHAT); clif_send(buf,WBUFW(buf,2),NULL,CHAT_MAINCHAT);
} }
/*========================================== /*==========================================
@ -7147,27 +7147,33 @@ void clif_guild_expulsionlist(struct map_session_data* sd)
WFIFOSET(fd,WFIFOW(fd,2)); WFIFOSET(fd,WFIFOW(fd,2));
} }
/*==========================================
* ƒƒhï˜b
*------------------------------------------*/
int clif_guild_message(struct guild *g,int account_id,const char *mes,int len)
{
struct map_session_data *sd;
unsigned char *buf;
buf = (unsigned char*)aMallocA((len + 4)*sizeof(unsigned char)); /// Notification of a guild chat message (ZC_GUILD_CHAT)
/// 017f <packet len>.W <message>.?B
void clif_guild_message(struct guild *g,int account_id,const char *mes,int len)
{// TODO: account_id is not used, candidate for deletion? [Ai4rei]
struct map_session_data *sd;
uint8 buf[256];
if( len == 0 )
{
return;
}
else if( len > sizeof(buf)-5 )
{
ShowWarning("clif_guild_message: Truncated message '%s' (len=%d, max=%d, guild_id=%d).\n", mes, len, sizeof(buf)-5, g->guild_id);
len = sizeof(buf)-5;
}
WBUFW(buf, 0) = 0x17f; WBUFW(buf, 0) = 0x17f;
WBUFW(buf, 2) = len + 4; WBUFW(buf, 2) = len + 5;
memcpy(WBUFP(buf,4), mes, len); safestrncpy((char*)WBUFP(buf,4), mes, len+1);
if ((sd = guild_getavailablesd(g)) != NULL) if ((sd = guild_getavailablesd(g)) != NULL)
clif_send(buf, WBUFW(buf,2), &sd->bl, GUILD_NOBG); clif_send(buf, WBUFW(buf,2), &sd->bl, GUILD_NOBG);
if(buf) aFree(buf);
return 0;
} }
/*========================================== /*==========================================
* *
*------------------------------------------*/ *------------------------------------------*/
@ -7409,18 +7415,9 @@ void clif_parse_ReqMarriage(int fd, struct map_session_data *sd)
/*========================================== /*==========================================
* *
*------------------------------------------*/ *------------------------------------------*/
int clif_disp_onlyself(struct map_session_data *sd, const char *mes, int len) void clif_disp_onlyself(struct map_session_data *sd, const char *mes, int len)
{ {
int fd; clif_disp_message(&sd->bl, mes, len, SELF);
nullpo_ret(sd);
fd = sd->fd;
if (!fd || !len) return 0; //Disconnected player.
WFIFOHEAD(fd, len+5);
WFIFOW(fd, 0) = 0x17f;
WFIFOW(fd, 2) = len + 5;
memcpy(WFIFOP(fd,4), mes, len);
WFIFOSET(fd, WFIFOW(fd,2));
return 1;
} }
/*========================================== /*==========================================
@ -7428,13 +7425,22 @@ int clif_disp_onlyself(struct map_session_data *sd, const char *mes, int len)
*------------------------------------------*/ *------------------------------------------*/
void clif_disp_message(struct block_list* src, const char* mes, int len, enum send_target target) void clif_disp_message(struct block_list* src, const char* mes, int len, enum send_target target)
{ {
unsigned char buf[1024]; unsigned char buf[256];
if (!len) return;
if( len == 0 )
{
return;
}
else if( len > sizeof(buf)-5 )
{
ShowWarning("clif_disp_message: Truncated message '%s' (len=%d, max=%d, aid=%d).\n", mes, len, sizeof(buf)-5, src->id);
len = sizeof(buf)-5;
}
WBUFW(buf, 0) = 0x17f; WBUFW(buf, 0) = 0x17f;
WBUFW(buf, 2) = len + 5; WBUFW(buf, 2) = len + 5;
memcpy(WBUFP(buf,4), mes, len); safestrncpy((char*)WBUFP(buf,4), mes, len+1);
clif_send(buf, WBUFW(buf,2), src, target); clif_send(buf, WBUFW(buf,2), src, target);
return;
} }
/*========================================== /*==========================================
@ -7657,12 +7663,12 @@ int clif_messagecolor(struct block_list* bl, unsigned long color, const char* ms
} }
// messages (from mobs/npcs) [Valaris] // messages (from mobs/npcs) [Valaris]
int clif_message(struct block_list* bl, const char* msg) void clif_message(struct block_list* bl, const char* msg)
{ {
unsigned short msg_len = strlen(msg) + 1; unsigned short msg_len = strlen(msg) + 1;
uint8 buf[256]; uint8 buf[256];
nullpo_ret(bl); nullpo_retv(bl);
if( msg_len > sizeof(buf)-8 ) if( msg_len > sizeof(buf)-8 )
{ {
@ -7673,11 +7679,9 @@ int clif_message(struct block_list* bl, const char* msg)
WBUFW(buf,0) = 0x8d; WBUFW(buf,0) = 0x8d;
WBUFW(buf,2) = msg_len + 8; WBUFW(buf,2) = msg_len + 8;
WBUFL(buf,4) = bl->id; WBUFL(buf,4) = bl->id;
memcpy(WBUFP(buf,8), msg, msg_len); safestrncpy((char*)WBUFP(buf,8), msg, msg_len);
clif_send(buf, WBUFW(buf,2), bl, AREA_CHAT_WOC); clif_send(buf, WBUFW(buf,2), bl, AREA_CHAT_WOC);
return 0;
} }
// refresh the client's screen, getting rid of any effects // refresh the client's screen, getting rid of any effects
@ -7951,29 +7955,27 @@ void clif_slide(struct block_list *bl, int x, int y)
/*------------------------------------------ /*------------------------------------------
* @me command by lordalfa, rewritten implementation by Skotlex * @me command by lordalfa, rewritten implementation by Skotlex
*------------------------------------------*/ *------------------------------------------*/
int clif_disp_overhead(struct map_session_data *sd, const char* mes) void clif_disp_overhead(struct map_session_data *sd, const char* mes)
{ {
unsigned char buf[256]; //This should be more than sufficient, the theorical max is CHAT_SIZE + 8 (pads and extra inserted crap) unsigned char buf[256]; //This should be more than sufficient, the theorical max is CHAT_SIZE + 8 (pads and extra inserted crap)
int len_mes = strlen(mes)+1; //Account for \0 int len_mes = strlen(mes)+1; //Account for \0
if (len_mes + 8 >= 256) { if (len_mes > sizeof(buf)-8) {
ShowError("clif_disp_overhead: Message too long (length %d)\n", len_mes); ShowError("clif_disp_overhead: Message too long (length %d)\n", len_mes);
len_mes = 247; //Trunk it to avoid problems. len_mes = sizeof(buf)-8; //Trunk it to avoid problems.
} }
// send message to others // send message to others
WBUFW(buf,0) = 0x8d; WBUFW(buf,0) = 0x8d;
WBUFW(buf,2) = len_mes + 8; // len of message + 8 (command+len+id) WBUFW(buf,2) = len_mes + 8; // len of message + 8 (command+len+id)
WBUFL(buf,4) = sd->bl.id; WBUFL(buf,4) = sd->bl.id;
memcpy(WBUFP(buf,8), mes, len_mes); safestrncpy((char*)WBUFP(buf,8), mes, len_mes);
clif_send(buf, WBUFW(buf,2), &sd->bl, AREA_CHAT_WOC); clif_send(buf, WBUFW(buf,2), &sd->bl, AREA_CHAT_WOC);
// send back message to the speaker // send back message to the speaker
WBUFW(buf,0) = 0x8e; WBUFW(buf,0) = 0x8e;
WBUFW(buf, 2) = len_mes + 4; WBUFW(buf, 2) = len_mes + 4;
memcpy(WBUFP(buf,4), mes, len_mes); safestrncpy((char*)WBUFP(buf,4), mes, len_mes);
clif_send(buf, WBUFW(buf,2), &sd->bl, SELF); clif_send(buf, WBUFW(buf,2), &sd->bl, SELF);
return 0;
} }
/*========================== /*==========================

View File

@ -437,7 +437,7 @@ int clif_guild_memberpositionchanged(struct guild *g,int idx);
int clif_guild_emblem(struct map_session_data *sd,struct guild *g); int clif_guild_emblem(struct map_session_data *sd,struct guild *g);
void clif_guild_emblem_area(struct block_list* bl); void clif_guild_emblem_area(struct block_list* bl);
int clif_guild_notice(struct map_session_data *sd,struct guild *g); int clif_guild_notice(struct map_session_data *sd,struct guild *g);
int clif_guild_message(struct guild *g,int account_id,const char *mes,int len); void clif_guild_message(struct guild *g,int account_id,const char *mes,int len);
int clif_guild_skillup(struct map_session_data *sd,int skill_num,int lv); int clif_guild_skillup(struct map_session_data *sd,int skill_num,int lv);
int clif_guild_reqalliance(struct map_session_data *sd,int account_id,const char *name); int clif_guild_reqalliance(struct map_session_data *sd,int account_id,const char *name);
int clif_guild_allianceack(struct map_session_data *sd,int flag); int clif_guild_allianceack(struct map_session_data *sd,int flag);
@ -468,7 +468,7 @@ int clif_font(struct map_session_data *sd);
// atcommand // atcommand
int clif_displaymessage(const int fd,const char* mes); int clif_displaymessage(const int fd,const char* mes);
int clif_disp_onlyself(struct map_session_data *sd,const char *mes,int len); void clif_disp_onlyself(struct map_session_data *sd,const char *mes,int len);
void clif_disp_message(struct block_list* src, const char* mes, int len, enum send_target target); void clif_disp_message(struct block_list* src, const char* mes, int len, enum send_target target);
int clif_broadcast(struct block_list *bl, const char* mes, int len, int type, enum send_target target); int clif_broadcast(struct block_list *bl, const char* mes, int len, int type, enum send_target target);
void clif_MainChatMessage(const char* message); //luzza void clif_MainChatMessage(const char* message); //luzza
@ -502,7 +502,7 @@ void clif_weather(int m); // [Valaris]
int clif_specialeffect(struct block_list* bl, int type, enum send_target target); // special effects [Valaris] int clif_specialeffect(struct block_list* bl, int type, enum send_target target); // special effects [Valaris]
void clif_specialeffect_single(struct block_list* bl, int type, int fd); void clif_specialeffect_single(struct block_list* bl, int type, int fd);
int clif_messagecolor(struct block_list* bl, unsigned long color, const char* msg); // Mob/Npc color talk [SnakeDrak] int clif_messagecolor(struct block_list* bl, unsigned long color, const char* msg); // Mob/Npc color talk [SnakeDrak]
int clif_message(struct block_list *bl, const char* msg); // messages (from mobs/npcs) [Valaris] void clif_message(struct block_list *bl, const char* msg); // messages (from mobs/npcs) [Valaris]
int clif_GM_kickack(struct map_session_data *sd,int id); int clif_GM_kickack(struct map_session_data *sd,int id);
void clif_GM_kick(struct map_session_data *sd,struct map_session_data *tsd); void clif_GM_kick(struct map_session_data *sd,struct map_session_data *tsd);
@ -510,7 +510,7 @@ void clif_manner_message(struct map_session_data* sd, uint32 type);
void clif_GM_silence(struct map_session_data* sd, struct map_session_data* tsd, uint8 type); void clif_GM_silence(struct map_session_data* sd, struct map_session_data* tsd, uint8 type);
int clif_timedout(struct map_session_data *sd); int clif_timedout(struct map_session_data *sd);
int clif_disp_overhead(struct map_session_data *sd, const char* mes); void clif_disp_overhead(struct map_session_data *sd, const char* mes);
void clif_get_weapon_view(struct map_session_data* sd, unsigned short *rhand, unsigned short *lhand); void clif_get_weapon_view(struct map_session_data* sd, unsigned short *rhand, unsigned short *lhand);