From dab523c1cddc1b8af0eb45653639ecd8bdddee41 Mon Sep 17 00:00:00 2001 From: Liu Aleaxander Date: Thu, 10 Dec 2009 21:35:07 +0800 Subject: [PATCH] LDLINUX:vfat: Oh, NO, I did fix the above bug in a wrong way! I shouldn't count on the 'dname' parameter, we should ZERO the 'long_name' buffer at every time we met a new long name entry, and that's the right way to fix the bug. And we shouldn't count the 'id == 0' to check if we have a long name matched first or not. Say we have one entry of a long name entry, it will always be 'id == 0' even it doesn't matches. So, add a new flag variable to do this. Signed-off-by: Liu Aleaxander --- core/fs/fat/fat.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/core/fs/fat/fat.c b/core/fs/fat/fat.c index 9cb9f99..7ed714b 100644 --- a/core/fs/fat/fat.c +++ b/core/fs/fat/fat.c @@ -411,6 +411,7 @@ static struct inode *vfat_find_entry(char *dname, struct inode *dir) int slots; int entries; int checksum; + int long_match = 0; slots = (strlen(dname) + 12) / 13 ; slots |= 0x40; @@ -438,6 +439,9 @@ static struct inode *vfat_find_entry(char *dname, struct inode *dir) /* get the initial checksum value */ vfat_csum = long_de->checksum; id &= 0x3f; + + /* ZERO the long_name buffer */ + memset(long_name, 0, sizeof long_name); } else { if (long_de->checksum != vfat_csum) goto not_match; @@ -448,8 +452,7 @@ static struct inode *vfat_find_entry(char *dname, struct inode *dir) /* got the long entry name */ long_entry_name(long_de); memcpy(long_name + id * 13, entry_name, 13); - long_name[strlen(dname)] = '\0'; - + /* * If we got the last entry, check it. * Or, go on with the next entry. @@ -457,6 +460,7 @@ static struct inode *vfat_find_entry(char *dname, struct inode *dir) if (id == 0) { if (strcmp(long_name, dname)) goto not_match; + long_match = 1; } de++; @@ -468,12 +472,14 @@ static struct inode *vfat_find_entry(char *dname, struct inode *dir) if (de->attr & 0x08) /* ignore volume labels */ goto not_match; - /* If we have a long name match, then vfat_next must be 0 */ - if (vfat_next == 0) { + if (long_match == 1) { /* * We already have a VFAT long name match. However, the * match is only valid if the checksum matches. + * + * Well, let's trun the long_match flag off first. */ + long_match = 0; checksum = get_checksum(de->name); if (checksum == vfat_csum) goto found; /* Got it */ -- 2.7.4