cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

upcase.c (2121B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 *
      4 * Copyright (C) 2019-2021 Paragon Software GmbH, All rights reserved.
      5 *
      6 */
      7
      8#include <linux/kernel.h>
      9#include <linux/types.h>
     10
     11#include "ntfs_fs.h"
     12
     13static inline u16 upcase_unicode_char(const u16 *upcase, u16 chr)
     14{
     15	if (chr < 'a')
     16		return chr;
     17
     18	if (chr <= 'z')
     19		return chr - ('a' - 'A');
     20
     21	return upcase[chr];
     22}
     23
     24/*
     25 * ntfs_cmp_names
     26 *
     27 * Thanks Kari Argillander <kari.argillander@gmail.com> for idea and implementation 'bothcase'
     28 *
     29 * Straight way to compare names:
     30 * - Case insensitive
     31 * - If name equals and 'bothcases' then
     32 * - Case sensitive
     33 * 'Straight way' code scans input names twice in worst case.
     34 * Optimized code scans input names only once.
     35 */
     36int ntfs_cmp_names(const __le16 *s1, size_t l1, const __le16 *s2, size_t l2,
     37		   const u16 *upcase, bool bothcase)
     38{
     39	int diff1 = 0;
     40	int diff2;
     41	size_t len = min(l1, l2);
     42
     43	if (!bothcase && upcase)
     44		goto case_insentive;
     45
     46	for (; len; s1++, s2++, len--) {
     47		diff1 = le16_to_cpu(*s1) - le16_to_cpu(*s2);
     48		if (diff1) {
     49			if (bothcase && upcase)
     50				goto case_insentive;
     51
     52			return diff1;
     53		}
     54	}
     55	return l1 - l2;
     56
     57case_insentive:
     58	for (; len; s1++, s2++, len--) {
     59		diff2 = upcase_unicode_char(upcase, le16_to_cpu(*s1)) -
     60			upcase_unicode_char(upcase, le16_to_cpu(*s2));
     61		if (diff2)
     62			return diff2;
     63	}
     64
     65	diff2 = l1 - l2;
     66	return diff2 ? diff2 : diff1;
     67}
     68
     69int ntfs_cmp_names_cpu(const struct cpu_str *uni1, const struct le_str *uni2,
     70		       const u16 *upcase, bool bothcase)
     71{
     72	const u16 *s1 = uni1->name;
     73	const __le16 *s2 = uni2->name;
     74	size_t l1 = uni1->len;
     75	size_t l2 = uni2->len;
     76	size_t len = min(l1, l2);
     77	int diff1 = 0;
     78	int diff2;
     79
     80	if (!bothcase && upcase)
     81		goto case_insentive;
     82
     83	for (; len; s1++, s2++, len--) {
     84		diff1 = *s1 - le16_to_cpu(*s2);
     85		if (diff1) {
     86			if (bothcase && upcase)
     87				goto case_insentive;
     88
     89			return diff1;
     90		}
     91	}
     92	return l1 - l2;
     93
     94case_insentive:
     95	for (; len; s1++, s2++, len--) {
     96		diff2 = upcase_unicode_char(upcase, *s1) -
     97			upcase_unicode_char(upcase, le16_to_cpu(*s2));
     98		if (diff2)
     99			return diff2;
    100	}
    101
    102	diff2 = l1 - l2;
    103	return diff2 ? diff2 : diff1;
    104}