#define UTF8DN 1
-#ifdef UTF8DN
-/*
- * Upper cases a UTF8 character. We cheat a bit, we only change to upper
- * if the byte length is preserved. Should be replaced.
- */
-
-int
-UTF8touppercheat( unsigned char *p )
-{
- ldap_unicode_t u;
- int len;
-
- len = LDAP_UTF8_CHARLEN( p );
- if ( !len ) {
- return 1;
- }
-
- u = ldap_utf8_to_ucs4( p );
- if ( u == LDAP_UCS4_INVALID ) {
- return 1;
- }
-
- u = uctoupper ( u );
- if ( u < 0 ) {
- return 1;
- }
-
- if ( u < 0x80 ) {
- if ( len == 1 ) {
- p[0] = u;
- } else {
- return 1;
- }
- } else if ( u < 0x800 ) {
- if ( len == 2 ) {
- p[0] = 0xc0 | ( u >> 6 );
- p[1] = 0x80 | ( u & 0x3f );
- } else {
- return 1;
- }
- } else if ( u < 0x10000 ) {
- if ( len == 3 ) {
- p[0] = 0xe0 | ( u >> 12 );
- p[1] = 0x80 | ( (u >> 6) & 0x3f );
- p[2] = 0x80 | ( u & 0x3f );
- } else {
- return 1;
- }
- } else if ( u < 0x200000 ) {
- if ( len == 4 ) {
- p[0] = 0xf0 | ( u >> 18 );
- p[1] = 0x80 | ( (u >> 12) & 0x3f );
- p[2] = 0x80 | ( (u >> 6) & 0x3f );
- p[3] = 0x80 | ( u & 0x3f );
- } else {
- return 1;
- }
- } else if ( u < 0x4000000 ) {
- if ( len == 5 ) {
- p[0] = 0xf8 | ( u >> 24 );
- p[1] = 0x80 | ( (u >> 18) & 0x3f );
- p[2] = 0x80 | ( (u >> 12) & 0x3f );
- p[3] = 0x80 | ( (u >> 6) & 0x3f );
- p[4] = 0x80 | ( u & 0x3f );
- } else {
- return 1;
- }
- } else if ( len == 6 ) {
- /* u < 0x80000000 */
- p[0] = 0xfc | ( u >> 30 );
- p[1] = 0x80 | ( (u >> 24) & 0x3f );
- p[2] = 0x80 | ( (u >> 18) & 0x3f );
- p[3] = 0x80 | ( (u >> 12) & 0x3f );
- p[4] = 0x80 | ( (u >> 6) & 0x3f );
- p[5] = 0x80 | ( u & 0x3f );
- } else {
- return 1;
- }
-
- return len;
-}
-#endif
-
/*
* dn_validate - validate and compress dn. the dn is
* compressed in place are returned if valid.
char *
dn_normalize( char *dn )
{
+ char *out;
/* upper case it */
#ifndef UTF8DN
ldap_pvt_str2upper( dn );
+ /* validate and compress dn */
+ out = dn_validate( dn );
#else
/* enabling this might require reindexing */
- char *p;
-
- p = dn;
- while ( *p ) {
- /* optimizing */
- if ( LDAP_UTF8_ISASCII(p) ) {
- *p = TOUPPER( (unsigned char) *p );
- p++;
- } else {
- p += UTF8touppercheat( p );
+ struct berval *bvdn, *nbvdn;
+
+ out = NULL;
+ bvdn = ber_bvstr( dn );
+
+ if ( dnNormalize( NULL, bvdn, &nbvdn ) == LDAP_SUCCESS ) {
+ if ( nbvdn->bv_len <= bvdn->bv_len ) {
+ out = dn;
+ strcpy( out, nbvdn->bv_val );
}
+ ber_bvfree( nbvdn );
}
+ bvdn->bv_val = NULL; /* prevent bvfree from freeing dn */
+ ber_bvfree( bvdn );
#endif
- /* validate and compress dn */
- dn = dn_validate( dn );
- return( dn );
+ return( out );
}
/*
return rc;
}
-static int
+int
dnNormalize(
Syntax *syntax,
struct berval *val,
struct berval **normalized )
{
- struct berval *out = ber_bvdup( val );
+ struct berval *out;
- if( out->bv_len != 0 ) {
+ if ( val->bv_len != 0 ) {
char *dn;
#ifdef USE_DN_NORMALIZE
- dn = dn_normalize( out->bv_val );
+ out = ber_bvstr( UTF8normalize( val->bv_val, UTF8_CASEFOLD ) );
#else
- dn = dn_validate( out->bv_val );
+ out = ber_bvdup( val );
+ ldap_pvt_str2upper( out->bv_val );
#endif
+ dn = dn_validate( out->bv_val );
if( dn == NULL ) {
ber_bvfree( out );
out->bv_val = dn;
out->bv_len = strlen( dn );
+ } else {
+ out = ber_bvdup( val );
}
*normalized = out;