Cleaned up file name collation code

- Update documentation for COLLATION_RULES
- Document how ntfs_names_full_collate() compares names
- Update comments and DEBUG code to reflect that ntfs_names_full_collate()
  always access 'upcase', even in CASE_SENSITIVE mode
- Remove unneeded assignments to 'c1' and 'c2' in IGNORE_CASE mode

Signed-off-by: Eric Biggers <ebiggers3@gmail.com>
This commit is contained in:
Jean-Pierre André 2016-07-28 16:10:14 +02:00
parent 54b78660d7
commit 4264f19acb
2 changed files with 31 additions and 30 deletions

View File

@ -515,16 +515,15 @@ typedef enum {
* enum COLLATION_RULES - The collation rules for sorting views/indexes/etc * enum COLLATION_RULES - The collation rules for sorting views/indexes/etc
* (32-bit). * (32-bit).
* *
* COLLATION_UNICODE_STRING - Collate Unicode strings by comparing their binary * COLLATION_BINARY - Collate by binary compare where the first byte is most
* Unicode values, except that when a character can be uppercased, the * significant.
* upper case value collates before the lower case one. * COLLATION_FILE_NAME - Collate Unicode strings by comparing their 16-bit
* COLLATION_FILE_NAME - Collate file names as Unicode strings. The collation * coding units, primarily ignoring case using the volume's $UpCase table,
* is done very much like COLLATION_UNICODE_STRING. In fact I have no idea * but falling back to a case-sensitive comparison if the names are equal
* what the difference is. Perhaps the difference is that file names * ignoring case.
* would treat some special characters in an odd way (see * COLLATION_UNICODE_STRING - TODO: this is not yet implemented and still needs
* unistr.c::ntfs_collate_names() and unistr.c::legal_ansi_char_array[] * to be properly documented --- is it really the same as
* for what I mean but COLLATION_UNICODE_STRING would not give any special * COLLATION_FILE_NAME?
* treatment to any characters at all, but this is speculation.
* COLLATION_NTOFS_ULONG - Sorting is done according to ascending le32 key * COLLATION_NTOFS_ULONG - Sorting is done according to ascending le32 key
* values. E.g. used for $SII index in FILE_Secure, which sorts by * values. E.g. used for $SII index in FILE_Secure, which sorts by
* security_id (le32). * security_id (le32).
@ -549,17 +548,9 @@ typedef enum {
* equal then the second le32 values would be compared, etc. * equal then the second le32 values would be compared, etc.
*/ */
typedef enum { typedef enum {
COLLATION_BINARY = const_cpu_to_le32(0), /* Collate by binary COLLATION_BINARY = const_cpu_to_le32(0),
compare where the first byte is most COLLATION_FILE_NAME = const_cpu_to_le32(1),
significant. */ COLLATION_UNICODE_STRING = const_cpu_to_le32(2),
COLLATION_FILE_NAME = const_cpu_to_le32(1), /* Collate file names
as Unicode strings. */
COLLATION_UNICODE_STRING = const_cpu_to_le32(2), /* Collate Unicode
strings by comparing their binary
Unicode values, except that when a
character can be uppercased, the upper
case value collates before the lower
case one. */
COLLATION_NTOFS_ULONG = const_cpu_to_le32(16), COLLATION_NTOFS_ULONG = const_cpu_to_le32(16),
COLLATION_NTOFS_SID = const_cpu_to_le32(17), COLLATION_NTOFS_SID = const_cpu_to_le32(17),
COLLATION_NTOFS_SECURITY_HASH = const_cpu_to_le32(18), COLLATION_NTOFS_SECURITY_HASH = const_cpu_to_le32(18),

View File

@ -143,14 +143,24 @@ BOOL ntfs_names_are_equal(const ntfschar *s1, size_t s1_len,
* @name1_len: length of first Unicode name to compare * @name1_len: length of first Unicode name to compare
* @name2: second Unicode name to compare * @name2: second Unicode name to compare
* @name2_len: length of second Unicode name to compare * @name2_len: length of second Unicode name to compare
* @ic: either CASE_SENSITIVE or IGNORE_CASE * @ic: either CASE_SENSITIVE or IGNORE_CASE (see below)
* @upcase: upcase table (ignored if @ic is CASE_SENSITIVE) * @upcase: upcase table
* @upcase_len: upcase table size (ignored if @ic is CASE_SENSITIVE) * @upcase_len: upcase table size
* *
* If @ic is CASE_SENSITIVE, then the names are compared primarily ignoring
* case, but if the names are equal ignoring case, then they are compared
* case-sensitively. As an example, "abc" would collate before "BCD" (since
* "abc" and "BCD" differ ignoring case and 'A' < 'B') but after "ABC" (since
* "ABC" and "abc" are equal ignoring case and 'A' < 'a'). This matches the
* collation order of filenames as indexed in NTFS directories.
*
* If @ic is IGNORE_CASE, then the names are only compared case-insensitively
* and are considered to match if and only if they are equal ignoring case.
*
* Returns:
* -1 if the first name collates before the second one, * -1 if the first name collates before the second one,
* 0 if the names match, * 0 if the names match, or
* 1 if the second name collates before the first one, or * 1 if the second name collates before the first one
*
*/ */
int ntfs_names_full_collate(const ntfschar *name1, const u32 name1_len, int ntfs_names_full_collate(const ntfschar *name1, const u32 name1_len,
const ntfschar *name2, const u32 name2_len, const ntfschar *name2, const u32 name2_len,
@ -162,7 +172,7 @@ int ntfs_names_full_collate(const ntfschar *name1, const u32 name1_len,
u16 u1, u2; u16 u1, u2;
#ifdef DEBUG #ifdef DEBUG
if (!name1 || !name2 || (ic && (!upcase || !upcase_len))) { if (!name1 || !name2 || !upcase || !upcase_len) {
ntfs_log_debug("ntfs_names_collate received NULL pointer!\n"); ntfs_log_debug("ntfs_names_collate received NULL pointer!\n");
exit(1); exit(1);
} }
@ -205,9 +215,9 @@ int ntfs_names_full_collate(const ntfschar *name1, const u32 name1_len,
return 1; return 1;
} else { } else {
do { do {
u1 = c1 = le16_to_cpu(*name1); u1 = le16_to_cpu(*name1);
name1++; name1++;
u2 = c2 = le16_to_cpu(*name2); u2 = le16_to_cpu(*name2);
name2++; name2++;
if (u1 < upcase_len) if (u1 < upcase_len)
u1 = le16_to_cpu(upcase[u1]); u1 = le16_to_cpu(upcase[u1]);