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-24 16:03:58 +0000
committerMagnus Auvinen <magnus.auvinen@gmail.com>2008-02-24 16:03:58 +0000
commit4739966e14ca2df24d4f44fb814b6275b9bf2a3c (patch)
tree2398dee3380dfa48582a71a4f2d4278448fa6cb8 /src/engine/e_packer.c
parent1ea859c431b33a384727c0016917dde15bceeff3 (diff)
downloadzcatch-4739966e14ca2df24d4f44fb814b6275b9bf2a3c.tar.gz
zcatch-4739966e14ca2df24d4f44fb814b6275b9bf2a3c.zip
larger restructure to improve security
Diffstat (limited to 'src/engine/e_packer.c')
-rw-r--r--src/engine/e_packer.c68
1 files changed, 61 insertions, 7 deletions
diff --git a/src/engine/e_packer.c b/src/engine/e_packer.c
index 9e77927d..fa5d54cf 100644
--- a/src/engine/e_packer.c
+++ b/src/engine/e_packer.c
@@ -1,12 +1,39 @@
 /* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
+#include <stdlib.h>
 
 #include "e_system.h"
 #include "e_packer.h"
 #include "e_compression.h"
+#include "e_engine.h"
 
 /* useful for debugging */
-#define packing_error(p) p->error = 1
-/* #define packing_error(p) p->error = 1; dbg_break() */
+#if 0
+	#define packing_error(p) p->error = 1; dbg_break()
+#else
+	#define packing_error(p) p->error = 1
+#endif
+
+int stress_get_int()
+{
+	static const int nasty[] = {-1, 0, 1, 66000, -66000, (-1<<31), 0x7fffffff};
+	if(rand()&1)
+		return rand();
+	return nasty[rand()%6];
+}
+
+const char *stress_get_string(int *size)
+{
+	static char noise[1024];
+	int i;
+	int s;
+	s = (rand()%1024)-1;
+	for(i = 0; i < s; i++)
+		noise[i] = (rand()%254)+1;
+	noise[s] = 0;
+	if(size)
+		*size = s;
+	return noise;
+}
 
 void packer_reset(PACKER *p)
 {
@@ -19,6 +46,9 @@ void packer_add_int(PACKER *p, int i)
 {
 	if(p->error)
 		return;
+		
+	/*if(engine_stress(0.05f))
+		i = stress_get_int();*/
 	
 	/* make sure that we have space enough */
 	if(p->end - p->current < 6)
@@ -35,6 +65,15 @@ void packer_add_string(PACKER *p, const char *str, int limit)
 	if(p->error)
 		return;
 		
+	/* STRESS: do this better */
+	/*
+	if(engine_stress(0.1f))
+	{
+		str = stress_get_string(0);
+		limit = 0;
+	}*/
+	
+	/* */
 	if(limit > 0)
 	{
 		while(*str && limit != 0)
@@ -105,8 +144,14 @@ void unpacker_reset(UNPACKER *p, const unsigned char *data, int size)
 int unpacker_get_int(UNPACKER *p)
 {
 	int i;
-	if(p->error || p->current >= p->end)
+	if(p->error)
 		return 0;
+	if(p->current >= p->end)
+	{
+		packing_error(p);
+		return 0;
+	}
+	
 	p->current = vint_unpack(p->current, &i);
 	if(p->current > p->end)
 	{
@@ -118,11 +163,11 @@ int unpacker_get_int(UNPACKER *p)
 
 const char *unpacker_get_string(UNPACKER *p)
 {
-	const char *ptr;
+	char *ptr;
 	if(p->error || p->current >= p->end)
 		return "";
 		
-	ptr = (const char *)p->current;
+	ptr = (char *)p->current;
 	while(*p->current) /* skip the string */
 	{
 		p->current++;
@@ -133,17 +178,26 @@ const char *unpacker_get_string(UNPACKER *p)
 		}
 	}
 	p->current++;
+	
+	/* sanitize all strings */
+	str_sanitize(ptr);
 	return ptr;
 }
 
 const unsigned char *unpacker_get_raw(UNPACKER *p, int size)
 {
 	const unsigned char *ptr = p->current;
-	p->current += size;
-	if(p->current > p->end)
+	if(p->error)
+		return 0;
+	
+	/* check for nasty sizes */
+	if(size < 0 || p->current+size > p->end)
 	{
 		packing_error(p);
 		return 0;
 	}
+
+	/* "unpack" the data */	
+	p->current += size;
 	return ptr;
 }