Enrik Berkhan wrote:
Never post before doing at least _some_ testing :)
Try this patch. Untested, but it builds. :( It also deals with overlong characters, and illegal use of surrogates. Alan DeKok. Index: src/lib/print.c =================================================================== RCS file: /source/radiusd/src/lib/print.c,v retrieving revision 1.49 diff -u -w -r1.49 print.c --- src/lib/print.c 29 May 2007 14:33:26 -0000 1.49 +++ src/lib/print.c 27 Aug 2007 16:01:33 -0000 @@ -28,6 +28,99 @@ #include <ctype.h> /* + * Checks for utf-8, + * taken from: + * + * http://www.w3.org/International/questions/qa-forms-utf-8 + */ +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 _at least_ 4x the size * of the input string! @@ -37,6 +130,7 @@ unsigned char *str = (unsigned char *)in; int done = 0; int sp = 0; + int utf8 = 0; if (inlen < 0) inlen = strlen(in); @@ -50,6 +144,7 @@ break; sp = 0; + if (utf8) goto copy; switch (*str) { case '\\': @@ -68,15 +163,18 @@ sp = '"'; break; default: - if (*str < 32 || (*str >= 128)){ + if ((*str < 32) || + ((utf8 = utf8_char((uint8_t *)in)) == 0)) { snprintf(out, outlen, "\\%03o", *str); done += 4; out += 4; outlen -= 4; } else { + copy: *out++ = *str; outlen--; done++; + if (utf8) utf8--; } } if (sp) {