diff --git a/src/xpdev/xpprintf.c b/src/xpdev/xpprintf.c
index 2c66bba7d29d1997162f8729d865e97677216a71..9459affd2fd681f8f05d64613b3cde9ffea70492 100644
--- a/src/xpdev/xpprintf.c
+++ b/src/xpdev/xpprintf.c
@@ -6,11 +6,8 @@
 #include "xpprintf.h"
 
 /* MSVC Sucks - can't tell the required len of a *printf() */
-/*
- * ToDo: don't cripple everyone because of this... see
- * conio/ciolib.c cprintf() for details
- */
-#define MAX_ARG_LEN		10240
+#define MAX_ARG_LEN		1024			/* MAX_ARG_LEN is the maximum length possible as a result of a format which
+										 * is not %s */
 
 /* Maximum length of a format specifier including the % */
 #define MAX_FORMAT_LEN	256
@@ -260,12 +257,16 @@ char *xp_asprintf_next(char *format, int type, ...)
 	size_t			this_format_len;
 	size_t			tail_len;
 	char			entry_buf[MAX_ARG_LEN];
+	char			*entry;
+	char			*str_buf;
 	char			this_format[MAX_FORMAT_LEN];
 	char			*fmt;
 	int				modifier=0;
 	char			*fmt_start;
 	int				correct_type=0;
 	char			num_str[128];		/* More than enough room for a 256-bit int */
+	size_t			width=0;
+	size_t			precision=0;
 
 	/*
 	 * Check if we're already done...
@@ -343,6 +344,8 @@ char *xp_asprintf_next(char *format, int type, ...)
 		return(format);
 	}
 	/* Skip width */
+	if(*p >= '0' && *p <= '9')
+		width=strtoul(p, NULL, 10);
 	while(*p >= '0' && *p <= '9')
 		*(fmt++)=*(p++);
 	/* Check for precision */
@@ -381,6 +384,8 @@ char *xp_asprintf_next(char *format, int type, ...)
 			return(format);
 		}
 		/* Skip precision */
+		if(*p >= '0' && *p <= '9')
+			precision=strtoul(p, NULL, 10);
 		while(*p >= '0' && *p <= '9')
 			*(fmt++)=*(p++);
 	}
@@ -1028,42 +1033,53 @@ char *xp_asprintf_next(char *format, int type, ...)
 	/* The next char is now the type... perform native sprintf() using it */
 	*(fmt++)=*p;
 	*fmt=0;
+	entry=entry_buf;
 	switch(type) {
 		case XP_PRINTF_TYPE_INT:	/* Also includes char and short */
-			j=sprintf(entry_buf, this_format, i);
+			j=sprintf(entry, this_format, i);
 			break;
 		case XP_PRINTF_TYPE_UINT:	/* Also includes char and short */
-			j=sprintf(entry_buf, this_format, ui);
+			j=sprintf(entry, this_format, ui);
 			break;
 		case XP_PRINTF_TYPE_LONG:
-			j=sprintf(entry_buf, this_format, l);
+			j=sprintf(entry, this_format, l);
 			break;
 		case XP_PRINTF_TYPE_ULONG:
-			j=sprintf(entry_buf, this_format, ul);
+			j=sprintf(entry, this_format, ul);
 			break;
 		case XP_PRINTF_TYPE_LONGLONG:
-			j=sprintf(entry_buf, this_format, ll);
+			j=sprintf(entry, this_format, ll);
 			break;
 		case XP_PRINTF_TYPE_ULONGLONG:
-			j=sprintf(entry_buf, this_format, ull);
+			j=sprintf(entry, this_format, ull);
 			break;
 		case XP_PRINTF_TYPE_CHARP:
 			if(cp==NULL)
-				j=sprintf(entry_buf, this_format, "<null>");
-			else
-				j=sprintf(entry_buf, this_format, cp);
+				j=sprintf(entry, this_format, "<null>");
+			else {
+				s=strlen(cp);
+				if(s<width)
+					s=width;
+				if(s<precision)
+					s=precision;
+				if(s>=MAX_ARG_LEN)
+					entry=(char *)malloc(s+1);
+				if(entry==NULL)
+					return(NULL);
+				j=sprintf(entry, this_format, cp);
+			}
 			break;
 		case XP_PRINTF_TYPE_DOUBLE:
-			j=sprintf(entry_buf, this_format, d);
+			j=sprintf(entry, this_format, d);
 			break;
 		case XP_PRINTF_TYPE_LONGDOUBLE:
-			j=sprintf(entry_buf, this_format, ld);
+			j=sprintf(entry, this_format, ld);
 			break;
 		case XP_PRINTF_TYPE_VOIDP:
-			j=sprintf(entry_buf, this_format, pntr);
+			j=sprintf(entry, this_format, pntr);
 			break;
 		case XP_PRINTF_TYPE_SIZET:
-			j=sprintf(entry_buf, this_format, s);
+			j=sprintf(entry, this_format, s);
 			break;
 	}
 
@@ -1079,7 +1095,9 @@ char *xp_asprintf_next(char *format, int type, ...)
 	format=newbuf;
 	/* Move trailing end to make space */
 	memmove(format+offset+j, format+offset+this_format_len, offset+format_len-this_format_len+1);
-	memcpy(format+offset, entry_buf, j);
+	memcpy(format+offset, entry, j);
+	if(entry != entry_buf)
+		free(entry);
 	p=format+offset+j;
 	/*
 	 * Search for next non-%% separateor and set offset