|
@@ -272,8 +272,8 @@ static inline int asc2unichar(struct super_block *sb, const char *astr, int len,
|
|
|
return size;
|
|
|
}
|
|
|
|
|
|
-/* Decomposes a single unicode character. */
|
|
|
-static inline u16 *decompose_unichar(wchar_t uc, int *size)
|
|
|
+/* Decomposes a non-Hangul unicode character. */
|
|
|
+static u16 *hfsplus_decompose_nonhangul(wchar_t uc, int *size)
|
|
|
{
|
|
|
int off;
|
|
|
|
|
@@ -296,6 +296,51 @@ static inline u16 *decompose_unichar(wchar_t uc, int *size)
|
|
|
return hfsplus_decompose_table + (off / 4);
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * Try to decompose a unicode character as Hangul. Return 0 if @uc is not
|
|
|
+ * precomposed Hangul, otherwise return the length of the decomposition.
|
|
|
+ *
|
|
|
+ * This function was adapted from sample code from the Unicode Standard
|
|
|
+ * Annex #15: Unicode Normalization Forms, version 3.2.0.
|
|
|
+ *
|
|
|
+ * Copyright (C) 1991-2018 Unicode, Inc. All rights reserved. Distributed
|
|
|
+ * under the Terms of Use in http://www.unicode.org/copyright.html.
|
|
|
+ */
|
|
|
+static int hfsplus_try_decompose_hangul(wchar_t uc, u16 *result)
|
|
|
+{
|
|
|
+ int index;
|
|
|
+ int l, v, t;
|
|
|
+
|
|
|
+ index = uc - Hangul_SBase;
|
|
|
+ if (index < 0 || index >= Hangul_SCount)
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ l = Hangul_LBase + index / Hangul_NCount;
|
|
|
+ v = Hangul_VBase + (index % Hangul_NCount) / Hangul_TCount;
|
|
|
+ t = Hangul_TBase + index % Hangul_TCount;
|
|
|
+
|
|
|
+ result[0] = l;
|
|
|
+ result[1] = v;
|
|
|
+ if (t != Hangul_TBase) {
|
|
|
+ result[2] = t;
|
|
|
+ return 3;
|
|
|
+ }
|
|
|
+ return 2;
|
|
|
+}
|
|
|
+
|
|
|
+/* Decomposes a single unicode character. */
|
|
|
+static u16 *decompose_unichar(wchar_t uc, int *size, u16 *hangul_buffer)
|
|
|
+{
|
|
|
+ u16 *result;
|
|
|
+
|
|
|
+ /* Hangul is handled separately */
|
|
|
+ result = hangul_buffer;
|
|
|
+ *size = hfsplus_try_decompose_hangul(uc, result);
|
|
|
+ if (*size == 0)
|
|
|
+ result = hfsplus_decompose_nonhangul(uc, size);
|
|
|
+ return result;
|
|
|
+}
|
|
|
+
|
|
|
int hfsplus_asc2uni(struct super_block *sb,
|
|
|
struct hfsplus_unistr *ustr, int max_unistr_len,
|
|
|
const char *astr, int len)
|
|
@@ -303,13 +348,14 @@ int hfsplus_asc2uni(struct super_block *sb,
|
|
|
int size, dsize, decompose;
|
|
|
u16 *dstr, outlen = 0;
|
|
|
wchar_t c;
|
|
|
+ u16 dhangul[3];
|
|
|
|
|
|
decompose = !test_bit(HFSPLUS_SB_NODECOMPOSE, &HFSPLUS_SB(sb)->flags);
|
|
|
while (outlen < max_unistr_len && len > 0) {
|
|
|
size = asc2unichar(sb, astr, len, &c);
|
|
|
|
|
|
if (decompose)
|
|
|
- dstr = decompose_unichar(c, &dsize);
|
|
|
+ dstr = decompose_unichar(c, &dsize, dhangul);
|
|
|
else
|
|
|
dstr = NULL;
|
|
|
if (dstr) {
|
|
@@ -344,6 +390,7 @@ int hfsplus_hash_dentry(const struct dentry *dentry, struct qstr *str)
|
|
|
unsigned long hash;
|
|
|
wchar_t c;
|
|
|
u16 c2;
|
|
|
+ u16 dhangul[3];
|
|
|
|
|
|
casefold = test_bit(HFSPLUS_SB_CASEFOLD, &HFSPLUS_SB(sb)->flags);
|
|
|
decompose = !test_bit(HFSPLUS_SB_NODECOMPOSE, &HFSPLUS_SB(sb)->flags);
|
|
@@ -357,7 +404,7 @@ int hfsplus_hash_dentry(const struct dentry *dentry, struct qstr *str)
|
|
|
len -= size;
|
|
|
|
|
|
if (decompose)
|
|
|
- dstr = decompose_unichar(c, &dsize);
|
|
|
+ dstr = decompose_unichar(c, &dsize, dhangul);
|
|
|
else
|
|
|
dstr = NULL;
|
|
|
if (dstr) {
|
|
@@ -396,6 +443,7 @@ int hfsplus_compare_dentry(const struct dentry *dentry,
|
|
|
const char *astr1, *astr2;
|
|
|
u16 c1, c2;
|
|
|
wchar_t c;
|
|
|
+ u16 dhangul_1[3], dhangul_2[3];
|
|
|
|
|
|
casefold = test_bit(HFSPLUS_SB_CASEFOLD, &HFSPLUS_SB(sb)->flags);
|
|
|
decompose = !test_bit(HFSPLUS_SB_NODECOMPOSE, &HFSPLUS_SB(sb)->flags);
|
|
@@ -413,7 +461,8 @@ int hfsplus_compare_dentry(const struct dentry *dentry,
|
|
|
len1 -= size;
|
|
|
|
|
|
if (decompose)
|
|
|
- dstr1 = decompose_unichar(c, &dsize1);
|
|
|
+ dstr1 = decompose_unichar(c, &dsize1,
|
|
|
+ dhangul_1);
|
|
|
if (!decompose || !dstr1) {
|
|
|
c1 = c;
|
|
|
dstr1 = &c1;
|
|
@@ -427,7 +476,8 @@ int hfsplus_compare_dentry(const struct dentry *dentry,
|
|
|
len2 -= size;
|
|
|
|
|
|
if (decompose)
|
|
|
- dstr2 = decompose_unichar(c, &dsize2);
|
|
|
+ dstr2 = decompose_unichar(c, &dsize2,
|
|
|
+ dhangul_2);
|
|
|
if (!decompose || !dstr2) {
|
|
|
c2 = c;
|
|
|
dstr2 = &c2;
|