[Date Prev][Date Next] [Chronological] [Thread] [Top]

sorted values vs. compare errors

I don't know if this is a false alarm or not, but anyway:

Sorted values, as with SLAP_ATTR_SORTED_VALS in attr_valfind(),
needs an unambiguous ordering.  However value_match() can return
error, and does not say which of the compared values caused the

Are there sorted value examples where it can return error both
because of the stored value and because of the assertion value?
Or overlays like rwm which can cause this?
If so the sort order of (normal value, value causing error) will
depend on the order of arguments to the compare function.

Then if we manage to insert an "ambiguously-sorted" attribute value
into the sorted list of values, then a binary search for an existing
normal value can fail if it hits the naughty value as a pivot entry.
Or it can cause a new value to be inserted at the wrong place.

Possibly there are also some other strange matching rules where the
ordering is ambiguous, I don't know.

In any case, I think this whould mean that:

- value_match() and ordering-compare functions should try to define
  unambiguous orderings of (normal value, truble value).  I think
  sorting of (trouble value 1, truble value 2) does not matter.

- maybe Sorted values should only be supported for attributes
  whose compare functions do define such an ordering.

However there are also inequality filters vs. sorted attribute
values.  This code in slapd/filterentry.c:test_ava_filter()
is similarly broken if there is an error-generating value
at either end of the array of values:

        if (( a->a_flags & SLAP_ATTR_SORTED_VALS ) && type != LDAP_FILTER_APPROX ) {
            unsigned slot;
            int ret;

            /* For Ordering matches, we just need to do one comparison with
             * either the first (least) or last (greatest) value.
            if ( use == SLAP_MR_ORDERING ) {
                const char *text;
                int match, which;
                which = (type == LDAP_FILTER_LE) ? 0 : a->a_numvals-1;
                ret = value_match( &match, a->a_desc, mr, use,
                    &a->a_nvals[which], &ava->aa_value, &text );
                if ( ret != LDAP_SUCCESS ) return ret;

For such a value, and with a normal assertion value, the function
ought to search for the nearest non-error-generating value and
compare with that.