diff options
Diffstat (limited to 'fs/unicode/utf8-core.c')
| -rw-r--r-- | fs/unicode/utf8-core.c | 109 | 
1 files changed, 45 insertions, 64 deletions
diff --git a/fs/unicode/utf8-core.c b/fs/unicode/utf8-core.c index dc25823bfed9..67aaadc3ab07 100644 --- a/fs/unicode/utf8-core.c +++ b/fs/unicode/utf8-core.c @@ -5,16 +5,13 @@  #include <linux/slab.h>  #include <linux/parser.h>  #include <linux/errno.h> -#include <linux/unicode.h>  #include <linux/stringhash.h>  #include "utf8n.h"  int utf8_validate(const struct unicode_map *um, const struct qstr *str)  { -	const struct utf8data *data = utf8nfdi(um->version); - -	if (utf8nlen(data, str->name, str->len) < 0) +	if (utf8nlen(um, UTF8_NFDI, str->name, str->len) < 0)  		return -1;  	return 0;  } @@ -23,14 +20,13 @@ EXPORT_SYMBOL(utf8_validate);  int utf8_strncmp(const struct unicode_map *um,  		 const struct qstr *s1, const struct qstr *s2)  { -	const struct utf8data *data = utf8nfdi(um->version);  	struct utf8cursor cur1, cur2;  	int c1, c2; -	if (utf8ncursor(&cur1, data, s1->name, s1->len) < 0) +	if (utf8ncursor(&cur1, um, UTF8_NFDI, s1->name, s1->len) < 0)  		return -EINVAL; -	if (utf8ncursor(&cur2, data, s2->name, s2->len) < 0) +	if (utf8ncursor(&cur2, um, UTF8_NFDI, s2->name, s2->len) < 0)  		return -EINVAL;  	do { @@ -50,14 +46,13 @@ EXPORT_SYMBOL(utf8_strncmp);  int utf8_strncasecmp(const struct unicode_map *um,  		     const struct qstr *s1, const struct qstr *s2)  { -	const struct utf8data *data = utf8nfdicf(um->version);  	struct utf8cursor cur1, cur2;  	int c1, c2; -	if (utf8ncursor(&cur1, data, s1->name, s1->len) < 0) +	if (utf8ncursor(&cur1, um, UTF8_NFDICF, s1->name, s1->len) < 0)  		return -EINVAL; -	if (utf8ncursor(&cur2, data, s2->name, s2->len) < 0) +	if (utf8ncursor(&cur2, um, UTF8_NFDICF, s2->name, s2->len) < 0)  		return -EINVAL;  	do { @@ -81,12 +76,11 @@ int utf8_strncasecmp_folded(const struct unicode_map *um,  			    const struct qstr *cf,  			    const struct qstr *s1)  { -	const struct utf8data *data = utf8nfdicf(um->version);  	struct utf8cursor cur1;  	int c1, c2;  	int i = 0; -	if (utf8ncursor(&cur1, data, s1->name, s1->len) < 0) +	if (utf8ncursor(&cur1, um, UTF8_NFDICF, s1->name, s1->len) < 0)  		return -EINVAL;  	do { @@ -105,11 +99,10 @@ EXPORT_SYMBOL(utf8_strncasecmp_folded);  int utf8_casefold(const struct unicode_map *um, const struct qstr *str,  		  unsigned char *dest, size_t dlen)  { -	const struct utf8data *data = utf8nfdicf(um->version);  	struct utf8cursor cur;  	size_t nlen = 0; -	if (utf8ncursor(&cur, data, str->name, str->len) < 0) +	if (utf8ncursor(&cur, um, UTF8_NFDICF, str->name, str->len) < 0)  		return -EINVAL;  	for (nlen = 0; nlen < dlen; nlen++) { @@ -128,12 +121,11 @@ EXPORT_SYMBOL(utf8_casefold);  int utf8_casefold_hash(const struct unicode_map *um, const void *salt,  		       struct qstr *str)  { -	const struct utf8data *data = utf8nfdicf(um->version);  	struct utf8cursor cur;  	int c;  	unsigned long hash = init_name_hash(salt); -	if (utf8ncursor(&cur, data, str->name, str->len) < 0) +	if (utf8ncursor(&cur, um, UTF8_NFDICF, str->name, str->len) < 0)  		return -EINVAL;  	while ((c = utf8byte(&cur))) { @@ -149,11 +141,10 @@ EXPORT_SYMBOL(utf8_casefold_hash);  int utf8_normalize(const struct unicode_map *um, const struct qstr *str,  		   unsigned char *dest, size_t dlen)  { -	const struct utf8data *data = utf8nfdi(um->version);  	struct utf8cursor cur;  	ssize_t nlen = 0; -	if (utf8ncursor(&cur, data, str->name, str->len) < 0) +	if (utf8ncursor(&cur, um, UTF8_NFDI, str->name, str->len) < 0)  		return -EINVAL;  	for (nlen = 0; nlen < dlen; nlen++) { @@ -167,69 +158,59 @@ int utf8_normalize(const struct unicode_map *um, const struct qstr *str,  	}  	return -EINVAL;  } -  EXPORT_SYMBOL(utf8_normalize); -static int utf8_parse_version(const char *version, unsigned int *maj, -			      unsigned int *min, unsigned int *rev) +static const struct utf8data *find_table_version(const struct utf8data *table, +		size_t nr_entries, unsigned int version)  { -	substring_t args[3]; -	char version_string[12]; -	static const struct match_token token[] = { -		{1, "%d.%d.%d"}, -		{0, NULL} -	}; - -	strncpy(version_string, version, sizeof(version_string)); - -	if (match_token(version_string, token, args) != 1) -		return -EINVAL; - -	if (match_int(&args[0], maj) || match_int(&args[1], min) || -	    match_int(&args[2], rev)) -		return -EINVAL; +	size_t i = nr_entries - 1; -	return 0; +	while (version < table[i].maxage) +		i--; +	if (version > table[i].maxage) +		return NULL; +	return &table[i];  } -struct unicode_map *utf8_load(const char *version) +struct unicode_map *utf8_load(unsigned int version)  { -	struct unicode_map *um = NULL; -	int unicode_version; - -	if (version) { -		unsigned int maj, min, rev; - -		if (utf8_parse_version(version, &maj, &min, &rev) < 0) -			return ERR_PTR(-EINVAL); - -		if (!utf8version_is_supported(maj, min, rev)) -			return ERR_PTR(-EINVAL); - -		unicode_version = UNICODE_AGE(maj, min, rev); -	} else { -		unicode_version = utf8version_latest(); -		printk(KERN_WARNING"UTF-8 version not specified. " -		       "Assuming latest supported version (%d.%d.%d).", -		       (unicode_version >> 16) & 0xff, -		       (unicode_version >> 8) & 0xff, -		       (unicode_version & 0xff)); -	} +	struct unicode_map *um;  	um = kzalloc(sizeof(struct unicode_map), GFP_KERNEL);  	if (!um)  		return ERR_PTR(-ENOMEM); - -	um->charset = "UTF-8"; -	um->version = unicode_version; - +	um->version = version; + +	um->tables = symbol_request(utf8_data_table); +	if (!um->tables) +		goto out_free_um; + +	if (!utf8version_is_supported(um, version)) +		goto out_symbol_put; +	um->ntab[UTF8_NFDI] = find_table_version(um->tables->utf8nfdidata, +			um->tables->utf8nfdidata_size, um->version); +	if (!um->ntab[UTF8_NFDI]) +		goto out_symbol_put; +	um->ntab[UTF8_NFDICF] = find_table_version(um->tables->utf8nfdicfdata, +			um->tables->utf8nfdicfdata_size, um->version); +	if (!um->ntab[UTF8_NFDICF]) +		goto out_symbol_put;  	return um; + +out_symbol_put: +	symbol_put(um->tables); +out_free_um: +	kfree(um); +	return ERR_PTR(-EINVAL);  }  EXPORT_SYMBOL(utf8_load);  void utf8_unload(struct unicode_map *um)  { -	kfree(um); +	if (um) { +		symbol_put(utf8_data_table); +		kfree(um); +	}  }  EXPORT_SYMBOL(utf8_unload);  |