ldb: reduce non-transitive comparisons in ldb_msg_element_compare()
authorDouglas Bagnall <douglas.bagnall@catalyst.net.nz>
Wed, 3 Apr 2024 22:26:25 +0000 (11:26 +1300)
committerAndrew Bartlett <abartlet@samba.org>
Wed, 10 Apr 2024 22:56:33 +0000 (22:56 +0000)
We can still have inconsistent comparisons, because two elements with
the same number of values will always return -1 if they are unequal,
which means they will sort differently depending on the order in which
they are compared.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15625

Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
lib/ldb/common/ldb_msg.c

index 9cb26d8bd89d05bc4407a8fdac1f7f269c2e5401..bbb7ff96233d12649e971130da4fa6287b06f196 100644 (file)
@@ -749,9 +749,16 @@ int ldb_msg_element_compare(struct ldb_message_element *el1,
        unsigned int i;
 
        if (el1->num_values != el2->num_values) {
-               return el1->num_values - el2->num_values;
+               return NUMERIC_CMP(el1->num_values, el2->num_values);
        }
-
+       /*
+        * Note this is an inconsistent comparison, unsuitable for
+        * sorting. If A has values {a, b} and B has values {b, c},
+        * then
+        *
+        * ldb_msg_element_compare(A, B) returns -1, meaning A < B
+        * ldb_msg_element_compare(B, A) returns -1, meaning B < A
+        */
        for (i=0;i<el1->num_values;i++) {
                if (!ldb_msg_find_val(el2, &el1->values[i])) {
                        return -1;