implement caseIgnoreListMatch (ITS#5608)

This commit is contained in:
Pierangelo Masarati 2008-08-30 14:30:31 +00:00
parent 94d8ab48ff
commit 03793fd9f4
3 changed files with 172 additions and 2 deletions

View file

@ -1987,6 +1987,168 @@ telephoneNumberNormalize(
return LDAP_SUCCESS;
}
static int
postalAddressValidate(
Syntax *syntax,
struct berval *in )
{
struct berval bv = *in;
int c;
for ( c = 0; c < in->bv_len; c++ ) {
if ( in->bv_val[c] == '\\' ) {
c++;
if ( strncasecmp( &in->bv_val[c], "24", STRLENOF( "24" ) ) != 0
&& strncasecmp( &in->bv_val[c], "5C", STRLENOF( "5C" ) ) != 0 )
{
return LDAP_INVALID_SYNTAX;
}
continue;
}
if ( in->bv_val[c] == '$' ) {
bv.bv_len = &in->bv_val[c] - bv.bv_val;
if ( UTF8StringValidate( NULL, &bv ) != LDAP_SUCCESS ) {
return LDAP_INVALID_SYNTAX;
}
bv.bv_val = &in->bv_val[c] + 1;
}
}
bv.bv_len = &in->bv_val[c] - bv.bv_val;
return UTF8StringValidate( NULL, &bv );
}
static int
postalAddressNormalize(
slap_mask_t usage,
Syntax *syntax,
MatchingRule *mr,
struct berval *val,
struct berval *normalized,
void *ctx )
{
BerVarray lines = NULL, nlines = NULL;
int l, c;
int nescapes = 0;
int rc = LDAP_SUCCESS;
MatchingRule *xmr = NULL;
struct berval bv = BER_BVNULL;
char *p;
if ( SLAP_MR_ASSOCIATED( mr, slap_schema.si_mr_caseIgnoreListMatch ) ) {
xmr = slap_schema.si_mr_caseIgnoreMatch;
} else {
xmr = slap_schema.si_mr_caseExactMatch;
}
for ( l = 0, c = 0; c < val->bv_len; c++ ) {
if ( val->bv_val[c] == '$' ) {
l++;
}
}
lines = slap_sl_calloc( sizeof( struct berval ), 2 * ( l + 2 ), ctx );
nlines = &lines[l + 2];
lines[0].bv_val = val->bv_val;
for ( l = 0, c = 0; c < val->bv_len; c++ ) {
if ( val->bv_val[c] == '$' ) {
lines[l].bv_len = &val->bv_val[c] - lines[l].bv_val;
l++;
lines[l].bv_val = &val->bv_val[c + 1];
}
}
lines[l].bv_len = &val->bv_val[c] - lines[l].bv_val;
normalized->bv_len = l;
for ( l = 0; !BER_BVISNULL( &lines[l] ); l++ ) {
int s, d;
ber_len_t oldlen;
ber_bvreplace_x( &bv, &lines[l], ctx );
oldlen = bv.bv_len;
for ( d = 0, s = 0; s < oldlen; d++, s++ ) {
if ( bv.bv_val[s] == '\\' ) {
if ( &bv.bv_val[s] - &bv.bv_val[0] + STRLENOF( "\\XX" ) > oldlen ) {
rc = LDAP_INVALID_SYNTAX;
goto done;
} else if ( strncasecmp( &bv.bv_val[s + 1], "24", STRLENOF( "24" ) ) == 0 ) {
bv.bv_val[d] = '$';
} else if ( strncasecmp( &bv.bv_val[s + 1], "5C", STRLENOF( "5C" ) ) == 0 ) {
bv.bv_val[d] = '\\';
} else {
rc = LDAP_INVALID_SYNTAX;
goto done;
}
nescapes++;
s += 2;
bv.bv_len -= 2;
} else {
bv.bv_val[d] = bv.bv_val[s];
}
}
rc = UTF8StringNormalize( usage, NULL, xmr, &bv, &nlines[l], ctx );
if ( rc != LDAP_SUCCESS ) {
rc = LDAP_INVALID_SYNTAX;
goto done;
}
normalized->bv_len += nlines[l].bv_len;
}
normalized->bv_len += 2*nescapes;
normalized->bv_val = slap_sl_malloc( normalized->bv_len + 1, ctx );
p = normalized->bv_val;
for ( l = 0; !BER_BVISNULL( &nlines[l] ); l++ ) {
for ( c = 0; c < nlines[l].bv_len; c++ ) {
switch ( nlines[l].bv_val[c] ) {
case '\\':
p = lutil_strcopy( p, "\\5C" );
break;
case '$':
p = lutil_strcopy( p, "\\24" );
break;
default:
*p++ = nlines[l].bv_val[c];
break;
}
}
*p++ = '$';
}
*--p = '\0';
assert( p - normalized->bv_val == normalized->bv_len );
done:;
if ( !BER_BVISNULL( &bv ) ) {
ber_memfree_x( bv.bv_val, ctx );
}
if ( nlines != NULL ) {
for ( l = 0; !BER_BVISNULL( &nlines[ l ] ); l++ ) {
slap_sl_free( nlines[l].bv_val, ctx );
}
slap_sl_free( lines, ctx );
}
return rc;
}
int
numericoidValidate(
Syntax *syntax,
@ -4688,7 +4850,7 @@ static slap_syntax_defs_rec syntax_defs[] = {
{"( 1.3.6.1.4.1.1466.115.121.1.40 DESC 'Octet String' )",
0, NULL, blobValidate, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.41 DESC 'Postal Address' )",
0, NULL, UTF8StringValidate, NULL},
0, NULL, postalAddressValidate, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.42 DESC 'Protocol Information' )",
0, NULL, NULL, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.43 DESC 'Presentation Address' )",
@ -4993,7 +5155,9 @@ static slap_mrule_defs_rec mrule_defs[] = {
{"( 2.5.13.11 NAME 'caseIgnoreListMatch' "
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )",
SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
NULL, NULL, NULL, NULL, NULL, NULL },
NULL, postalAddressNormalize, octetStringMatch,
octetStringIndexer, octetStringFilter,
NULL },
{"( 2.5.13.12 NAME 'caseIgnoreListSubstringsMatch' "
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",

View file

@ -1072,6 +1072,10 @@ static struct slap_schema_mr_map {
{ "objectIdentifierFirstComponentMatch",
offsetof(struct slap_internal_schema,
si_mr_objectIdentifierFirstComponentMatch) },
{ "caseIgnoreMatch",
offsetof(struct slap_internal_schema, si_mr_caseIgnoreMatch) },
{ "caseIgnoreListMatch",
offsetof(struct slap_internal_schema, si_mr_caseIgnoreListMatch) },
{ NULL, 0 }
};

View file

@ -969,6 +969,8 @@ struct slap_internal_schema {
MatchingRule *si_mr_integerMatch;
MatchingRule *si_mr_integerFirstComponentMatch;
MatchingRule *si_mr_objectIdentifierFirstComponentMatch;
MatchingRule *si_mr_caseIgnoreMatch;
MatchingRule *si_mr_caseIgnoreListMatch;
/* Syntaxes */
Syntax *si_syn_directoryString;