diff options
author | Anton Altaparmakov <aia21@cantab.net> | 2006-03-23 11:05:11 -0500 |
---|---|---|
committer | Anton Altaparmakov <aia21@cantab.net> | 2006-03-23 11:05:11 -0500 |
commit | d4faf636d6f8d8940174e38317161eb08a7a57ec (patch) | |
tree | 9d9b54e5c41fa5c4c1f4cd8f8d5e3363ec71ffde /fs/ntfs/unistr.c | |
parent | f95c4018fd4b0bdef9b1bcb4eac7056e2a07282a (diff) |
NTFS: Limit name length in fs/ntfs/unistr.c::ntfs_nlstoucs() to maximum
allowed by NTFS, i.e. 255 Unicode characters, not including the
terminating NULL (which is not stored on disk).
Signed-off-by: Anton Altaparmakov <aia21@cantab.net>
Diffstat (limited to 'fs/ntfs/unistr.c')
-rw-r--r-- | fs/ntfs/unistr.c | 51 |
1 files changed, 32 insertions, 19 deletions
diff --git a/fs/ntfs/unistr.c b/fs/ntfs/unistr.c index 0ea887fc859c..b123c0fa6bf6 100644 --- a/fs/ntfs/unistr.c +++ b/fs/ntfs/unistr.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * unistr.c - NTFS Unicode string handling. Part of the Linux-NTFS project. | 2 | * unistr.c - NTFS Unicode string handling. Part of the Linux-NTFS project. |
3 | * | 3 | * |
4 | * Copyright (c) 2001-2005 Anton Altaparmakov | 4 | * Copyright (c) 2001-2006 Anton Altaparmakov |
5 | * | 5 | * |
6 | * This program/include file is free software; you can redistribute it and/or | 6 | * This program/include file is free software; you can redistribute it and/or |
7 | * modify it under the terms of the GNU General Public License as published | 7 | * modify it under the terms of the GNU General Public License as published |
@@ -19,6 +19,8 @@ | |||
19 | * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 19 | * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include <linux/slab.h> | ||
23 | |||
22 | #include "types.h" | 24 | #include "types.h" |
23 | #include "debug.h" | 25 | #include "debug.h" |
24 | #include "ntfs.h" | 26 | #include "ntfs.h" |
@@ -242,7 +244,7 @@ int ntfs_file_compare_values(FILE_NAME_ATTR *file_name_attr1, | |||
242 | * map dictates, into a little endian, 2-byte Unicode string. | 244 | * map dictates, into a little endian, 2-byte Unicode string. |
243 | * | 245 | * |
244 | * This function allocates the string and the caller is responsible for | 246 | * This function allocates the string and the caller is responsible for |
245 | * calling kmem_cache_free(ntfs_name_cache, @outs); when finished with it. | 247 | * calling kmem_cache_free(ntfs_name_cache, *@outs); when finished with it. |
246 | * | 248 | * |
247 | * On success the function returns the number of Unicode characters written to | 249 | * On success the function returns the number of Unicode characters written to |
248 | * the output string *@outs (>= 0), not counting the terminating Unicode NULL | 250 | * 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, | |||
262 | wchar_t wc; | 264 | wchar_t wc; |
263 | int i, o, wc_len; | 265 | int i, o, wc_len; |
264 | 266 | ||
265 | /* We don't trust outside sources. */ | 267 | /* We do not trust outside sources. */ |
266 | if (ins) { | 268 | if (likely(ins)) { |
267 | ucs = kmem_cache_alloc(ntfs_name_cache, SLAB_NOFS); | 269 | ucs = kmem_cache_alloc(ntfs_name_cache, SLAB_NOFS); |
268 | if (ucs) { | 270 | if (likely(ucs)) { |
269 | for (i = o = 0; i < ins_len; i += wc_len) { | 271 | for (i = o = 0; i < ins_len; i += wc_len) { |
270 | wc_len = nls->char2uni(ins + i, ins_len - i, | 272 | wc_len = nls->char2uni(ins + i, ins_len - i, |
271 | &wc); | 273 | &wc); |
272 | if (wc_len >= 0) { | 274 | if (likely(wc_len >= 0 && |
273 | if (wc) { | 275 | o < NTFS_MAX_NAME_LEN)) { |
276 | if (likely(wc)) { | ||
274 | ucs[o++] = cpu_to_le16(wc); | 277 | ucs[o++] = cpu_to_le16(wc); |
275 | continue; | 278 | continue; |
276 | } /* else (!wc) */ | 279 | } /* else if (!wc) */ |
277 | break; | 280 | break; |
278 | } /* else (wc_len < 0) */ | 281 | } /* else if (wc_len < 0 || |
279 | goto conversion_err; | 282 | o >= NTFS_MAX_NAME_LEN) */ |
283 | goto name_err; | ||
280 | } | 284 | } |
281 | ucs[o] = 0; | 285 | ucs[o] = 0; |
282 | *outs = ucs; | 286 | *outs = ucs; |
283 | return o; | 287 | return o; |
284 | } /* else (!ucs) */ | 288 | } /* else if (!ucs) */ |
285 | ntfs_error(vol->sb, "Failed to allocate name from " | 289 | ntfs_error(vol->sb, "Failed to allocate buffer for converted " |
286 | "ntfs_name_cache!"); | 290 | "name from ntfs_name_cache."); |
287 | return -ENOMEM; | 291 | return -ENOMEM; |
288 | } /* else (!ins) */ | 292 | } /* else if (!ins) */ |
289 | ntfs_error(NULL, "Received NULL pointer."); | 293 | ntfs_error(vol->sb, "Received NULL pointer."); |
290 | return -EINVAL; | 294 | return -EINVAL; |
291 | conversion_err: | 295 | name_err: |
292 | ntfs_error(vol->sb, "Name using character set %s contains characters " | ||
293 | "that cannot be converted to Unicode.", nls->charset); | ||
294 | kmem_cache_free(ntfs_name_cache, ucs); | 296 | kmem_cache_free(ntfs_name_cache, ucs); |
295 | return -EILSEQ; | 297 | if (wc_len < 0) { |
298 | ntfs_error(vol->sb, "Name using character set %s contains " | ||
299 | "characters that cannot be converted to " | ||
300 | "Unicode.", nls->charset); | ||
301 | i = -EILSEQ; | ||
302 | } else /* if (o >= NTFS_MAX_NAME_LEN) */ { | ||
303 | ntfs_error(vol->sb, "Name is too long (maximum length for a " | ||
304 | "name on NTFS is %d Unicode characters.", | ||
305 | NTFS_MAX_NAME_LEN); | ||
306 | i = -ENAMETOOLONG; | ||
307 | } | ||
308 | return i; | ||
296 | } | 309 | } |
297 | 310 | ||
298 | /** | 311 | /** |