root/fs/unicode/utf8-core.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. utf8_validate
  2. utf8_strncmp
  3. utf8_strncasecmp
  4. utf8_strncasecmp_folded
  5. utf8_casefold
  6. utf8_normalize
  7. utf8_parse_version
  8. utf8_load
  9. utf8_unload

   1 /* SPDX-License-Identifier: GPL-2.0 */
   2 #include <linux/module.h>
   3 #include <linux/kernel.h>
   4 #include <linux/string.h>
   5 #include <linux/slab.h>
   6 #include <linux/parser.h>
   7 #include <linux/errno.h>
   8 #include <linux/unicode.h>
   9 
  10 #include "utf8n.h"
  11 
  12 int utf8_validate(const struct unicode_map *um, const struct qstr *str)
  13 {
  14         const struct utf8data *data = utf8nfdi(um->version);
  15 
  16         if (utf8nlen(data, str->name, str->len) < 0)
  17                 return -1;
  18         return 0;
  19 }
  20 EXPORT_SYMBOL(utf8_validate);
  21 
  22 int utf8_strncmp(const struct unicode_map *um,
  23                  const struct qstr *s1, const struct qstr *s2)
  24 {
  25         const struct utf8data *data = utf8nfdi(um->version);
  26         struct utf8cursor cur1, cur2;
  27         int c1, c2;
  28 
  29         if (utf8ncursor(&cur1, data, s1->name, s1->len) < 0)
  30                 return -EINVAL;
  31 
  32         if (utf8ncursor(&cur2, data, s2->name, s2->len) < 0)
  33                 return -EINVAL;
  34 
  35         do {
  36                 c1 = utf8byte(&cur1);
  37                 c2 = utf8byte(&cur2);
  38 
  39                 if (c1 < 0 || c2 < 0)
  40                         return -EINVAL;
  41                 if (c1 != c2)
  42                         return 1;
  43         } while (c1);
  44 
  45         return 0;
  46 }
  47 EXPORT_SYMBOL(utf8_strncmp);
  48 
  49 int utf8_strncasecmp(const struct unicode_map *um,
  50                      const struct qstr *s1, const struct qstr *s2)
  51 {
  52         const struct utf8data *data = utf8nfdicf(um->version);
  53         struct utf8cursor cur1, cur2;
  54         int c1, c2;
  55 
  56         if (utf8ncursor(&cur1, data, s1->name, s1->len) < 0)
  57                 return -EINVAL;
  58 
  59         if (utf8ncursor(&cur2, data, s2->name, s2->len) < 0)
  60                 return -EINVAL;
  61 
  62         do {
  63                 c1 = utf8byte(&cur1);
  64                 c2 = utf8byte(&cur2);
  65 
  66                 if (c1 < 0 || c2 < 0)
  67                         return -EINVAL;
  68                 if (c1 != c2)
  69                         return 1;
  70         } while (c1);
  71 
  72         return 0;
  73 }
  74 EXPORT_SYMBOL(utf8_strncasecmp);
  75 
  76 /* String cf is expected to be a valid UTF-8 casefolded
  77  * string.
  78  */
  79 int utf8_strncasecmp_folded(const struct unicode_map *um,
  80                             const struct qstr *cf,
  81                             const struct qstr *s1)
  82 {
  83         const struct utf8data *data = utf8nfdicf(um->version);
  84         struct utf8cursor cur1;
  85         int c1, c2;
  86         int i = 0;
  87 
  88         if (utf8ncursor(&cur1, data, s1->name, s1->len) < 0)
  89                 return -EINVAL;
  90 
  91         do {
  92                 c1 = utf8byte(&cur1);
  93                 c2 = cf->name[i++];
  94                 if (c1 < 0)
  95                         return -EINVAL;
  96                 if (c1 != c2)
  97                         return 1;
  98         } while (c1);
  99 
 100         return 0;
 101 }
 102 EXPORT_SYMBOL(utf8_strncasecmp_folded);
 103 
 104 int utf8_casefold(const struct unicode_map *um, const struct qstr *str,
 105                   unsigned char *dest, size_t dlen)
 106 {
 107         const struct utf8data *data = utf8nfdicf(um->version);
 108         struct utf8cursor cur;
 109         size_t nlen = 0;
 110 
 111         if (utf8ncursor(&cur, data, str->name, str->len) < 0)
 112                 return -EINVAL;
 113 
 114         for (nlen = 0; nlen < dlen; nlen++) {
 115                 int c = utf8byte(&cur);
 116 
 117                 dest[nlen] = c;
 118                 if (!c)
 119                         return nlen;
 120                 if (c == -1)
 121                         break;
 122         }
 123         return -EINVAL;
 124 }
 125 
 126 EXPORT_SYMBOL(utf8_casefold);
 127 
 128 int utf8_normalize(const struct unicode_map *um, const struct qstr *str,
 129                    unsigned char *dest, size_t dlen)
 130 {
 131         const struct utf8data *data = utf8nfdi(um->version);
 132         struct utf8cursor cur;
 133         ssize_t nlen = 0;
 134 
 135         if (utf8ncursor(&cur, data, str->name, str->len) < 0)
 136                 return -EINVAL;
 137 
 138         for (nlen = 0; nlen < dlen; nlen++) {
 139                 int c = utf8byte(&cur);
 140 
 141                 dest[nlen] = c;
 142                 if (!c)
 143                         return nlen;
 144                 if (c == -1)
 145                         break;
 146         }
 147         return -EINVAL;
 148 }
 149 
 150 EXPORT_SYMBOL(utf8_normalize);
 151 
 152 static int utf8_parse_version(const char *version, unsigned int *maj,
 153                               unsigned int *min, unsigned int *rev)
 154 {
 155         substring_t args[3];
 156         char version_string[12];
 157         static const struct match_token token[] = {
 158                 {1, "%d.%d.%d"},
 159                 {0, NULL}
 160         };
 161 
 162         strncpy(version_string, version, sizeof(version_string));
 163 
 164         if (match_token(version_string, token, args) != 1)
 165                 return -EINVAL;
 166 
 167         if (match_int(&args[0], maj) || match_int(&args[1], min) ||
 168             match_int(&args[2], rev))
 169                 return -EINVAL;
 170 
 171         return 0;
 172 }
 173 
 174 struct unicode_map *utf8_load(const char *version)
 175 {
 176         struct unicode_map *um = NULL;
 177         int unicode_version;
 178 
 179         if (version) {
 180                 unsigned int maj, min, rev;
 181 
 182                 if (utf8_parse_version(version, &maj, &min, &rev) < 0)
 183                         return ERR_PTR(-EINVAL);
 184 
 185                 if (!utf8version_is_supported(maj, min, rev))
 186                         return ERR_PTR(-EINVAL);
 187 
 188                 unicode_version = UNICODE_AGE(maj, min, rev);
 189         } else {
 190                 unicode_version = utf8version_latest();
 191                 printk(KERN_WARNING"UTF-8 version not specified. "
 192                        "Assuming latest supported version (%d.%d.%d).",
 193                        (unicode_version >> 16) & 0xff,
 194                        (unicode_version >> 8) & 0xff,
 195                        (unicode_version & 0xff));
 196         }
 197 
 198         um = kzalloc(sizeof(struct unicode_map), GFP_KERNEL);
 199         if (!um)
 200                 return ERR_PTR(-ENOMEM);
 201 
 202         um->charset = "UTF-8";
 203         um->version = unicode_version;
 204 
 205         return um;
 206 }
 207 EXPORT_SYMBOL(utf8_load);
 208 
 209 void utf8_unload(struct unicode_map *um)
 210 {
 211         kfree(um);
 212 }
 213 EXPORT_SYMBOL(utf8_unload);
 214 
 215 MODULE_LICENSE("GPL v2");

/* [<][>][^][v][top][bottom][index][help] */