This is an automated email from the ASF dual-hosted git repository.
michallenc pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new 8f23897d03f fs/fat: Restore the no-short-name marker when the name
will not shorten.
8f23897d03f is described below
commit 8f23897d03f08c00307da4ef19a9588239bc1ca0
Author: Justin Hammond <[email protected]>
AuthorDate: Mon Aug 3 14:28:46 2026 +0800
fs/fat: Restore the no-short-name marker when the name will not shorten.
fat_path2dirname() marks a parsed name as needing long file name
entries by clearing the first byte of the short name buffer, and
fat_dirnamewrite() writes the long name entries only while that marker
survives. Since commit bc9e1ffb01, a name short enough to fit the 8.3
form is speculatively re-parsed as a short name, and the re-parse
fills the short name buffer with spaces before it examines a single
character. When it then rejects the name (lower case, for example) the
spaces stay behind, the marker is gone, and the file is created with
eleven spaces for a name: no long name entries, a blank alias.
Every such file aliases to every other, since every rejected name
converts to the same blank entry. Create a.txt, then create big1, and
both names now open one file; a directory of them lists as a single
nameless entry. Any application that writes two lowercase short-named
files and reads the first back gets the second's contents.
Restore the marker when the speculative parse fails.
Tested on FAT32 with CONFIG_FAT_LFN: lower case, upper case, mixed
case and over-length names now create distinct, correctly named
entries that survive unmount and reboot; upper case 8.3 names still
produce plain short entries with no long name chain.
Assisted-by: Claude:claude-opus-5
Signed-off-by: Justin Hammond <[email protected]>
---
fs/fat/fs_fat32dirent.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/fs/fat/fs_fat32dirent.c b/fs/fat/fs_fat32dirent.c
index abb17575bf3..ac70349a51c 100644
--- a/fs/fat/fs_fat32dirent.c
+++ b/fs/fat/fs_fat32dirent.c
@@ -1165,7 +1165,19 @@ static int fat_path2dirname(FAR const char **path,
char name[DIR_MAXFNAME];
memcpy(name, dirinfo->fd_lfname, DIR_MAXFNAME);
FAR const char *tmp = (FAR const char *)name;
- fat_parsesfname(&tmp, dirinfo, NULL);
+ if (fat_parsesfname(&tmp, dirinfo, NULL) != OK)
+ {
+ /* The name fits the short form's length but cannot be
+ * expressed as one (lower case, for example). The failed
+ * parse has already filled the short name buffer with
+ * spaces, and fat_dirnamewrite() writes long name entries
+ * only while the buffer holds its empty marker. Without
+ * the marker the file gets eleven spaces for a name, and
+ * every such file aliases to every other.
+ */
+
+ dirinfo->fd_name[0] = '\0';
+ }
}
}