Support non-BMP characters in NTFS.
Subsystems (2)
PATCH 7/8 Support non-BMP characters in NTFS.
ntfs-3g supports non-BMP characters just fine. This patch make standard read-only driver work as well. Patch is bigger than required since checkpatch.pl asked me to restructure the code to avoid overlong lines.
Signed-off-by Vladimir Serbinenko <[email protected]>
--- fs/ntfs/unistr.c | 70 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 41 insertions(+), 29 deletions(-)
fs/ntfs/unistr.c +41 -29
@@ -265,33 +265,35 @@ int ntfs_nlstoucs(const ntfs_volume *vol, const char *ins,int i, o, wc_len;/* We do not trust outside sources. */ -if (likely (ins)) { - ucs =kmem_cache_alloc (ntfs_name_cache,GFP_NOFS ); -if (likely (ucs)) { -for (i = o =0 ; i < ins_len; i += wc_len) { - wc_len = nls->char2uni (ins + i, ins_len - i, - &wc); -if (likely (wc_len >=0 && wc <=0xffff - && o <NTFS_MAX_NAME_LEN )) { -if (likely (wc)) { - ucs[o++] =cpu_to_le16 (wc); -continue ; - }/* else if (!wc) */ -break ; - }/* else if (wc_len < 0 || -o >= NTFS_MAX_NAME_LEN) */ - goto name_err; - } - ucs[o] =0 ; - *outs = ucs; -return o; - }/* else if (!ucs) */ -ntfs_error (vol->sb,"Failed to allocate buffer for converted " -"name from ntfs_name_cache." ); +if (unlikely (!ins)) { +ntfs_error (vol->sb,"Received NULL pointer." ); +return -EINVAL ; + } + + ucs =kmem_cache_alloc (ntfs_name_cache,GFP_NOFS ); +if (unlikely (!ucs)) { +ntfs_error (vol->sb, +"Failed to allocate buffer for converted " +"name from ntfs_name_cache." );return -ENOMEM ; - }/* else if (!ins) */ -ntfs_error (vol->sb,"Received NULL pointer." ); -return -EINVAL ; + } + +for (i = o =0 ; i < ins_len; i += wc_len) { +int s; + wc_len = nls->char2uni (ins + i, ins_len - i, &wc); +if (unlikely (wc_len <0 || o >=NTFS_MAX_NAME_LEN )) + goto name_err; +if (unlikely (!wc)) +break ; + s =unicode_to_utf16s (wc,UTF16_LITTLE_ENDIAN , ucs + o, +NTFS_MAX_NAME_LEN - o); +if (s <=0 ) +break ; + o += s; + } + ucs[o] =0 ; + *outs = ucs; +return o; name_err:kmem_cache_free (ntfs_name_cache, ucs);if (wc_len <0 ) {
@@ -342,6 +344,7 @@ int ntfs_ucstonls(const ntfs_volume *vol, const ntfschar *ins,/* We don't trust outside sources. */ if (ins) { +int step; ns = *outs; ns_len = outs_len;if (ns && !ns_len) {
@@ -354,9 +357,18 @@ int ntfs_ucstonls(const ntfs_volume *vol, const ntfschar *ins,if (!ns) goto mem_err_out; } -for (i = o =0 ; i < ins_len; i++) { -retry: wc = nls->uni2char (le16_to_cpu (ins[i]), ns + o, - ns_len - o); +for (i = o =0 ; i < ins_len; i += step) { +unicode_t uni; +retry: + step =utf16s_to_unicode (ins + i, ins_len - i, +UTF16_LITTLE_ENDIAN , + &uni); +if (step <=0 ) { + uni =le16_to_cpu (ins[i]); + step =1 ; + } + + wc = nls->uni2char (uni, ns + o, ns_len - o);if (wc >0 ) { o += wc;continue ;
Signature · 5 lines
1.7.10 -- Regards Vladimir 'φ-coder/phcoder' Serbinenko