X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=fs%2Fntfs%2Funistr.c;h=b123c0fa6bf6a4d7b10ad1c7cda1dcd1ec0ddf9c;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=560b0ea255b0b6be01b5f3abcb4ad9d572c457da;hpb=cee37fe97739d85991964371c1f3a745c00dd236;p=linux-2.6.git diff --git a/fs/ntfs/unistr.c b/fs/ntfs/unistr.c index 560b0ea25..b123c0fa6 100644 --- a/fs/ntfs/unistr.c +++ b/fs/ntfs/unistr.c @@ -1,7 +1,7 @@ /* * unistr.c - NTFS Unicode string handling. Part of the Linux-NTFS project. * - * Copyright (c) 2001-2004 Anton Altaparmakov + * Copyright (c) 2001-2006 Anton Altaparmakov * * This program/include file is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as published @@ -19,6 +19,8 @@ * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include + #include "types.h" #include "debug.h" #include "ntfs.h" @@ -242,7 +244,7 @@ int ntfs_file_compare_values(FILE_NAME_ATTR *file_name_attr1, * map dictates, into a little endian, 2-byte Unicode string. * * This function allocates the string and the caller is responsible for - * calling kmem_cache_free(ntfs_name_cache, @outs); when finished with it. + * calling kmem_cache_free(ntfs_name_cache, *@outs); when finished with it. * * On success the function returns the number of Unicode characters written to * the output string *@outs (>= 0), not counting the terminating Unicode NULL @@ -262,37 +264,48 @@ int ntfs_nlstoucs(const ntfs_volume *vol, const char *ins, wchar_t wc; int i, o, wc_len; - /* We don't trust outside sources. */ - if (ins) { - ucs = (ntfschar*)kmem_cache_alloc(ntfs_name_cache, SLAB_NOFS); - if (ucs) { + /* We do not trust outside sources. */ + if (likely(ins)) { + ucs = kmem_cache_alloc(ntfs_name_cache, SLAB_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 (wc_len >= 0) { - if (wc) { + if (likely(wc_len >= 0 && + o < NTFS_MAX_NAME_LEN)) { + if (likely(wc)) { ucs[o++] = cpu_to_le16(wc); continue; - } /* else (!wc) */ + } /* else if (!wc) */ break; - } /* else (wc_len < 0) */ - goto conversion_err; + } /* else if (wc_len < 0 || + o >= NTFS_MAX_NAME_LEN) */ + goto name_err; } ucs[o] = 0; *outs = ucs; return o; - } /* else (!ucs) */ - ntfs_error(vol->sb, "Failed to allocate name from " - "ntfs_name_cache!"); + } /* else if (!ucs) */ + ntfs_error(vol->sb, "Failed to allocate buffer for converted " + "name from ntfs_name_cache."); return -ENOMEM; - } /* else (!ins) */ - ntfs_error(NULL, "Received NULL pointer."); + } /* else if (!ins) */ + ntfs_error(vol->sb, "Received NULL pointer."); return -EINVAL; -conversion_err: - ntfs_error(vol->sb, "Name using character set %s contains characters " - "that cannot be converted to Unicode.", nls->charset); +name_err: kmem_cache_free(ntfs_name_cache, ucs); - return -EILSEQ; + if (wc_len < 0) { + ntfs_error(vol->sb, "Name using character set %s contains " + "characters that cannot be converted to " + "Unicode.", nls->charset); + i = -EILSEQ; + } else /* if (o >= NTFS_MAX_NAME_LEN) */ { + ntfs_error(vol->sb, "Name is too long (maximum length for a " + "name on NTFS is %d Unicode characters.", + NTFS_MAX_NAME_LEN); + i = -ENAMETOOLONG; + } + return i; } /** @@ -372,7 +385,8 @@ retry: wc = nls->uni2char(le16_to_cpu(ins[i]), ns + o, return -EINVAL; conversion_err: ntfs_error(vol->sb, "Unicode name contains characters that cannot be " - "converted to character set %s.", nls->charset); + "converted to character set %s. You might want to " + "try to use the mount option nls=utf8.", nls->charset); if (ns != *outs) kfree(ns); if (wc != -ENAMETOOLONG)