summaryrefslogtreecommitdiff
path: root/src/map/clif.c
diff options
context:
space:
mode:
authorai4rei <ai4rei@54d463be-8e91-2dee-dedb-b68131a5f0ec>2011-08-20 06:10:43 +0000
committerai4rei <ai4rei@54d463be-8e91-2dee-dedb-b68131a5f0ec>2011-08-20 06:10:43 +0000
commita26298ee3aa66edb4ef23b291b23ac0419be50f5 (patch)
tree10132924b5c1ba96a11d0701c1d7a9a469356fd3 /src/map/clif.c
parent14c2376cab40d580743a8a5d02af6109659d9892 (diff)
downloadhercules-a26298ee3aa66edb4ef23b291b23ac0419be50f5.tar.gz
hercules-a26298ee3aa66edb4ef23b291b23ac0419be50f5.tar.bz2
hercules-a26298ee3aa66edb4ef23b291b23ac0419be50f5.tar.xz
hercules-a26298ee3aa66edb4ef23b291b23ac0419be50f5.zip
* Added quick validation of guild emblems' bitmap format to prevent forged emblems, that cause the client to crash, from being accepted (thx to sinya for a sample).
git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@14937 54d463be-8e91-2dee-dedb-b68131a5f0ec
Diffstat (limited to 'src/map/clif.c')
-rw-r--r--src/map/clif.c32
1 files changed, 30 insertions, 2 deletions
diff --git a/src/map/clif.c b/src/map/clif.c
index 5ee32c3e1..d45c941ba 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -4,6 +4,7 @@
#include "../common/cbasetypes.h"
#include "../common/socket.h"
#include "../common/timer.h"
+#include "../common/grfio.h"
#include "../common/malloc.h"
#include "../common/version.h"
#include "../common/nullpo.h"
@@ -11087,16 +11088,43 @@ void clif_parse_GuildRequestEmblem(int fd,struct map_session_data *sd)
clif_guild_emblem(sd,g);
}
+
+/// Validates data of a guild emblem (compressed bitmap)
+static bool clif_validate_emblem(const uint8* emblem, unsigned long emblem_len)
+{
+ bool success;
+ uint8 buf[1800]; // no well-formed emblem bitmap is larger than 1782 (24 bit) / 1654 (8 bit) bytes
+ unsigned long buf_len = sizeof(buf);
+
+ success = ( decode_zip(buf, &buf_len, emblem, emblem_len) == 0 && buf_len >= 18 ) // sizeof(BITMAPFILEHEADER) + sizeof(biSize) of the following info header struct
+ && RBUFW(buf,0) == 0x4d42 // BITMAPFILEHEADER.bfType (signature)
+ && RBUFL(buf,2) == buf_len // BITMAPFILEHEADER.bfSize (file size)
+ && RBUFL(buf,10) < buf_len // BITMAPFILEHEADER.bfOffBits (offset to bitmap bits)
+ ;
+
+ return success;
+}
+
+
/*==========================================
* ギルドエンブレム変更
* S 0153 <packet len>.W <emblem data>.?B
*------------------------------------------*/
void clif_parse_GuildChangeEmblem(int fd,struct map_session_data *sd)
{
- if(!sd->state.gmaster_flag)
+ unsigned long emblem_len = RFIFOW(fd,2)-4;
+ const uint8* emblem = RFIFOP(fd,4);
+
+ if( !emblem_len || !sd->state.gmaster_flag )
+ return;
+
+ if( !clif_validate_emblem(emblem, emblem_len) )
+ {
+ ShowWarning("clif_parse_GuildChangeEmblem: Rejected malformed guild emblem (size=%lu, accound_id=%d, char_id=%d, guild_id=%d).\n", emblem_len, sd->status.account_id, sd->status.char_id, sd->status.guild_id);
return;
+ }
- guild_change_emblem(sd,RFIFOW(fd,2)-4,(char*)RFIFOP(fd,4));
+ guild_change_emblem(sd, emblem_len, emblem);
}
/*==========================================