Index: src/lib/print.c
===================================================================
RCS file: /source/radiusd/src/lib/print.c,v
retrieving revision 1.26.2.1.2.2
diff -u -b -r1.26.2.1.2.2 print.c
--- src/lib/print.c	15 Mar 2006 15:37:56 -0000	1.26.2.1.2.2
+++ src/lib/print.c	28 Aug 2007 14:26:07 -0000
@@ -33,28 +33,123 @@
 #include	"libradius.h"
 
 /*
- *	Convert a string to something printable.
- *	The output string has to be _at least_ 4x the size
- *	of the input string!
+ *      Checks for utf-8, taken from:
+ *
+ *  http://www.w3.org/International/questions/qa-forms-utf-8
+ *
+ *      Note that we don't care about the length of the input string,
+ *      because '\0' is an invalid UTF-8 character.
+ */
+static int utf8_char(uint8_t *str)
+{
+        if (*str < 0x20) return 0;
+
+        if (*str <= 0x7e) return 1; /* 1 */
+
+        if (*str <= 0xc1) return 0;
+
+        if ((str[0] >= 0xc2) && /* 2 */
+            (str[0] <= 0xdf) &&
+            (str[1] >= 0x80) &&
+            (str[1] <= 0xbf)) {
+                return 2;
+        }
+
+        if ((str[0] == 0xe0) && /* 3 */
+            (str[1] >= 0xa0) &&
+            (str[1] <= 0xbf) &&
+            (str[2] >= 0x80) &&
+            (str[2] <= 0xbf)) {
+                return 3;
+        }
+
+        if ((str[0] >= 0xe1) && /* 4a */
+            (str[0] <= 0xec) &&
+            (str[1] >= 0x80) &&
+            (str[1] <= 0xbf) &&
+            (str[2] >= 0x80) &&
+            (str[2] <= 0xbf)) {
+                return 3;
+        }
+
+        if ((str[0] >= 0xee) && /* 4b */
+            (str[0] <= 0xef) &&
+            (str[1] >= 0x80) &&
+            (str[1] <= 0xbf) &&
+            (str[2] >= 0x80) &&
+            (str[2] <= 0xbf)) {
+                return 3;
+        }
+
+        if ((str[0] == 0xed) && /* 5 */
+            (str[1] >= 0x80) &&
+            (str[1] <= 0x9f) &&
+            (str[2] >= 0x80) &&
+            (str[2] <= 0xbf)) {
+                return 3;
+        }
+
+        if ((str[0] == 0xf0) && /* 6 */
+            (str[1] >= 0x90) &&
+            (str[1] <= 0xbf) &&
+            (str[2] >= 0x80) &&
+            (str[2] <= 0xbf) &&
+            (str[3] >= 0x80) &&
+            (str[3] <= 0xbf)) {
+                return 4;
+        }
+
+        if ((str[0] >= 0xf1) && /* 6 */
+            (str[1] <= 0xf3) &&
+            (str[1] >= 0x80) &&
+            (str[1] <= 0xbf) &&
+            (str[2] >= 0x80) &&
+            (str[2] <= 0xbf) &&
+            (str[3] >= 0x80) &&
+            (str[3] <= 0xbf)) {
+                return 4;
+        }
+
+
+        if ((str[0] == 0xf4) && /* 7 */
+            (str[1] >= 0x80) &&
+            (str[1] <= 0x8f) &&
+            (str[2] >= 0x80) &&
+            (str[2] <= 0xbf) &&
+            (str[3] >= 0x80) &&
+            (str[3] <= 0xbf)) {
+                return 4;
+        }
+
+        /*
+         *      Invalid UTF-8 Character
+         */
+        return 0;
+}
+
+/*
+ *      Convert a string to something printable.  The output string
+ *      has to be larger than the input string by at least 5 bytes.
+ *      If not, the output is silently truncated...
  */
 void librad_safeprint(char *in, int inlen, char *out, int outlen)
 {
 	unsigned char	*str = (unsigned char *)in;
-	int		done = 0;
 	int		sp = 0;
+        int             utf8 = 0;
 
 	if (inlen < 0) inlen = strlen(in);
 
-	while (inlen-- > 0 && (done + 3) < outlen) {
+        /*
+         *      
+         */
+        while ((inlen > 0) && (outlen > 4)) {
 		/*
 		 *	Hack: never print trailing zero.
 		 *	Some clients send strings with an off-by-one
 		 *	length (confused with strings in C).
 		 */
-		if (inlen == 0 && *str == 0)
-			break;
-
-		sp = 0;
+                if ((inlen == 0) && (*str == 0)) break;
 
 		switch (*str) {
 			case '\\':
@@ -69,25 +164,38 @@
 			case '\t':
 				sp = 't';
 				break;
+                        case '"':
+                                sp = '"';
+                                break;
 			default:
-				if (*str < 32 || (*str >= 128)){
-					snprintf(out, outlen, "\\%03o", *str);
-					done += 4;
-					out  += 4;
-					outlen -= 4;
-				} else {
-					*out++ = *str;
-					outlen--;
-					done++;
-				}
+                                sp = 0;
+                                break;
 		}
+
 		if (sp) {
 			*out++ = '\\';
 			*out++ = sp;
 			outlen -= 2;
-			done += 2;
+                        str++;
+                        inlen--;
+                        continue;
 		}
+
+                utf8 = utf8_char((uint8_t *)str);
+                if (!utf8) {
+                        snprintf(out, outlen, "\\%03o", *str);
+                        out  += 4;
+                        outlen -= 4;
 		str++;
+                        inlen--;
+                        continue;
+                }
+
+                do {
+                        *out++ = *str++;
+                        outlen--;
+                        inlen--;
+                } while (--utf8 > 0);
 	}
 	*out = 0;
 }
@@ -117,18 +225,23 @@
 			if (vp->attribute == PW_NAS_PORT)
 				a = (char *)vp->strvalue;
 			else {
-				if (delimitst && vp->flags.has_tag) {
+				if (delimitst == 1 && vp->flags.has_tag) {
 				        /* Tagged attribute: print delimter and ignore tag */
 				        buf[0] = '"';
 					librad_safeprint((char *)(vp->strvalue),
 							 vp->length, buf + 1, sizeof(buf) - 2);
 					strcat(buf, "\"");
-				} else if (delimitst) {
+				} else if (delimitst == 1) {
 				        /* Non-tagged attribute: print delimter */
 				        buf[0] = '"';
 					librad_safeprint((char *)vp->strvalue,
 							 vp->length, buf + 1, sizeof(buf) - 2);
 					strcat(buf, "\"");
+
+				} else if (delimitst < 0) { /* xlat.c */
+					strlcpy(out, vp->strvalue, outlen);
+					return strlen(out);
+
 				} else {
 				        /* Non-tagged attribute: no delimiter */
 				        librad_safeprint((char *)vp->strvalue,
Index: src/main/xlat.c
===================================================================
RCS file: /source/radiusd/src/main/xlat.c,v
retrieving revision 1.72.2.7.2.5
diff -u -b -r1.72.2.7.2.5 xlat.c
--- src/main/xlat.c	14 Jul 2007 11:07:54 -0000	1.72.2.7.2.5
+++ src/main/xlat.c	28 Aug 2007 14:26:08 -0000
@@ -72,7 +72,7 @@
 	char buffer[MAX_STRING_LEN * 4];
 
 	if (pair != NULL) {
-		vp_prints_value(buffer, sizeof(buffer), pair, 0);
+		vp_prints_value(buffer, sizeof(buffer), pair, -1);
 		return func(out, outlen, buffer);
 	}
 
