diff options
Diffstat (limited to 'fs/hfsplus/unicode.c')
| -rw-r--r-- | fs/hfsplus/unicode.c | 95 | 
1 files changed, 62 insertions, 33 deletions
diff --git a/fs/hfsplus/unicode.c b/fs/hfsplus/unicode.c index b66d67de882..e8ef121a4d8 100644 --- a/fs/hfsplus/unicode.c +++ b/fs/hfsplus/unicode.c @@ -17,14 +17,14 @@  /* Returns folded char, or 0 if ignorable */  static inline u16 case_fold(u16 c)  { -        u16 tmp; - -        tmp = hfsplus_case_fold_table[c >> 8]; -        if (tmp) -                tmp = hfsplus_case_fold_table[tmp + (c & 0xff)]; -        else -                tmp = c; -        return tmp; +	u16 tmp; + +	tmp = hfsplus_case_fold_table[c >> 8]; +	if (tmp) +		tmp = hfsplus_case_fold_table[tmp + (c & 0xff)]; +	else +		tmp = c; +	return tmp;  }  /* Compare unicode strings, return values like normal strcmp */ @@ -118,7 +118,9 @@ static u16 *hfsplus_compose_lookup(u16 *p, u16 cc)  	return NULL;  } -int hfsplus_uni2asc(struct super_block *sb, const struct hfsplus_unistr *ustr, char *astr, int *len_p) +int hfsplus_uni2asc(struct super_block *sb, +		const struct hfsplus_unistr *ustr, +		char *astr, int *len_p)  {  	const hfsplus_unichr *ip;  	struct nls_table *nls = HFSPLUS_SB(sb)->nls; @@ -140,7 +142,11 @@ int hfsplus_uni2asc(struct super_block *sb, const struct hfsplus_unistr *ustr, c  		/* search for single decomposed char */  		if (likely(compose))  			ce1 = hfsplus_compose_lookup(hfsplus_compose_table, c0); -		if (ce1 && (cc = ce1[0])) { +		if (ce1) +			cc = ce1[0]; +		else +			cc = 0; +		if (cc) {  			/* start of a possibly decomposed Hangul char */  			if (cc != 0xffff)  				goto done; @@ -171,7 +177,8 @@ int hfsplus_uni2asc(struct super_block *sb, const struct hfsplus_unistr *ustr, c  				goto same;  			c1 = be16_to_cpu(*ip);  			if (likely(compose)) -				ce1 = hfsplus_compose_lookup(hfsplus_compose_table, c1); +				ce1 = hfsplus_compose_lookup( +					hfsplus_compose_table, c1);  			if (ce1)  				break;  			switch (c0) { @@ -199,19 +206,21 @@ int hfsplus_uni2asc(struct super_block *sb, const struct hfsplus_unistr *ustr, c  		if (ce2) {  			i = 1;  			while (i < ustrlen) { -				ce1 = hfsplus_compose_lookup(ce2, be16_to_cpu(ip[i])); +				ce1 = hfsplus_compose_lookup(ce2, +					be16_to_cpu(ip[i]));  				if (!ce1)  					break;  				i++;  				ce2 = ce1;  			} -			if ((cc = ce2[0])) { +			cc = ce2[0]; +			if (cc) {  				ip += i;  				ustrlen -= i;  				goto done;  			}  		} -	same: +same:  		switch (c0) {  		case 0:  			cc = 0x2400; @@ -222,7 +231,7 @@ int hfsplus_uni2asc(struct super_block *sb, const struct hfsplus_unistr *ustr, c  		default:  			cc = c0;  		} -	done: +done:  		res = nls->uni2char(cc, op, len);  		if (res < 0) {  			if (res == -ENAMETOOLONG) @@ -286,7 +295,8 @@ static inline u16 *decompose_unichar(wchar_t uc, int *size)  	return hfsplus_decompose_table + (off / 4);  } -int hfsplus_asc2uni(struct super_block *sb, struct hfsplus_unistr *ustr, +int hfsplus_asc2uni(struct super_block *sb, +		    struct hfsplus_unistr *ustr, int max_unistr_len,  		    const char *astr, int len)  {  	int size, dsize, decompose; @@ -294,11 +304,15 @@ int hfsplus_asc2uni(struct super_block *sb, struct hfsplus_unistr *ustr,  	wchar_t c;  	decompose = !test_bit(HFSPLUS_SB_NODECOMPOSE, &HFSPLUS_SB(sb)->flags); -	while (outlen < HFSPLUS_MAX_STRLEN && len > 0) { +	while (outlen < max_unistr_len && len > 0) {  		size = asc2unichar(sb, astr, len, &c); -		if (decompose && (dstr = decompose_unichar(c, &dsize))) { -			if (outlen + dsize > HFSPLUS_MAX_STRLEN) +		if (decompose) +			dstr = decompose_unichar(c, &dsize); +		else +			dstr = NULL; +		if (dstr) { +			if (outlen + dsize > max_unistr_len)  				break;  			do {  				ustr->unicode[outlen++] = cpu_to_be16(*dstr++); @@ -320,7 +334,7 @@ int hfsplus_asc2uni(struct super_block *sb, struct hfsplus_unistr *ustr,   * Composed unicode characters are decomposed and case-folding is performed   * if the appropriate bits are (un)set on the superblock.   */ -int hfsplus_hash_dentry(struct dentry *dentry, struct qstr *str) +int hfsplus_hash_dentry(const struct dentry *dentry, struct qstr *str)  {  	struct super_block *sb = dentry->d_sb;  	const char *astr; @@ -341,15 +355,23 @@ int hfsplus_hash_dentry(struct dentry *dentry, struct qstr *str)  		astr += size;  		len -= size; -		if (decompose && (dstr = decompose_unichar(c, &dsize))) { +		if (decompose) +			dstr = decompose_unichar(c, &dsize); +		else +			dstr = NULL; +		if (dstr) {  			do {  				c2 = *dstr++; -				if (!casefold || (c2 = case_fold(c2))) +				if (casefold) +					c2 = case_fold(c2); +				if (!casefold || c2)  					hash = partial_name_hash(c2, hash);  			} while (--dsize > 0);  		} else {  			c2 = c; -			if (!casefold || (c2 = case_fold(c2))) +			if (casefold) +				c2 = case_fold(c2); +			if (!casefold || c2)  				hash = partial_name_hash(c2, hash);  		}  	} @@ -363,9 +385,10 @@ int hfsplus_hash_dentry(struct dentry *dentry, struct qstr *str)   * Composed unicode characters are decomposed and case-folding is performed   * if the appropriate bits are (un)set on the superblock.   */ -int hfsplus_compare_dentry(struct dentry *dentry, struct qstr *s1, struct qstr *s2) +int hfsplus_compare_dentry(const struct dentry *parent, const struct dentry *dentry, +		unsigned int len, const char *str, const struct qstr *name)  { -	struct super_block *sb = dentry->d_sb; +	struct super_block *sb = parent->d_sb;  	int casefold, decompose, size;  	int dsize1, dsize2, len1, len2;  	const u16 *dstr1, *dstr2; @@ -375,10 +398,10 @@ int hfsplus_compare_dentry(struct dentry *dentry, struct qstr *s1, struct qstr *  	casefold = test_bit(HFSPLUS_SB_CASEFOLD, &HFSPLUS_SB(sb)->flags);  	decompose = !test_bit(HFSPLUS_SB_NODECOMPOSE, &HFSPLUS_SB(sb)->flags); -	astr1 = s1->name; -	len1 = s1->len; -	astr2 = s2->name; -	len2 = s2->len; +	astr1 = str; +	len1 = len; +	astr2 = name->name; +	len2 = name->len;  	dsize1 = dsize2 = 0;  	dstr1 = dstr2 = NULL; @@ -388,7 +411,9 @@ int hfsplus_compare_dentry(struct dentry *dentry, struct qstr *s1, struct qstr *  			astr1 += size;  			len1 -= size; -			if (!decompose || !(dstr1 = decompose_unichar(c, &dsize1))) { +			if (decompose) +				dstr1 = decompose_unichar(c, &dsize1); +			if (!decompose || !dstr1) {  				c1 = c;  				dstr1 = &c1;  				dsize1 = 1; @@ -400,7 +425,9 @@ int hfsplus_compare_dentry(struct dentry *dentry, struct qstr *s1, struct qstr *  			astr2 += size;  			len2 -= size; -			if (!decompose || !(dstr2 = decompose_unichar(c, &dsize2))) { +			if (decompose) +				dstr2 = decompose_unichar(c, &dsize2); +			if (!decompose || !dstr2) {  				c2 = c;  				dstr2 = &c2;  				dsize2 = 1; @@ -410,12 +437,14 @@ int hfsplus_compare_dentry(struct dentry *dentry, struct qstr *s1, struct qstr *  		c1 = *dstr1;  		c2 = *dstr2;  		if (casefold) { -			if  (!(c1 = case_fold(c1))) { +			c1 = case_fold(c1); +			if (!c1) {  				dstr1++;  				dsize1--;  				continue;  			} -			if (!(c2 = case_fold(c2))) { +			c2 = case_fold(c2); +			if (!c2) {  				dstr2++;  				dsize2--;  				continue;  | 
