about summary refs log tree commit diff
path: root/src/engine/e_packer.c
diff options
context:
space:
mode:
authorMagnus Auvinen <magnus.auvinen@gmail.com>2008-02-11 22:25:10 +0000
committerMagnus Auvinen <magnus.auvinen@gmail.com>2008-02-11 22:25:10 +0000
commit1ea859c431b33a384727c0016917dde15bceeff3 (patch)
treea2e8a040abaa6334e6e5c0442a75b5777355000d /src/engine/e_packer.c
parent79dfdb3cd71a44ec3cd8e1dab15263837381cbbf (diff)
downloadzcatch-1ea859c431b33a384727c0016917dde15bceeff3.tar.gz
zcatch-1ea859c431b33a384727c0016917dde15bceeff3.zip
security audit: fixed so the packer functions checks for errors
Diffstat (limited to 'src/engine/e_packer.c')
-rw-r--r--src/engine/e_packer.c64
1 files changed, 61 insertions, 3 deletions
diff --git a/src/engine/e_packer.c b/src/engine/e_packer.c
index 948db4ea..9e77927d 100644
--- a/src/engine/e_packer.c
+++ b/src/engine/e_packer.c
@@ -1,8 +1,13 @@
 /* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
 
+#include "e_system.h"
 #include "e_packer.h"
 #include "e_compression.h"
 
+/* useful for debugging */
+#define packing_error(p) p->error = 1
+/* #define packing_error(p) p->error = 1; dbg_break() */
+
 void packer_reset(PACKER *p)
 {
 	p->error = 0;
@@ -12,30 +17,66 @@ void packer_reset(PACKER *p)
 
 void packer_add_int(PACKER *p, int i)
 {
-	p->current = vint_pack(p->current, i);
+	if(p->error)
+		return;
+	
+	/* make sure that we have space enough */
+	if(p->end - p->current < 6)
+	{
+		dbg_break();
+		p->error = 1;
+	}
+	else
+		p->current = vint_pack(p->current, i);
 }
 
 void packer_add_string(PACKER *p, const char *str, int limit)
 {
+	if(p->error)
+		return;
+		
 	if(limit > 0)
 	{
 		while(*str && limit != 0)
 		{
 			*p->current++ = *str++;
 			limit--;
+			
+			if(p->current >= p->end)
+			{
+				packing_error(p);
+				break;
+			}
 		}
 		*p->current++ = 0;
 	}
 	else
 	{
 		while(*str)
+		{
 			*p->current++ = *str++;
+
+			if(p->current >= p->end)
+			{
+				packing_error(p);
+				break;
+			}
+		}
 		*p->current++ = 0;
 	}
 }
 
 void packer_add_raw(PACKER *p, const unsigned char *data, int size)
 {
+	if(p->error)
+		return;
+		
+	if(p->current+size >= p->end)
+	{
+		packing_error(p);
+		return;
+	}
+	
 	while(size)
 	{
 		*p->current++ = *data++;
@@ -64,21 +105,33 @@ void unpacker_reset(UNPACKER *p, const unsigned char *data, int size)
 int unpacker_get_int(UNPACKER *p)
 {
 	int i;
-	if(p->current >= p->end)
+	if(p->error || p->current >= p->end)
 		return 0;
 	p->current = vint_unpack(p->current, &i);
+	if(p->current > p->end)
+	{
+		packing_error(p);
+		return 0;
+	}
 	return i;
 }
 
 const char *unpacker_get_string(UNPACKER *p)
 {
 	const char *ptr;
-	if(p->current >= p->end)
+	if(p->error || p->current >= p->end)
 		return "";
 		
 	ptr = (const char *)p->current;
 	while(*p->current) /* skip the string */
+	{
 		p->current++;
+		if(p->current == p->end)
+		{
+			packing_error(p);
+			return "";
+		}
+	}
 	p->current++;
 	return ptr;
 }
@@ -87,5 +140,10 @@ const unsigned char *unpacker_get_raw(UNPACKER *p, int size)
 {
 	const unsigned char *ptr = p->current;
 	p->current += size;
+	if(p->current > p->end)
+	{
+		packing_error(p);
+		return 0;
+	}
 	return ptr;
 }