Commit 6c362d77 authored by Stig Venaas's avatar Stig Venaas
Browse files

Made caseIgnoreSubstringsMatch and caseExactSubstringsMatch use proper

Unicode cannonical normalization
parent 82f3004a
......@@ -498,99 +498,6 @@ booleanMatch(
return LDAP_SUCCESS;
}
#if UTF8MATCH
/* case insensitive UTF8 strncmp with offset for second string */
static int
UTF8oncasecmp(
struct berval *right,
struct berval *left,
ber_len_t len,
ber_len_t offset )
{
ber_len_t r, l;
ber_len_t rlen, llen;
ber_len_t rslen, lslen;
ldap_unicode_t ru, lu;
ldap_unicode_t ruu, luu;
rslen = len < right->bv_len ? len : right->bv_len;
lslen = len + offset < left->bv_len ? len : left->bv_len;
for( r = 0, l = offset;
r < rslen && l < lslen;
r+=rlen, l+=llen )
{
/*
* XXYYZ: we convert to ucs4 even though -llunicode
* expects ucs2 in an unsigned long
*/
ru = ldap_utf8_to_ucs4( &right->bv_val[r] );
if( ru == LDAP_UCS4_INVALID ) {
return 1;
}
lu = ldap_utf8_to_ucs4( &left->bv_val[l] );
if( lu == LDAP_UCS4_INVALID ) {
return -1;
}
ruu = uctoupper( ru );
luu = uctoupper( lu );
if( ruu > luu ) {
return 1;
} else if( luu > ruu ) {
return -1;
}
rlen = LDAP_UTF8_CHARLEN( &right->bv_val[r] );
llen = LDAP_UTF8_CHARLEN( &left->bv_val[l] );
}
if( r < rslen ) {
/* less left */
return -1;
}
if( l < lslen ) {
/* less right */
return 1;
}
return 0;
}
static char *UTF8casechr( const char *str, const char *c )
{
char *p, *lower, *upper;
ldap_ucs4_t tch, ch = ldap_utf8_to_ucs4(c);
tch = uctolower ( ch );
for( p = (char *) str; *p != '\0'; LDAP_UTF8_INCR(p) ) {
if( ldap_utf8_to_ucs4( p ) == tch ) {
break;
}
}
lower = *p != '\0' ? p : NULL;
tch = uctoupper ( ch );
for( p = (char *) str; *p != '\0'; LDAP_UTF8_INCR(p) ) {
if( ldap_utf8_to_ucs4( p ) == tch ) {
break;
}
}
upper = *p != '\0' ? p : NULL;
if( lower && upper ) {
return lower < upper ? lower : upper;
} else if ( lower ) {
return lower;
} else {
return upper;
}
}
#endif
static int
UTF8StringValidate(
Syntax *syntax,
......@@ -1075,10 +982,31 @@ caseExactSubstringsMatch(
void *assertedValue )
{
int match = 0;
SubstringsAssertion *sub = assertedValue;
struct berval left = *value;
SubstringsAssertion *sub;
struct berval left;
int i;
ber_len_t inlen=0;
#if UTF8MATCH
char *nav;
#endif
#if UTF8MATCH
nav = UTF8normalize( value->bv_val, UTF8_NOCASEFOLD );
if( nav == NULL ) {
match = 1;
goto done;
}
left.bv_val = nav;
left.bv_len = strlen( nav );
sub = UTF8SubstringsassertionNormalize( assertedValue, UTF8_NOCASEFOLD );
#else
left = *value;
sub = assertedValue;
#endif
if( sub == NULL ) {
match = -1;
goto done;
}
/* Add up asserted input length */
if( sub->sa_initial ) {
......@@ -1186,6 +1114,15 @@ retry:
}
done:
#if UTF8MATCH
free( nav );
if( sub != NULL ) {
ch_free( sub->sa_final );
ber_bvecfree( sub->sa_any );
ch_free( sub->sa_initial );
ch_free( sub );
}
#endif
*matchp = match;
return LDAP_SUCCESS;
}
......@@ -1711,10 +1648,31 @@ caseIgnoreSubstringsMatch(
void *assertedValue )
{
int match = 0;
SubstringsAssertion *sub = assertedValue;
struct berval left = *value;
SubstringsAssertion *sub;
struct berval left;
int i;
ber_len_t inlen=0;
#if UTF8MATCH
char *nav;
#endif
#if UTF8MATCH
nav = UTF8normalize( value->bv_val, UTF8_CASEFOLD );
if( nav == NULL ) {
match = 1;
goto done;
}
left.bv_val = nav;
left.bv_len = strlen( nav );
sub = UTF8SubstringsassertionNormalize( assertedValue, UTF8_CASEFOLD );
#else
left = *value;
sub = assertedValue;
#endif
if( sub == NULL ) {
match = -1;
goto done;
}
/* Add up asserted input length */
if( sub->sa_initial ) {
......@@ -1736,8 +1694,8 @@ caseIgnoreSubstringsMatch(
}
#if UTF8MATCH
match = UTF8oncasecmp( sub->sa_initial, &left,
sub->sa_initial->bv_len, 0 );
match = strncmp( sub->sa_initial->bv_val, left.bv_val,
sub->sa_initial->bv_len );
#else
match = strncasecmp( sub->sa_initial->bv_val, left.bv_val,
sub->sa_initial->bv_len );
......@@ -1759,9 +1717,9 @@ caseIgnoreSubstringsMatch(
}
#if UTF8MATCH
match = UTF8oncasecmp( sub->sa_final, &left,
sub->sa_final->bv_len,
left.bv_len - sub->sa_final->bv_len );
match = strncmp( sub->sa_final->bv_val,
&left.bv_val[left.bv_len - sub->sa_final->bv_len],
sub->sa_final->bv_len );
#else
match = strncasecmp( sub->sa_final->bv_val,
&left.bv_val[left.bv_len - sub->sa_final->bv_len],
......@@ -1793,7 +1751,7 @@ retry:
}
#if UTF8MATCH
p = UTF8casechr( left.bv_val, sub->sa_any[i]->bv_val );
p = strchr( left.bv_val, *sub->sa_any[i]->bv_val );
#else
p = strcasechr( left.bv_val, *sub->sa_any[i]->bv_val );
#endif
......@@ -1821,19 +1779,14 @@ retry:
}
#if UTF8MATCH
match = UTF8oncasecmp( &left, sub->sa_any[i],
sub->sa_any[i]->bv_len, 0 );
if( match != 0 ) {
int len = LDAP_UTF8_CHARLEN( left.bv_val );
left.bv_val += len;
left.bv_len -= len;
goto retry;
}
match = strncmp( left.bv_val,
sub->sa_any[i]->bv_val,
sub->sa_any[i]->bv_len );
#else
match = strncasecmp( left.bv_val,
sub->sa_any[i]->bv_val,
sub->sa_any[i]->bv_len );
#endif
if( match != 0 ) {
left.bv_val++;
......@@ -1841,7 +1794,6 @@ retry:
goto retry;
}
#endif
left.bv_val += sub->sa_any[i]->bv_len;
left.bv_len -= sub->sa_any[i]->bv_len;
......@@ -1850,6 +1802,15 @@ retry:
}
done:
#if UTF8MATCH
free( nav );
if( sub != NULL ) {
ch_free( sub->sa_final );
ber_bvecfree( sub->sa_any );
ch_free( sub->sa_initial );
ch_free( sub );
}
#endif
*matchp = match;
return LDAP_SUCCESS;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment