Problem with expansion of %{Ldap-UserDn} containing UTF-8 (cf. Bug #411)
Enrik Berkhan
enrik#freeradius at planb.de
Mon Aug 27 17:05:55 CEST 2007
Alan DeKok wrote:
> Bleah. There's no need to use a function with local non-thread-aware
> storage. It's easy to know what a valid UTF-8 character is. We should
> just check ourselves, and escape anything that isn't valid.
You're right. So this could be a start:
static int valid_utf8(const unsigned char *p, size_t len)
{
if (len >= 1
&& p[0] < 0x7f) {
return 1;
} else if (len >= 2
&& p[0] >= 0xC0 && p[0] < 0xE0
&& (p[1]&0x80) == 0x80) {
return 2;
} else if (len >= 3
&& p[0] >= 0xE0 && p[0] < 0xF0
&& (p[1]&0x80) == 0x80 && (p[2]&0x80) == 0x80) {
return 3;
} else if (len >= 4
&& p[0] >= 0xF0 && p[0] < 0xF8
&& (p[1]&0x80) == 0x80 && (p[2]&0x80) == 0x80
&& (p[3]&0x80) == 0x80) {
return 4;
} else if (len >= 5
&& p[0] >= 0xF8 && p[0] < 0xFC
&& (p[1]&0x80) == 0x80 && (p[2]&0x80) == 0x80
&& (p[3]&0x80) == 0x80 && (p[4]&0x80) == 0x80) {
return 5;
} else if (len >= 6
&& p[0] >= 0xFC && p[0] < 0xFE
&& (p[1]&0x80) == 0x80 && (p[2]&0x80) == 0x80
&& (p[3]&0x80) == 0x80 && (p[4]&0x80) == 0x80
&& (p[5]&0x80) == 0x80) {
return 6;
}
return 0;
}
/*
* Check if string contains valid UTF-8, escape violating bytes.
* The output string has to be _at least_ 4x the size
* of the input string!
*/
void librad_utf8_sanitize(const char *in, size_t inlen,
char *out, size_t outlen)
{
while (inlen && outlen) {
size_t next = valid_utf8(in, inlen);
if (next) {
if (outlen > next) {
inlen -= next;
outlen -= next;
while(next--)
*out++ = *in++;
} else {
goto no_more;
}
} else {
if (outlen > 4) { /* room for \ooo\0 */
sprintf(out, "\\%03o", (unsigned char)(*in++)&0xff);
out += 4;
inlen--;
outlen -= 4;
} else {
goto no_more;
}
}
}
no_more:
*out = 0;
}
Enrik
More information about the Freeradius-Devel
mailing list