diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-20 04:07:27 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-20 04:07:27 +0000 |
commit | 19d0fde1ace012e366182b511c528f7ab6a0ed37 (patch) | |
tree | 4b7f31bfcae1f06f2a77dd154508460119172422 /lib/ldb/common/attrib_handlers.c | |
parent | Adding debian version 2:4.20.1+dfsg-5. (diff) | |
download | samba-19d0fde1ace012e366182b511c528f7ab6a0ed37.tar.xz samba-19d0fde1ace012e366182b511c528f7ab6a0ed37.zip |
Merging upstream version 2:4.20.2+dfsg.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'lib/ldb/common/attrib_handlers.c')
-rw-r--r-- | lib/ldb/common/attrib_handlers.c | 53 |
1 files changed, 42 insertions, 11 deletions
diff --git a/lib/ldb/common/attrib_handlers.c b/lib/ldb/common/attrib_handlers.c index 15470cf..3d13e4b 100644 --- a/lib/ldb/common/attrib_handlers.c +++ b/lib/ldb/common/attrib_handlers.c @@ -281,15 +281,36 @@ static int ldb_canonicalise_Boolean(struct ldb_context *ldb, void *mem_ctx, } /* - compare two Booleans -*/ + * compare two Booleans. + * + * According to RFC4517 4.2.2, "the booleanMatch rule is an equality matching + * rule", meaning it isn't used for ordering. + * + * However, it seems conceivable that Samba could be coerced into sorting on a + * field with Boolean syntax, so we might as well have consistent behaviour in + * that case. + * + * The most probably values are {"FALSE", 5} and {"TRUE", 4}. To save time we + * compare first by length, which makes FALSE > TRUE. This is somewhat + * contrary to convention, but is how Samba has worked forever. + * + * If somehow we are comparing incompletely normalised values where the length + * is the same (for example {"false", 5} and {"TRUE\0", 5}), the length is the + * same, and we fall back to a strncasecmp. In this case, since "FALSE" is + * alphabetically lower, we swap the order, so that "TRUE\0" again comes + * before "FALSE". + * + * ldb_canonicalise_Boolean (just above) gives us a clue as to what we might + * expect to cope with by way of invalid values. + */ static int ldb_comparison_Boolean(struct ldb_context *ldb, void *mem_ctx, const struct ldb_val *v1, const struct ldb_val *v2) { if (v1->length != v2->length) { - return v1->length - v2->length; + return NUMERIC_CMP(v2->length, v1->length); } - return strncasecmp((char *)v1->data, (char *)v2->data, v1->length); + /* reversed, see long comment above */ + return strncasecmp((char *)v2->data, (char *)v1->data, v1->length); } @@ -300,7 +321,7 @@ int ldb_comparison_binary(struct ldb_context *ldb, void *mem_ctx, const struct ldb_val *v1, const struct ldb_val *v2) { if (v1->length != v2->length) { - return v1->length - v2->length; + return NUMERIC_CMP(v1->length, v2->length); } return memcmp(v1->data, v2->data, v1->length); } @@ -372,17 +393,27 @@ utf8str: b2 = ldb_casefold(ldb, mem_ctx, s2, n2); if (!b1 || !b2) { - /* One of the strings was not UTF8, so we have no - * options but to do a binary compare */ + /* + * One of the strings was not UTF8, so we have no + * options but to do a binary compare. + */ talloc_free(b1); talloc_free(b2); ret = memcmp(s1, s2, MIN(n1, n2)); if (ret == 0) { - if (n1 == n2) return 0; + if (n1 == n2) { + return 0; + } if (n1 > n2) { - return (int)ldb_ascii_toupper(s1[n2]); + if (s1[n2] == '\0') { + return 0; + } + return 1; } else { - return -(int)ldb_ascii_toupper(s2[n1]); + if (s2[n1] == '\0') { + return 0; + } + return -1; } } return ret; @@ -404,7 +435,7 @@ utf8str: while (*u1 == ' ') u1++; while (*u2 == ' ') u2++; } - ret = (int)(*u1 - *u2); + ret = NUMERIC_CMP(*u1, *u2); talloc_free(b1); talloc_free(b2); |