mirror of
https://github.com/samba-team/samba.git
synced 2025-01-08 21:18:16 +03:00
ldb:attrib_handlers: reduce non-transitive behaviour in ldb_comparison_fold
If two strings are invalid UTF-8, the string is first compared with memcmp(), which compares as unsigned char. If the strings are of different lengths and one is a substring of the other, the memcmp() returns 0 and a second comparison is made which assumes the next character in the shorter string is '\0' -- but this comparison was done using SIGNED chars (on most systems). That leads to non-transitive comparisons. Consider the strings {"a\xff", "a", "ab\xff"} under that system. "a\xff" < "a", because (char)0xff == -1. "ab\xff" > "a", because 'b' == 98. "ab\xff" < "a\xff", because memcmp("ab\xff", "a\xff", 2) avoiding the signed char tiebreaker. (Beforec49c48afe0
, the final character might br arbitrarily cast into another character -- in latin-1, for example, the 0xff here would have been seen as 'ÿ', which would be uppercased to 'Ÿ', which is U+0178, which would be truncated to '\x78', a positive char. On the other hand e.g. 0xfe, 'þ', would have mapped to 0xde, 'Þ', remaining negative). 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> (cherry picked from commite2051eebd4
)
This commit is contained in:
parent
3f9d9f8344
commit
e21251926b
@ -393,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;
|
||||
|
Loading…
Reference in New Issue
Block a user