diff --git a/src/byteptr.h b/src/byteptr.h
index aa09d6be41f5251400cc902929c2ab87397f3802..9756e7d9562d8285402b8b75c4bb40900e6d2227 100644
--- a/src/byteptr.h
+++ b/src/byteptr.h
@@ -150,26 +150,78 @@ FUNCINLINE static ATTRINLINE UINT32 readulong(void *ptr)
 
 #undef DEALIGNED
 
-#define WRITESTRINGN(p,s,n) { size_t tmp_i = 0; for (; tmp_i < n && s[tmp_i] != '\0'; tmp_i++) WRITECHAR(p, s[tmp_i]); if (tmp_i < n) WRITECHAR(p, '\0');}
-#define WRITESTRING(p,s)    { size_t tmp_i = 0; for (;              s[tmp_i] != '\0'; tmp_i++) WRITECHAR(p, s[tmp_i]); WRITECHAR(p, '\0');}
-#define WRITEMEM(p,s,n)     { memcpy(p, s, n); p += n; }
-
-#define SKIPSTRING(p)       while (READCHAR(p) != '\0')
-
-#define READSTRINGN(p,s,n)  { size_t tmp_i = 0; for (; tmp_i < n && (s[tmp_i] = READCHAR(p)) != '\0'; tmp_i++); s[tmp_i] = '\0';}
-#define READSTRING(p,s)     { size_t tmp_i = 0; for (;              (s[tmp_i] = READCHAR(p)) != '\0'; tmp_i++); s[tmp_i] = '\0';}
-#define READMEM(p,s,n)      { memcpy(s, p, n); p += n; }
-
-#if 0 // old names
-#define WRITEBYTE(p,b)      WRITEUINT8(p,b)
-#define WRITESHORT(p,b)     WRITEINT16(p,b)
-#define WRITEUSHORT(p,b)    WRITEUINT16(p,b)
-#define WRITELONG(p,b)      WRITEINT32(p,b)
-#define WRITEULONG(p,b)     WRITEUINT32(p,b)
-
-#define READBYTE(p)         READUINT8(p)
-#define READSHORT(p)        READINT16(p)
-#define READUSHORT(p)       READUINT16(p)
-#define READLONG(p)         READINT32(p)
-#define READULONG(p)        READUINT32(p)
-#endif
+#define WRITESTRINGN(p, s, n) ({                            \
+	size_t tmp_i;                                           \
+                                                            \
+	for (tmp_i = 0; tmp_i < n && s[tmp_i] != '\0'; tmp_i++) \
+		WRITECHAR(p, s[tmp_i]);                             \
+                                                            \
+	if (tmp_i < n)                                          \
+		WRITECHAR(p, '\0');                                 \
+})
+
+#define WRITESTRINGL(p, s, n) ({                                \
+	size_t tmp_i;                                               \
+                                                                \
+	for (tmp_i = 0; tmp_i < n - 1 && s[tmp_i] != '\0'; tmp_i++) \
+		WRITECHAR(p, s[tmp_i]);                                 \
+                                                                \
+	WRITECHAR(p, '\0');                                         \
+})
+
+#define WRITESTRING(p, s) ({                   \
+	size_t tmp_i;                              \
+                                               \
+	for (tmp_i = 0; s[tmp_i] != '\0'; tmp_i++) \
+		WRITECHAR(p, s[tmp_i]);                \
+                                               \
+	WRITECHAR(p, '\0');                        \
+})
+
+#define WRITEMEM(p, s, n) ({ \
+	memcpy(p, s, n);         \
+	p += n;                  \
+})
+
+#define SKIPSTRING(p) while (READCHAR(p) != '\0')
+
+#define SKIPSTRINGN(p, n) ({                 \
+	size_t tmp_i = 0;                        \
+                                             \
+	while (tmp_i < n && READCHAR(p) != '\0') \
+		tmp_i++;                             \
+})
+
+#define SKIPSTRINGL(p, n) SKIPSTRINGN(p, n)
+
+#define READSTRINGN(p, s, n) ({                           \
+	size_t tmp_i = 0;                                     \
+                                                          \
+	while (tmp_i < n && (s[tmp_i] = READCHAR(p)) != '\0') \
+		tmp_i++;                                          \
+                                                          \
+	s[tmp_i] = '\0';                                      \
+})
+
+#define READSTRINGL(p, s, n) ({                               \
+	size_t tmp_i = 0;                                         \
+                                                              \
+	while (tmp_i < n - 1 && (s[tmp_i] = READCHAR(p)) != '\0') \
+		tmp_i++;                                              \
+                                                              \
+	s[tmp_i] = '\0';                                          \
+})
+
+#define READSTRING(p, s) ({                  \
+	size_t tmp_i = 0;                        \
+                                             \
+	while ((s[tmp_i] = READCHAR(p)) != '\0') \
+		tmp_i++;                             \
+                                             \
+	s[tmp_i] = '\0';                         \
+})
+
+#define READMEM(p, s, n) ({ \
+	memcpy(s, p, n);        \
+	p += n;                 \
+})
diff --git a/src/hu_stuff.c b/src/hu_stuff.c
index 1d0f8b4c2919dab83e25430d5ed3c91b2ee6e794..55e16eff4019a84577f9b0cf990a5c7f0ae5601b 100644
--- a/src/hu_stuff.c
+++ b/src/hu_stuff.c
@@ -84,7 +84,7 @@ patch_t *frameslash;	// framerate stuff. Used in screen.c
 
 static player_t *plr;
 boolean chat_on; // entering a chat message?
-static char w_chat[HU_MAXMSGLEN];
+static char w_chat[HU_MAXMSGLEN + 1];
 static size_t c_input = 0; // let's try to make the chat input less shitty.
 static boolean headsupactive = false;
 boolean hu_showscores; // draw rankings
@@ -463,7 +463,7 @@ void HU_AddChatText(const char *text, boolean playsound)
 
 static void DoSayCommand(SINT8 target, size_t usedargs, UINT8 flags)
 {
-	XBOXSTATIC char buf[254];
+	XBOXSTATIC char buf[2 + HU_MAXMSGLEN + 1];
 	size_t numwords, ix;
 	char *msg = &buf[2];
 	const size_t msgspace = sizeof buf - 2;
@@ -544,7 +544,7 @@ static void DoSayCommand(SINT8 target, size_t usedargs, UINT8 flags)
 		}
 		buf[0] = target;
 		newmsg = msg+5+spc;
-		strlcpy(msg, newmsg, 252);
+		strlcpy(msg, newmsg, HU_MAXMSGLEN + 1);
 	}
 
 	SendNetXCmd(XD_SAY, buf, strlen(msg) + 1 + msg-buf);
@@ -654,7 +654,7 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum)
 	target = READSINT8(*p);
 	flags = READUINT8(*p);
 	msg = (char *)*p;
-	SKIPSTRING(*p);
+	SKIPSTRINGL(*p, HU_MAXMSGLEN + 1);
 
 	if ((cv_mute.value || flags & (HU_CSAY|HU_SERVER_SAY)) && playernum != serverplayer && !(IsPlayerAdmin(playernum)))
 	{
@@ -1108,7 +1108,7 @@ static void HU_queueChatChar(INT32 c)
 	// send automaticly the message (no more chat char)
 	if (c == KEY_ENTER)
 	{
-		char buf[2+256];
+		char buf[2 + HU_MAXMSGLEN + 1];
 		char *msg = &buf[2];
 		size_t i;
 		size_t ci = 2;
@@ -1198,7 +1198,7 @@ static void HU_queueChatChar(INT32 c)
 
 			// we need to get rid of the /pm<node>
 			newmsg = msg+5+spc;
-			strlcpy(msg, newmsg, 255);
+			strlcpy(msg, newmsg, HU_MAXMSGLEN + 1);
 		}
 		if (ci > 3) // don't send target+flags+empty message.
 		{
diff --git a/src/hu_stuff.h b/src/hu_stuff.h
index be6798a823c38cb64211c46fdca236879486a7aa..77e0628e5d0928492346206b3f885bb24c9a998d 100644
--- a/src/hu_stuff.h
+++ b/src/hu_stuff.h
@@ -61,7 +61,7 @@ typedef struct
 //------------------------------------
 //           chat stuff
 //------------------------------------
-#define HU_MAXMSGLEN 224
+#define HU_MAXMSGLEN 223
 #define CHAT_BUFSIZE 64		// that's enough messages, right? We'll delete the older ones when that gets out of hand.
 #define NETSPLITSCREEN // why the hell WOULDN'T we want this?
 #ifdef NETSPLITSCREEN