aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/fat/dir.c42
1 files changed, 26 insertions, 16 deletions
diff --git a/fs/fat/dir.c b/fs/fat/dir.c
index a4410740627f..96a1cad30da4 100644
--- a/fs/fat/dir.c
+++ b/fs/fat/dir.c
@@ -325,6 +325,19 @@ parse_long:
325} 325}
326 326
327/* 327/*
328 * Maximum buffer size of short name.
329 * [(MSDOS_NAME + '.') * max one char + nul]
330 * For msdos style, ['.' (hidden) + MSDOS_NAME + '.' + nul]
331 */
332#define FAT_MAX_SHORT_SIZE ((MSDOS_NAME + 1) * NLS_MAX_CHARSET_SIZE + 1)
333/*
334 * Maximum buffer size of unicode chars from slots.
335 * [(max longname slots * 13 (size in a slot) + nul) * sizeof(wchar_t)]
336 */
337#define FAT_MAX_UNI_CHARS ((MSDOS_SLOTS - 1) * 13 + 1)
338#define FAT_MAX_UNI_SIZE (FAT_MAX_UNI_CHARS * sizeof(wchar_t))
339
340/*
328 * Return values: negative -> error, 0 -> not found, positive -> found, 341 * Return values: negative -> error, 0 -> not found, positive -> found,
329 * value is the total amount of slots, including the shortname entry. 342 * value is the total amount of slots, including the shortname entry.
330 */ 343 */
@@ -340,15 +353,11 @@ int fat_search_long(struct inode *inode, const unsigned char *name,
340 wchar_t bufuname[14]; 353 wchar_t bufuname[14];
341 wchar_t *unicode = NULL; 354 wchar_t *unicode = NULL;
342 unsigned char work[MSDOS_NAME]; 355 unsigned char work[MSDOS_NAME];
343 unsigned char *bufname = NULL; 356 unsigned char bufname[FAT_MAX_SHORT_SIZE];
344 unsigned short opt_shortname = sbi->options.shortname; 357 unsigned short opt_shortname = sbi->options.shortname;
345 loff_t cpos = 0; 358 loff_t cpos = 0;
346 int chl, i, j, last_u, err, len; 359 int chl, i, j, last_u, err, len;
347 360
348 bufname = __getname();
349 if (!bufname)
350 return -ENOMEM;
351
352 err = -ENOENT; 361 err = -ENOENT;
353 while (1) { 362 while (1) {
354 if (fat_get_entry(inode, &cpos, &bh, &de) == -1) 363 if (fat_get_entry(inode, &cpos, &bh, &de) == -1)
@@ -414,14 +423,17 @@ parse_record:
414 423
415 /* Compare shortname */ 424 /* Compare shortname */
416 bufuname[last_u] = 0x0000; 425 bufuname[last_u] = 0x0000;
417 len = fat_uni_to_x8(sbi, bufuname, bufname, PATH_MAX); 426 len = fat_uni_to_x8(sbi, bufuname, bufname, sizeof(bufname));
418 if (fat_name_match(sbi, name, name_len, bufname, len)) 427 if (fat_name_match(sbi, name, name_len, bufname, len))
419 goto found; 428 goto found;
420 429
421 if (nr_slots) { 430 if (nr_slots) {
431 void *longname = unicode + FAT_MAX_UNI_CHARS;
432 int size = PATH_MAX - FAT_MAX_UNI_SIZE;
433
422 /* Compare longname */ 434 /* Compare longname */
423 len = fat_uni_to_x8(sbi, unicode, bufname, PATH_MAX); 435 len = fat_uni_to_x8(sbi, unicode, longname, size);
424 if (fat_name_match(sbi, name, name_len, bufname, len)) 436 if (fat_name_match(sbi, name, name_len, longname, len))
425 goto found; 437 goto found;
426 } 438 }
427 } 439 }
@@ -435,8 +447,6 @@ found:
435 sinfo->i_pos = fat_make_i_pos(sb, sinfo->bh, sinfo->de); 447 sinfo->i_pos = fat_make_i_pos(sb, sinfo->bh, sinfo->de);
436 err = 0; 448 err = 0;
437end_of_dir: 449end_of_dir:
438 if (bufname)
439 __putname(bufname);
440 if (unicode) 450 if (unicode)
441 __putname(unicode); 451 __putname(unicode);
442 452
@@ -466,7 +476,8 @@ static int __fat_readdir(struct inode *inode, struct file *filp, void *dirent,
466 unsigned char nr_slots; 476 unsigned char nr_slots;
467 wchar_t bufuname[14]; 477 wchar_t bufuname[14];
468 wchar_t *unicode = NULL; 478 wchar_t *unicode = NULL;
469 unsigned char c, work[MSDOS_NAME], bufname[56], *ptname = bufname; 479 unsigned char c, work[MSDOS_NAME];
480 unsigned char bufname[FAT_MAX_SHORT_SIZE], *ptname = bufname;
470 unsigned short opt_shortname = sbi->options.shortname; 481 unsigned short opt_shortname = sbi->options.shortname;
471 int isvfat = sbi->options.isvfat; 482 int isvfat = sbi->options.isvfat;
472 int nocase = sbi->options.nocase; 483 int nocase = sbi->options.nocase;
@@ -620,11 +631,10 @@ parse_record:
620 fill_name = bufname; 631 fill_name = bufname;
621 fill_len = i; 632 fill_len = i;
622 if (!short_only && nr_slots) { 633 if (!short_only && nr_slots) {
623 /* convert the unicode long name. 261 is maximum size 634 void *longname = unicode + FAT_MAX_UNI_CHARS;
624 * of unicode buffer. (13 * slots + nul) */ 635 int long_len, size = PATH_MAX - FAT_MAX_UNI_SIZE;
625 void *longname = unicode + 261; 636
626 int buf_size = PATH_MAX - (261 * sizeof(unicode[0])); 637 long_len = fat_uni_to_x8(sbi, unicode, longname, size);
627 int long_len = fat_uni_to_x8(sbi, unicode, longname, buf_size);
628 638
629 if (!both) { 639 if (!both) {
630 fill_name = longname; 640 fill_name = longname;