diff options
author | Keith Mok <ek9852@gmail.com> | 2008-04-28 05:16:29 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-28 11:58:47 -0400 |
commit | f22032ba8de2960a64a3dd9719fb5c99b1f1ae6e (patch) | |
tree | c515ff4c94c041325cede8061a9fe3301ec08e53 /fs/vfat/namei.c | |
parent | 061e97469f46f924cf14bbf1dd4805b46986691a (diff) |
vfat: bug fix for vfat cannot handle filename with 255
This patch fix the problem that the buffer allocated for convert of unicode to
utf8 in fat/dir.c is too small.
And cannot handle filename with 255 asian characters when mounted with utf8
options.
Also it fix the filename length limitation checking in vfat/namei.c that the
filename length should be checked against the number of converted unicode
characters.
Not the length before NLS/UTF8 converted.
Signed-off-by: Keith Mok <ek9852@gmail.com>
Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/vfat/namei.c')
-rw-r--r-- | fs/vfat/namei.c | 25 |
1 files changed, 11 insertions, 14 deletions
diff --git a/fs/vfat/namei.c b/fs/vfat/namei.c index efc70576e4b4..ab4f3da770f0 100644 --- a/fs/vfat/namei.c +++ b/fs/vfat/namei.c | |||
@@ -176,15 +176,10 @@ static inline int vfat_is_used_badchars(const wchar_t *s, int len) | |||
176 | for (i = 0; i < len; i++) | 176 | for (i = 0; i < len; i++) |
177 | if (vfat_bad_char(s[i])) | 177 | if (vfat_bad_char(s[i])) |
178 | return -EINVAL; | 178 | return -EINVAL; |
179 | return 0; | ||
180 | } | ||
181 | 179 | ||
182 | static int vfat_valid_longname(const unsigned char *name, unsigned int len) | 180 | if (s[i - 1] == ' ') /* last character cannot be space */ |
183 | { | ||
184 | if (name[len - 1] == ' ') | ||
185 | return -EINVAL; | 181 | return -EINVAL; |
186 | if (len >= 256) | 182 | |
187 | return -ENAMETOOLONG; | ||
188 | return 0; | 183 | return 0; |
189 | } | 184 | } |
190 | 185 | ||
@@ -485,11 +480,14 @@ xlate_to_uni(const unsigned char *name, int len, unsigned char *outname, | |||
485 | */ | 480 | */ |
486 | *outlen -= (name_len - len); | 481 | *outlen -= (name_len - len); |
487 | 482 | ||
483 | if (*outlen > 255) | ||
484 | return -ENAMETOOLONG; | ||
485 | |||
488 | op = &outname[*outlen * sizeof(wchar_t)]; | 486 | op = &outname[*outlen * sizeof(wchar_t)]; |
489 | } else { | 487 | } else { |
490 | if (nls) { | 488 | if (nls) { |
491 | for (i = 0, ip = name, op = outname, *outlen = 0; | 489 | for (i = 0, ip = name, op = outname, *outlen = 0; |
492 | i < len && *outlen <= 260; | 490 | i < len && *outlen <= 255; |
493 | *outlen += 1) | 491 | *outlen += 1) |
494 | { | 492 | { |
495 | if (escape && (*ip == ':')) { | 493 | if (escape && (*ip == ':')) { |
@@ -525,18 +523,20 @@ xlate_to_uni(const unsigned char *name, int len, unsigned char *outname, | |||
525 | op += 2; | 523 | op += 2; |
526 | } | 524 | } |
527 | } | 525 | } |
526 | if (i < len) | ||
527 | return -ENAMETOOLONG; | ||
528 | } else { | 528 | } else { |
529 | for (i = 0, ip = name, op = outname, *outlen = 0; | 529 | for (i = 0, ip = name, op = outname, *outlen = 0; |
530 | i < len && *outlen <= 260; | 530 | i < len && *outlen <= 255; |
531 | i++, *outlen += 1) | 531 | i++, *outlen += 1) |
532 | { | 532 | { |
533 | *op++ = *ip++; | 533 | *op++ = *ip++; |
534 | *op++ = 0; | 534 | *op++ = 0; |
535 | } | 535 | } |
536 | if (i < len) | ||
537 | return -ENAMETOOLONG; | ||
536 | } | 538 | } |
537 | } | 539 | } |
538 | if (*outlen > 260) | ||
539 | return -ENAMETOOLONG; | ||
540 | 540 | ||
541 | *longlen = *outlen; | 541 | *longlen = *outlen; |
542 | if (*outlen % 13) { | 542 | if (*outlen % 13) { |
@@ -574,9 +574,6 @@ static int vfat_build_slots(struct inode *dir, const unsigned char *name, | |||
574 | loff_t offset; | 574 | loff_t offset; |
575 | 575 | ||
576 | *nr_slots = 0; | 576 | *nr_slots = 0; |
577 | err = vfat_valid_longname(name, len); | ||
578 | if (err) | ||
579 | return err; | ||
580 | 577 | ||
581 | page = __get_free_page(GFP_KERNEL); | 578 | page = __get_free_page(GFP_KERNEL); |
582 | if (!page) | 579 | if (!page) |