From 8da81d42c7b31191c175aa0a8a9439b66594f3c3 Mon Sep 17 00:00:00 2001 From: Kurt Zeilenga Date: Fri, 25 Mar 2005 05:57:07 +0000 Subject: [PATCH] ITS#3538: improved substrings matching (spaces handled in accordance with LDAPprep) --- servers/slapd/schema_init.c | 151 ++++++++++++++++++++++++++++++++++-- 1 file changed, 144 insertions(+), 7 deletions(-) diff --git a/servers/slapd/schema_init.c b/servers/slapd/schema_init.c index 8396006f59..4f4edc6c35 100644 --- a/servers/slapd/schema_init.c +++ b/servers/slapd/schema_init.c @@ -1323,7 +1323,10 @@ UTF8StringNormalize( nvalue.bv_len = 0; nvalue.bv_val = tmp.bv_val; - wasspace = 1; /* trim leading spaces */ + /* trim leading spaces? */ + wasspace = !((( use & SLAP_MR_SUBSTR_ANY ) == SLAP_MR_SUBSTR_ANY ) || + (( use & SLAP_MR_SUBSTR_FINAL ) == SLAP_MR_SUBSTR_FINAL )); + for( i = 0; i < tmp.bv_len; i++) { if ( ASCII_SPACE( tmp.bv_val[i] )) { if( wasspace++ == 0 ) { @@ -1337,8 +1340,11 @@ UTF8StringNormalize( } if( !BER_BVISEMPTY( &nvalue ) ) { - if( wasspace ) { - /* last character was a space, trim it */ + /* trim trailing space? */ + if( wasspace && ( + (( use & SLAP_MR_SUBSTR_INITIAL ) != SLAP_MR_SUBSTR_INITIAL ) && + ( use & SLAP_MR_SUBSTR_ANY ) != SLAP_MR_SUBSTR_ANY )) + { --nvalue.bv_len; } nvalue.bv_val[nvalue.bv_len] = '\0'; @@ -1354,6 +1360,137 @@ UTF8StringNormalize( return LDAP_SUCCESS; } +static int +directoryStringSubstringsMatch( + int *matchp, + slap_mask_t flags, + Syntax *syntax, + MatchingRule *mr, + struct berval *value, + void *assertedValue ) +{ + int match = 0; + SubstringsAssertion *sub = assertedValue; + struct berval left = *value; + int i; + int priorspace=0; + + if ( !BER_BVISNULL( &sub->sa_initial ) ) { + if ( sub->sa_initial.bv_len > left.bv_len ) { + /* not enough left */ + match = 1; + goto done; + } + + match = memcmp( sub->sa_initial.bv_val, left.bv_val, + sub->sa_initial.bv_len ); + + if ( match != 0 ) { + goto done; + } + + left.bv_val += sub->sa_initial.bv_len; + left.bv_len -= sub->sa_initial.bv_len; + + priorspace = ASCII_SPACE( + sub->sa_initial.bv_val[sub->sa_initial.bv_len] ); + } + + if ( sub->sa_any ) { + for ( i = 0; !BER_BVISNULL( &sub->sa_any[i] ); i++ ) { + ber_len_t idx; + char *p; + + if( priorspace && !BER_BVISEMPTY( &sub->sa_any[i] ) + && ASCII_SPACE( sub->sa_any[i].bv_val[0] )) + { + /* allow next space to match */ + left.bv_val--; + left.bv_len++; + } + priorspace=0; + +retry: + if ( BER_BVISEMPTY( &sub->sa_any[i] ) ) { + continue; + } + + if ( sub->sa_any[i].bv_len > left.bv_len ) { + /* not enough left */ + match = 1; + goto done; + } + + p = memchr( left.bv_val, *sub->sa_any[i].bv_val, left.bv_len ); + + if( p == NULL ) { + match = 1; + goto done; + } + + idx = p - left.bv_val; + + if ( idx >= left.bv_len ) { + /* this shouldn't happen */ + return LDAP_OTHER; + } + + left.bv_val = p; + left.bv_len -= idx; + + if ( sub->sa_any[i].bv_len > left.bv_len ) { + /* not enough left */ + match = 1; + goto done; + } + + match = memcmp( left.bv_val, + sub->sa_any[i].bv_val, + sub->sa_any[i].bv_len ); + + if ( match != 0 ) { + left.bv_val++; + left.bv_len--; + goto retry; + } + + left.bv_val += sub->sa_any[i].bv_len; + left.bv_len -= sub->sa_any[i].bv_len; + + priorspace = ASCII_SPACE( + sub->sa_any[i].bv_val[sub->sa_any[i].bv_len] ); + } + } + + if ( !BER_BVISNULL( &sub->sa_final ) ) { + if( priorspace && !BER_BVISEMPTY( &sub->sa_final ) + && ASCII_SPACE( sub->sa_final.bv_val[0] )) + { + /* allow next space to match */ + left.bv_val--; + left.bv_len++; + } + + if ( sub->sa_final.bv_len > left.bv_len ) { + /* not enough left */ + match = 1; + goto done; + } + + match = memcmp( sub->sa_final.bv_val, + &left.bv_val[left.bv_len - sub->sa_final.bv_len], + sub->sa_final.bv_len ); + + if ( match != 0 ) { + goto done; + } + } + +done: + *matchp = match; + return LDAP_SUCCESS; +} + #if defined(SLAPD_APPROX_INITIALS) # define SLAPD_APPROX_DELIMITER "._ " # define SLAPD_APPROX_WORDLEN 2 @@ -3371,7 +3508,7 @@ static slap_mrule_defs_rec mrule_defs[] = { {"( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )", SLAP_MR_SUBSTR, directoryStringSyntaxes, - NULL, UTF8StringNormalize, octetStringSubstringsMatch, + NULL, UTF8StringNormalize, directoryStringSubstringsMatch, octetStringSubstringsIndexer, octetStringSubstringsFilter, "caseIgnoreMatch" }, @@ -3392,7 +3529,7 @@ static slap_mrule_defs_rec mrule_defs[] = { {"( 2.5.13.7 NAME 'caseExactSubstringsMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )", SLAP_MR_SUBSTR, directoryStringSyntaxes, - NULL, UTF8StringNormalize, octetStringSubstringsMatch, + NULL, UTF8StringNormalize, directoryStringSubstringsMatch, octetStringSubstringsIndexer, octetStringSubstringsFilter, "caseExactMatch" }, @@ -3578,14 +3715,14 @@ static slap_mrule_defs_rec mrule_defs[] = { {"( 1.3.6.1.4.1.1466.109.114.3 NAME 'caseIgnoreIA5SubstringsMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )", SLAP_MR_SUBSTR, NULL, - NULL, IA5StringNormalize, octetStringSubstringsMatch, + NULL, IA5StringNormalize, directoryStringSubstringsMatch, octetStringSubstringsIndexer, octetStringSubstringsFilter, "caseIgnoreIA5Match" }, {"( 1.3.6.1.4.1.4203.1.2.1 NAME 'caseExactIA5SubstringsMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )", SLAP_MR_SUBSTR, NULL, - NULL, IA5StringNormalize, octetStringSubstringsMatch, + NULL, IA5StringNormalize, directoryStringSubstringsMatch, octetStringSubstringsIndexer, octetStringSubstringsFilter, "caseExactIA5Match" }, -- 2.39.5