1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright (C) International Business Machines Corp., 2000-2004 4 */ 5 6 #include <linux/fs.h> 7 #include <linux/slab.h> 8 #include "jfs_incore.h" 9 #include "jfs_filsys.h" 10 #include "jfs_unicode.h" 11 #include "jfs_debug.h" 12 13 /* 14 * NAME: jfs_strfromUCS() 15 * 16 * FUNCTION: Convert little-endian unicode string to character string 17 * 18 */ 19 int jfs_strfromUCS_le(char *to, const __le16 * from, 20 int len, struct nls_table *codepage) 21 { 22 int i; 23 int outlen = 0; 24 static int warn_again = 5; /* Only warn up to 5 times total */ 25 int warn = !!warn_again; /* once per string */ 26 27 if (codepage) { 28 for (i = 0; (i < len) && from[i]; i++) { 29 int charlen; 30 charlen = 31 codepage->uni2char(le16_to_cpu(from[i]), 32 &to[outlen], 33 NLS_MAX_CHARSET_SIZE); 34 if (charlen > 0) 35 outlen += charlen; 36 else 37 to[outlen++] = '?'; 38 } 39 } else { 40 for (i = 0; (i < len) && from[i]; i++) { 41 if (unlikely(le16_to_cpu(from[i]) & 0xff00)) { 42 to[i] = '?'; 43 if (unlikely(warn)) { 44 warn--; 45 warn_again--; 46 printk(KERN_ERR 47 "non-latin1 character 0x%x found in JFS file name\n", 48 le16_to_cpu(from[i])); 49 printk(KERN_ERR 50 "mount with iocharset=utf8 to access\n"); 51 } 52 53 } 54 else 55 to[i] = (char) (le16_to_cpu(from[i])); 56 } 57 outlen = i; 58 } 59 to[outlen] = 0; 60 return outlen; 61 } 62 63 /* 64 * NAME: jfs_strtoUCS() 65 * 66 * FUNCTION: Convert character string to unicode string 67 * 68 */ 69 static int jfs_strtoUCS(wchar_t * to, const unsigned char *from, int len, 70 struct nls_table *codepage) 71 { 72 int charlen; 73 int i; 74 75 if (codepage) { 76 for (i = 0; len && *from; i++, from += charlen, len -= charlen) 77 { 78 charlen = codepage->char2uni(from, len, &to[i]); 79 if (charlen < 1) { 80 jfs_err("jfs_strtoUCS: char2uni returned %d.", 81 charlen); 82 jfs_err("charset = %s, char = 0x%x", 83 codepage->charset, *from); 84 return charlen; 85 } 86 } 87 } else { 88 for (i = 0; (i < len) && from[i]; i++) 89 to[i] = (wchar_t) from[i]; 90 } 91 92 to[i] = 0; 93 return i; 94 } 95 96 /* 97 * NAME: get_UCSname() 98 * 99 * FUNCTION: Allocate and translate to unicode string 100 * 101 */ 102 int get_UCSname(struct component_name * uniName, struct dentry *dentry) 103 { 104 struct nls_table *nls_tab = JFS_SBI(dentry->d_sb)->nls_tab; 105 int length = dentry->d_name.len; 106 107 if (length > JFS_NAME_MAX) 108 return -ENAMETOOLONG; 109 110 uniName->name = 111 kmalloc_array(length + 1, sizeof(wchar_t), GFP_NOFS); 112 113 if (uniName->name == NULL) 114 return -ENOMEM; 115 116 uniName->namlen = jfs_strtoUCS(uniName->name, dentry->d_name.name, 117 length, nls_tab); 118 119 if (uniName->namlen < 0) { 120 kfree(uniName->name); 121 return uniName->namlen; 122 } 123 124 return 0; 125 } 126