/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
*
- * Copyright 1998-2006 The OpenLDAP Foundation.
+ * Copyright 1998-2011 The OpenLDAP Foundation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
return LDAP_INAPPROPRIATE_MATCHING;
}
- assert(SLAP_IS_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH( flags ));
+ assert( SLAP_IS_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH( flags ) != 0 );
if( !SLAP_IS_MR_ASSERTED_VALUE_NORMALIZED_MATCH( flags ) &&
mr->smr_normalize )
{
rc = (mr->smr_normalize)(
flags & (SLAP_MR_TYPE_MASK|SLAP_MR_SUBTYPE_MASK|SLAP_MR_VALUE_OF_SYNTAX),
- ad ? ad->ad_type->sat_syntax : NULL,
+ ad->ad_type->sat_syntax,
mr, val, &nval, ctx );
if( rc != LDAP_SUCCESS ) {
/* assign new indexes to an attribute's ordered values */
void
-ordered_value_renumber( Attribute *a, int vals )
+ordered_value_renumber( Attribute *a )
{
char *ptr, ibuf[64]; /* many digits */
struct berval ibv, tmp, vtmp;
- int i;
+ unsigned i;
ibv.bv_val = ibuf;
- for (i=0; i<vals; i++) {
- ibv.bv_len = sprintf(ibv.bv_val, "{%d}", i);
+ for (i=0; i<a->a_numvals; i++) {
+ ibv.bv_len = sprintf(ibv.bv_val, "{%u}", i);
vtmp = a->a_vals[i];
if ( vtmp.bv_val[0] == '{' ) {
ptr = ber_bvchr(&vtmp, '}');
}
if ( do_renumber && renumber )
- ordered_value_renumber( a, vals );
+ ordered_value_renumber( a );
return 0;
}
/* Skip past the assertion index */
if ( bv.bv_val[0] == '{' ) {
- char *ptr;
+ char *ptr;
ptr = ber_bvchr( &bv, '}' );
- if ( ptr == NULL ) {
- return LDAP_INVALID_SYNTAX;
+ if ( ptr != NULL ) {
+ struct berval ns;
+
+ ns.bv_val = bv.bv_val + 1;
+ ns.bv_len = ptr - ns.bv_val;
+
+ if ( numericStringValidate( NULL, &ns ) == LDAP_SUCCESS ) {
+ ptr++;
+ bv.bv_len -= ptr - bv.bv_val;
+ bv.bv_val = ptr;
+ in = &bv;
+ /* If deleting by index, just succeed */
+ if ( mop == LDAP_MOD_DELETE && BER_BVISEMPTY( &bv ) ) {
+ return LDAP_SUCCESS;
+ }
+ }
}
- ptr++;
- bv.bv_len -= ptr - bv.bv_val;
- bv.bv_val = ptr;
- in = &bv;
- /* If deleting by index, just succeed */
- if ( mop == LDAP_MOD_DELETE && BER_BVISEMPTY( &bv ))
- return LDAP_SUCCESS;
}
}
struct berval *out,
void *ctx )
{
- struct berval bv = *val,
+ struct berval bv,
idx = BER_BVNULL;
int rc;
assert( val != NULL );
assert( out != NULL );
+ bv = *val;
+
if ( ad->ad_type->sat_flags & SLAP_AT_ORDERED ) {
/* Skip past the assertion index */
char *ptr;
ptr = ber_bvchr( &bv, '}' );
- if ( ptr == NULL ) {
- return LDAP_INVALID_SYNTAX;
- }
- ptr++;
+ if ( ptr != NULL ) {
+ struct berval ns;
+
+ ns.bv_val = bv.bv_val + 1;
+ ns.bv_len = ptr - ns.bv_val;
- idx = bv;
- idx.bv_len = ptr - bv.bv_val;
+ if ( numericStringValidate( NULL, &ns ) == LDAP_SUCCESS ) {
+ ptr++;
- bv.bv_len -= idx.bv_len;
- bv.bv_val = ptr;
+ idx = bv;
+ idx.bv_len = ptr - bv.bv_val;
- val = &bv;
+ bv.bv_len -= idx.bv_len;
+ bv.bv_val = ptr;
+
+ val = &bv;
+ }
+ }
}
}
struct berval *normalized,
void *ctx )
{
- struct berval bv = *val,
+ struct berval bv,
idx = BER_BVNULL;
int rc;
assert( val != NULL );
assert( normalized != NULL );
+ bv = *val;
+
if ( ad->ad_type->sat_flags & SLAP_AT_ORDERED ) {
/* Skip past the assertion index */
char *ptr;
ptr = ber_bvchr( &bv, '}' );
- if ( ptr == NULL ) {
- return LDAP_INVALID_SYNTAX;
- }
- ptr++;
+ if ( ptr != NULL ) {
+ struct berval ns;
+
+ ns.bv_val = bv.bv_val + 1;
+ ns.bv_len = ptr - ns.bv_val;
- idx = bv;
- idx.bv_len = ptr - bv.bv_val;
+ if ( numericStringValidate( NULL, &ns ) == LDAP_SUCCESS ) {
+ ptr++;
- bv.bv_len -= idx.bv_len;
- bv.bv_val = ptr;
+ idx = bv;
+ idx.bv_len = ptr - bv.bv_val;
- /* validator will already prevent this for Adds */
- if ( BER_BVISEMPTY( &bv )) {
- ber_dupbv_x( normalized, &idx, ctx );
- return LDAP_SUCCESS;
+ bv.bv_len -= idx.bv_len;
+ bv.bv_val = ptr;
+
+ /* validator will already prevent this for Adds */
+ if ( BER_BVISEMPTY( &bv )) {
+ ber_dupbv_x( normalized, &idx, ctx );
+ return LDAP_SUCCESS;
+ }
+ val = &bv;
+ }
}
- val = &bv;
}
}
*/
if ( ad->ad_type->sat_flags & SLAP_AT_ORDERED ) {
char *ptr;
- struct berval iv;
+ struct berval ns1 = BER_BVNULL, ns2 = BER_BVNULL;
bv1 = *v1;
bv2 = *v2;
- iv = bv2;
/* Skip past the assertion index */
if ( bv2.bv_val[0] == '{' ) {
ptr = ber_bvchr( &bv2, '}' );
- if ( ptr == NULL ) {
- return LDAP_INVALID_SYNTAX;
+ if ( ptr != NULL ) {
+ ns2.bv_val = bv2.bv_val + 1;
+ ns2.bv_len = ptr - ns2.bv_val;
+
+ if ( numericStringValidate( NULL, &ns2 ) == LDAP_SUCCESS ) {
+ ptr++;
+ bv2.bv_len -= ptr - bv2.bv_val;
+ bv2.bv_val = ptr;
+ v2 = &bv2;
+ }
}
- ptr++;
- bv2.bv_len -= ptr - bv2.bv_val;
- bv2.bv_val = ptr;
- v2 = &bv2;
}
- if ( SLAP_MR_IS_VALUE_OF_ASSERTION_SYNTAX( flags )) {
- if ( iv.bv_val[0] == '{' && bv1.bv_val[0] == '{' ) {
- /* compare index values first */
- long l1, l2, ret;
-
- l1 = strtol( bv1.bv_val+1, NULL, 0 );
- l2 = strtol( iv.bv_val+1, &ptr, 0 );
+ /* Skip past the attribute index */
+ if ( bv1.bv_val[0] == '{' ) {
+ ptr = ber_bvchr( &bv1, '}' );
+ if ( ptr != NULL ) {
+ ns1.bv_val = bv1.bv_val + 1;
+ ns1.bv_len = ptr - ns1.bv_val;
+
+ if ( numericStringValidate( NULL, &ns1 ) == LDAP_SUCCESS ) {
+ ptr++;
+ bv1.bv_len -= ptr - bv1.bv_val;
+ bv1.bv_val = ptr;
+ v1 = &bv1;
+ }
+ }
+ }
- ret = l1 - l2;
+ if ( SLAP_MR_IS_VALUE_OF_ASSERTION_SYNTAX( flags )) {
+ if ( !BER_BVISNULL( &ns2 ) && !BER_BVISNULL( &ns1 ) ) {
+ /* compare index values first */
+ (void)octetStringOrderingMatch( match, 0, NULL, NULL, &ns1, &ns2 );
/* If not equal, or we're only comparing the index,
* return result now.
*/
- if ( ret || ptr == iv.bv_val + iv.bv_len - 1 ) {
- *match = ( ret < 0 ) ? -1 : (ret > 0 );
+ if ( *match != 0 || BER_BVISEMPTY( &bv2 ) ) {
return LDAP_SUCCESS;
}
}
}
- /* Skip past the attribute index */
- if ( bv1.bv_val[0] == '{' ) {
- ptr = ber_bvchr( &bv1, '}' );
- if ( ptr == NULL ) {
- return LDAP_INVALID_SYNTAX;
- }
- ptr++;
- bv1.bv_len -= ptr - bv1.bv_val;
- bv1.bv_val = ptr;
- v1 = &bv1;
- }
+
}
if ( !mr || !mr->smr_match ) {
vnum = i;
if ( a ) {
- for (i=0; !BER_BVISNULL( a->a_vals+i ); i++) ;
- anum = i;
ordered_value_sort( a, 0 );
} else {
Attribute **ap;
- anum = 0;
for ( ap=&e->e_attrs; *ap; ap = &(*ap)->a_next ) ;
- a = ch_calloc( 1, sizeof(Attribute) );
- a->a_desc = ad;
+ a = attr_alloc( ad );
*ap = a;
}
+ anum = a->a_numvals;
new = ch_malloc( (anum+vnum+1) * sizeof(struct berval));
- if ( a->a_nvals && a->a_nvals != a->a_vals ) {
+
+ /* sanity check: if normalized modifications come in, either
+ * no values are present or normalized existing values differ
+ * from non-normalized; if no normalized modifications come in,
+ * either no values are present or normalized existing values
+ * don't differ from non-normalized */
+ if ( nvals != NULL ) {
+ assert( nvals != vals );
+ assert( a->a_nvals == NULL || a->a_nvals != a->a_vals );
+
+ } else {
+ assert( a->a_nvals == NULL || a->a_nvals == a->a_vals );
+ }
+
+ if ( ( a->a_nvals && a->a_nvals != a->a_vals ) || nvals != NULL ) {
nnew = ch_malloc( (anum+vnum+1) * sizeof(struct berval));
/* Shouldn't happen... */
if ( !nvals ) nvals = vals;
}
if ( anum ) {
AC_MEMCPY( new, a->a_vals, anum * sizeof(struct berval));
- if ( nnew )
+ if ( nnew && a->a_nvals )
AC_MEMCPY( nnew, a->a_nvals, anum * sizeof(struct berval));
}
k = -1;
if ( vals[i].bv_val[0] == '{' ) {
+ /* FIXME: strtol() could go past end... */
k = strtol( vals[i].bv_val + 1, &next, 0 );
if ( next == vals[i].bv_val + 1 ||
next[ 0 ] != '}' ||
- next - vals[i].bv_val > vals[i].bv_len )
+ (ber_len_t) (next - vals[i].bv_val) > vals[i].bv_len )
{
ch_free( nnew );
ch_free( new );
a->a_nvals = a->a_vals;
}
- ordered_value_renumber( a, anum );
+ a->a_numvals = anum;
+ ordered_value_renumber( a );
return 0;
}