mirror of
https://git.openldap.org/openldap/openldap.git
synced 2026-01-06 23:19:59 -05:00
Made caseIgnoreSubstringsMatch and caseExactSubstringsMatch use proper
Unicode cannonical normalization
This commit is contained in:
parent
82f3004a16
commit
6c362d77ac
1 changed files with 74 additions and 113 deletions
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue