This is an automated email from the ASF dual-hosted git repository. xiaoxiang781216 pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 1312bc84a258e55bda32fc5999aae1d8778dc9c3 Author: yukangzhi <[email protected]> AuthorDate: Wed Jul 15 10:25:13 2026 +0800 fs: remove redundant ".." handling after VFS canonicalization Since _inode_canonicalize() now resolves all "." and ".." segments in the common VFS layer before inode search, the relpath passed to each filesystem will never contain ".." segments. Remove the now-dead ".." handling code from individual filesystem layers and the inode search internals. Files modified (redundant ".." path resolution removed): - fs/hostfs/hostfs.c: remove depth-tracking escape check in hostfs_mkpath(), simplify to direct path concatenation. - fs/rpmsgfs/rpmsgfs.c: same as hostfs, remove depth-tracking in rpmsgfs_mkpath(). - fs/smartfs/smartfs_utils.c: remove "." and ".." segment checks in smartfs_finddirentry(), de-indent the remaining search logic. - fs/inode/fs_inodesearch.c: remove _inode_isdotdot() function, simplify _compute_path_depth() to only count forward segments, remove dead else-if branch in _inode_search(). Files NOT modified (and why): - fs/littlefs/littlefs/lfs.c: third-party upstream library (git submodule), must not be modified locally. - fs/fatfs/fatfs/source/ff.c: third-party upstream library. - fs/lwext4/lwext4/src/ext4*.c: third-party upstream library. - fs/cromfs/fs_cromfs.c: handles "." and ".." as directory entries (structural, not path resolution), so its code stays. - fs/vfs/fs_symlink.c: constructs relative paths containing ".." (writes, not parses relpath). Signed-off-by: yukangzhi <[email protected]> --- fs/hostfs/hostfs.c | 52 +----- fs/inode/fs_inodesearch.c | 52 +----- fs/rpmsgfs/rpmsgfs.c | 52 +----- fs/smartfs/smartfs_utils.c | 398 +++++++++++++++++++++------------------------ 4 files changed, 198 insertions(+), 356 deletions(-) diff --git a/fs/hostfs/hostfs.c b/fs/hostfs/hostfs.c index d8b2df3193e..c9157da0ebc 100644 --- a/fs/hostfs/hostfs.c +++ b/fs/hostfs/hostfs.c @@ -201,54 +201,14 @@ static void hostfs_mkpath(FAR struct hostfs_mountpt_s *fs, FAR const char *relpath, FAR char *path, int pathlen) { - int depth = 0; - int first; - int x; - - /* Copy base host path to output */ - - strlcpy(path, fs->fs_root, pathlen); - - /* Be sure we aren't trying to use ".." to display outside of our - * mounted path. + /* Copy base host path to output and append relative path directly. + * Note: Both ".." segments and leading slashes are already resolved + * by the VFS layer (_inode_canonicalize + inode_nextname) before + * relpath reaches here. */ - x = 0; - while (relpath[x] == '/') - { - x++; - } - - first = x; - - while (relpath[x] != '\0') - { - /* Test for ".." occurrence */ - - if (strncmp(&relpath[x], "..", 2) == 0) - { - /* Reduce depth by 1 */ - - depth--; - x += 2; - } - - else if (relpath[x] == '/' && relpath[x + 1] != '/' && - relpath[x + 1] != '\0') - { - depth++; - x++; - } - else - { - x++; - } - } - - if (depth >= 0) - { - strlcat(path, &relpath[first], pathlen); - } + strlcpy(path, fs->fs_root, pathlen); + strlcat(path, relpath, pathlen); } /**************************************************************************** diff --git a/fs/inode/fs_inodesearch.c b/fs/inode/fs_inodesearch.c index e769f5bde16..969ded7453b 100644 --- a/fs/inode/fs_inodesearch.c +++ b/fs/inode/fs_inodesearch.c @@ -60,16 +60,6 @@ FAR struct inode *g_root_inode = NULL; * Private Functions ****************************************************************************/ -/**************************************************************************** - * Name: _inode_isdotdot - ****************************************************************************/ - -static inline bool _inode_isdotdot(FAR const char *name) -{ - return name[0] == '.' && name[1] == '.' && - (name[2] == '\0' || name[2] == '/'); -} - /**************************************************************************** * Name: _inode_isdot ****************************************************************************/ @@ -221,20 +211,13 @@ static int _compute_path_depth(FAR const char *path) FAR const char *name = path; int depth = 0; + /* After _inode_canonicalize(), path never contains ".." segments, + * so we only need to count path components. + */ + while (*name != '\0') { - if (_inode_isdotdot(name)) - { - if (--depth < 0) - { - break; - } - } - else - { - depth++; - } - + depth++; name = inode_nextname(name); } @@ -512,31 +495,6 @@ static int _inode_search(FAR struct inode_search_s *desc) ret = OK; break; } - else if (_inode_isdotdot(name)) - { - do - { - if (above != NULL) - { - inode = above; - above = above->i_parent; - } - - name = inode_nextname(name); - } - while (_inode_isdotdot(name)); - - if (*name == '\0') - { - relpath = name; - ret = OK; - break; - } - - above = inode; - left = NULL; - inode = inode->i_child; - } else { /* More nodes to be examined in the path "below" this one. */ diff --git a/fs/rpmsgfs/rpmsgfs.c b/fs/rpmsgfs/rpmsgfs.c index 28c55c6923e..7065f59a9e5 100644 --- a/fs/rpmsgfs/rpmsgfs.c +++ b/fs/rpmsgfs/rpmsgfs.c @@ -232,54 +232,14 @@ static void rpmsgfs_mkpath(FAR struct rpmsgfs_mountpt_s *fs, FAR const char *relpath, FAR char *path, int pathlen) { - int depth = 0; - int first; - int x; - - /* Copy base host path to output */ - - strlcpy(path, fs->fs_root, pathlen); - - /* Be sure we aren't trying to use ".." to display outside of our - * mounted path. + /* Copy base host path to output and append relative path directly. + * Note: Both ".." segments and leading slashes are already resolved + * by the VFS layer (_inode_canonicalize + inode_nextname) before + * relpath reaches here. */ - x = 0; - while (relpath[x] == '/') - { - x++; - } - - first = x; - - while (relpath[x] != '\0') - { - /* Test for ".." occurrence */ - - if (strncmp(&relpath[x], "..", 2) == 0) - { - /* Reduce depth by 1 */ - - depth--; - x += 2; - } - - else if (relpath[x] == '/' && relpath[x + 1] != '/' && - relpath[x + 1] != '\0') - { - depth++; - x++; - } - else - { - x++; - } - } - - if (depth >= 0) - { - strlcat(path, &relpath[first], pathlen - strlen(path)); - } + strlcpy(path, fs->fs_root, pathlen); + strlcat(path, relpath, pathlen); while (fs->timeout > 0) { diff --git a/fs/smartfs/smartfs_utils.c b/fs/smartfs/smartfs_utils.c index 7024f0e0229..5ed4d14dd49 100644 --- a/fs/smartfs/smartfs_utils.c +++ b/fs/smartfs/smartfs_utils.c @@ -518,293 +518,257 @@ int smartfs_finddirentry(FAR struct smartfs_mountpt_s *fs, strlcpy(fs->fs_workbuffer, segment, seglen + 1); - /* Search for "." and ".." as segment names */ + /* Search for the entry in the current directory. + * Note: "." and ".." segments are already resolved by the VFS layer + * (_inode_canonicalize) before relpath reaches here. + */ - if (strcmp(fs->fs_workbuffer, ".") == 0) - { - /* Just ignore this segment. Advance ptr if not on NULL */ + dirsector = dirstack[depth]; - if (*ptr == '/') - { - ptr++; - } + /* Read the directory */ - segment = ptr; - continue; - } - else if (strcmp(fs->fs_workbuffer, "..") == 0) + offset = 0xffff; + +#if CONFIG_SMARTFS_ERASEDSTATE == 0xff + while (dirsector != 0xffff) +#else + while (dirsector != 0) +#endif { - /* Up one level */ + /* Read the next directory in the chain */ - if (depth == 0) + readwrite.logsector = dirsector; + readwrite.count = fs->fs_llformat.availbytes; + readwrite.buffer = (uint8_t *)fs->fs_rwbuffer; + readwrite.offset = 0; + ret = FS_IOCTL(fs, BIOC_READSECT, (unsigned long) &readwrite); + if (ret < 0) { - /* We went up one level past our mount point! */ - goto errout; } - /* "Pop" to the previous directory level */ + /* Point to next sector in chain */ - depth--; - if (*ptr == '/') - { - ptr++; - } + header = (FAR struct smartfs_chain_header_s *) fs->fs_rwbuffer; + dirsector = SMARTFS_NEXTSECTOR(header); - segment = ptr; - continue; - } - else - { - /* Search for the entry in the current directory */ + /* Search for the entry */ - dirsector = dirstack[depth]; - - /* Read the directory */ - - offset = 0xffff; + offset = sizeof(struct smartfs_chain_header_s); + entry = (struct smartfs_entry_header_s *) + &fs->fs_rwbuffer[offset]; + while (offset < readwrite.count) + { + /* Test if this entry is valid and active */ -#if CONFIG_SMARTFS_ERASEDSTATE == 0xff - while (dirsector != 0xffff) +#ifdef CONFIG_SMARTFS_ALIGNED_ACCESS + if (((smartfs_rdle16(&entry->flags) & + SMARTFS_DIRENT_EMPTY) == + (SMARTFS_ERASEDSTATE_16BIT & SMARTFS_DIRENT_EMPTY)) || + ((smartfs_rdle16(&entry->flags) + & SMARTFS_DIRENT_ACTIVE) != + (SMARTFS_ERASEDSTATE_16BIT & SMARTFS_DIRENT_ACTIVE))) #else - while (dirsector != 0) + if (((entry->flags & SMARTFS_DIRENT_EMPTY) == + (SMARTFS_ERASEDSTATE_16BIT & SMARTFS_DIRENT_EMPTY)) || + ((entry->flags & SMARTFS_DIRENT_ACTIVE) != + (SMARTFS_ERASEDSTATE_16BIT & SMARTFS_DIRENT_ACTIVE))) #endif - { - /* Read the next directory in the chain */ - - readwrite.logsector = dirsector; - readwrite.count = fs->fs_llformat.availbytes; - readwrite.buffer = (uint8_t *)fs->fs_rwbuffer; - readwrite.offset = 0; - ret = FS_IOCTL(fs, BIOC_READSECT, (unsigned long) &readwrite); - if (ret < 0) { - goto errout; - } + /* This entry isn't valid, skip it */ - /* Point to next sector in chain */ + offset += entrysize; + entry = (struct smartfs_entry_header_s *) + &fs->fs_rwbuffer[offset]; - header = (FAR struct smartfs_chain_header_s *) fs->fs_rwbuffer; - dirsector = SMARTFS_NEXTSECTOR(header); + continue; + } - /* Search for the entry */ + /* Test if the name matches */ - offset = sizeof(struct smartfs_chain_header_s); - entry = (struct smartfs_entry_header_s *) - &fs->fs_rwbuffer[offset]; - while (offset < readwrite.count) + if (strncmp(entry->name, fs->fs_workbuffer, + fs->fs_llformat.namesize) == 0) { - /* Test if this entry is valid and active */ + /* We found it! If this is the last segment entry, + * then report the entry. If it isn't the last + * entry, then validate it is a directory entry and + * open it and continue searching. + */ -#ifdef CONFIG_SMARTFS_ALIGNED_ACCESS - if (((smartfs_rdle16(&entry->flags) & - SMARTFS_DIRENT_EMPTY) == - (SMARTFS_ERASEDSTATE_16BIT & SMARTFS_DIRENT_EMPTY)) || - ((smartfs_rdle16(&entry->flags) - & SMARTFS_DIRENT_ACTIVE) != - (SMARTFS_ERASEDSTATE_16BIT & SMARTFS_DIRENT_ACTIVE))) -#else - if (((entry->flags & SMARTFS_DIRENT_EMPTY) == - (SMARTFS_ERASEDSTATE_16BIT & SMARTFS_DIRENT_EMPTY)) || - ((entry->flags & SMARTFS_DIRENT_ACTIVE) != - (SMARTFS_ERASEDSTATE_16BIT & SMARTFS_DIRENT_ACTIVE))) -#endif + if (*ptr == '\0') { - /* This entry isn't valid, skip it */ - - offset += entrysize; - entry = (struct smartfs_entry_header_s *) - &fs->fs_rwbuffer[offset]; - - continue; - } + /* We are at the last segment. Report the entry */ - /* Test if the name matches */ - - if (strncmp(entry->name, fs->fs_workbuffer, - fs->fs_llformat.namesize) == 0) - { - /* We found it! If this is the last segment entry, - * then report the entry. If it isn't the last - * entry, then validate it is a directory entry and - * open it and continue searching. - */ - - if (*ptr == '\0') - { - /* We are at the last segment. Report the entry */ - - /* Fill in the entry */ + /* Fill in the entry */ #ifdef CONFIG_SMARTFS_ALIGNED_ACCESS - direntry->firstsector = - smartfs_rdle16(&entry->firstsector); - direntry->flags = smartfs_rdle16(&entry->flags); - direntry->utc = smartfs_rdle32(&entry->utc); + direntry->firstsector = + smartfs_rdle16(&entry->firstsector); + direntry->flags = smartfs_rdle16(&entry->flags); + direntry->utc = smartfs_rdle32(&entry->utc); #else - direntry->firstsector = entry->firstsector; - direntry->flags = entry->flags; - direntry->utc = entry->utc; + direntry->firstsector = entry->firstsector; + direntry->flags = entry->flags; + direntry->utc = entry->utc; #endif - direntry->dsector = readwrite.logsector; - direntry->doffset = offset; - direntry->dfirst = dirstack[depth]; - if (direntry->name == NULL) - { - direntry->name = (FAR char *) - fs_heap_malloc(fs->fs_llformat.namesize + 1); - } + direntry->dsector = readwrite.logsector; + direntry->doffset = offset; + direntry->dfirst = dirstack[depth]; + if (direntry->name == NULL) + { + direntry->name = (FAR char *) + fs_heap_malloc(fs->fs_llformat.namesize + 1); + } - strlcpy(direntry->name, entry->name, - fs->fs_llformat.namesize + 1); - direntry->datlen = 0; + strlcpy(direntry->name, entry->name, + fs->fs_llformat.namesize + 1); + direntry->datlen = 0; - /* Scan the file's sectors to calculate the length - * and perform a rudimentary check. - */ + /* Scan the file's sectors to calculate the length + * and perform a rudimentary check. + */ #ifdef CONFIG_SMARTFS_ALIGNED_ACCESS - if ((smartfs_rdle16(&entry->flags) & - SMARTFS_DIRENT_TYPE) == - SMARTFS_DIRENT_TYPE_FILE) + if ((smartfs_rdle16(&entry->flags) & + SMARTFS_DIRENT_TYPE) == + SMARTFS_DIRENT_TYPE_FILE) #else - if ((entry->flags & SMARTFS_DIRENT_TYPE) == - SMARTFS_DIRENT_TYPE_FILE) + if ((entry->flags & SMARTFS_DIRENT_TYPE) == + SMARTFS_DIRENT_TYPE_FILE) #endif - { + { #ifdef CONFIG_SMARTFS_ALIGNED_ACCESS - dirsector = - smartfs_rdle16(&entry->firstsector); + dirsector = + smartfs_rdle16(&entry->firstsector); #else - dirsector = entry->firstsector; + dirsector = entry->firstsector; #endif - readwrite.count = - sizeof(struct smartfs_chain_header_s); - readwrite.buffer = (uint8_t *)fs->fs_rwbuffer; - readwrite.offset = 0; + readwrite.count = + sizeof(struct smartfs_chain_header_s); + readwrite.buffer = (uint8_t *)fs->fs_rwbuffer; + readwrite.offset = 0; - while (dirsector != SMARTFS_ERASEDSTATE_16BIT) + while (dirsector != SMARTFS_ERASEDSTATE_16BIT) + { + /* Read the next sector of the file */ + + readwrite.logsector = dirsector; + ret = FS_IOCTL(fs, BIOC_READSECT, + (unsigned long) &readwrite); + if (ret < 0) { - /* Read the next sector of the file */ - - readwrite.logsector = dirsector; - ret = FS_IOCTL(fs, BIOC_READSECT, - (unsigned long) &readwrite); - if (ret < 0) - { - ferr("ERROR: Error in sector" - " chain at %d!\n", dirsector); - break; - } - - /* Add used bytes to the total and point - * to next sector - */ - - if (SMARTFS_USED(header) != - SMARTFS_ERASEDSTATE_16BIT) - { - direntry->datlen += - SMARTFS_USED(header); - } - - dirsector = SMARTFS_NEXTSECTOR(header); + ferr("ERROR: Error in sector" + " chain at %d!\n", dirsector); + break; } - } - *parentdirsector = dirstack[depth]; - *filename = segment; - ret = OK; - goto errout; + /* Add used bytes to the total and point + * to next sector + */ + + if (SMARTFS_USED(header) != + SMARTFS_ERASEDSTATE_16BIT) + { + direntry->datlen += + SMARTFS_USED(header); + } + + dirsector = SMARTFS_NEXTSECTOR(header); + } } - else - { - /* Validate it's a directory */ + + *parentdirsector = dirstack[depth]; + *filename = segment; + ret = OK; + goto errout; + } + else + { + /* Validate it's a directory */ #ifdef CONFIG_SMARTFS_ALIGNED_ACCESS - if ((smartfs_rdle16(&entry->flags) & - SMARTFS_DIRENT_TYPE) != - SMARTFS_DIRENT_TYPE_DIR) + if ((smartfs_rdle16(&entry->flags) & + SMARTFS_DIRENT_TYPE) != + SMARTFS_DIRENT_TYPE_DIR) #else - if ((entry->flags & SMARTFS_DIRENT_TYPE) != - SMARTFS_DIRENT_TYPE_DIR) + if ((entry->flags & SMARTFS_DIRENT_TYPE) != + SMARTFS_DIRENT_TYPE_DIR) #endif - { - /* Not a directory! Report the error */ + { + /* Not a directory! Report the error */ - ret = -ENOTDIR; - goto errout; - } + ret = -ENOTDIR; + goto errout; + } - /* "Push" the directory and continue searching */ + /* "Push" the directory and continue searching */ - if (depth >= CONFIG_SMARTFS_DIRDEPTH - 1) - { - /* Directory depth too big */ + if (depth >= CONFIG_SMARTFS_DIRDEPTH - 1) + { + /* Directory depth too big */ - ret = -ENAMETOOLONG; - goto errout; - } + ret = -ENAMETOOLONG; + goto errout; + } #ifdef CONFIG_SMARTFS_ALIGNED_ACCESS - dirstack[++depth] = - smartfs_rdle16(&entry->firstsector); + dirstack[++depth] = + smartfs_rdle16(&entry->firstsector); #else - dirstack[++depth] = entry->firstsector; + dirstack[++depth] = entry->firstsector; #endif - segment = ptr + 1; - break; - } + segment = ptr + 1; + break; } - - /* Not this entry. Skip to the next one */ - - offset += entrysize; - entry = (struct smartfs_entry_header_s *) - &fs->fs_rwbuffer[offset]; } - /* Test if a directory entry was found and break if it was */ + /* Not this entry. Skip to the next one */ - if (offset < readwrite.count) - { - break; - } + offset += entrysize; + entry = (struct smartfs_entry_header_s *) + &fs->fs_rwbuffer[offset]; } - /* If we found a dir entry, then continue searching */ + /* Test if a directory entry was found and break if it was */ if (offset < readwrite.count) { - /* Update the segment pointer */ - - if (*ptr != '\0') - { - ptr++; - } - - segment = ptr; - continue; + break; } + } - /* Entry not found! Report the error. Also, if this is the last - * segment, then report the parent directory sector. - */ + /* If we found a dir entry, then continue searching */ - if (*ptr == '\0') - { - *parentdirsector = dirstack[depth]; - *filename = segment; - } - else + if (offset < readwrite.count) + { + /* Update the segment pointer */ + + if (*ptr != '\0') { - *parentdirsector = 0xffff; - *filename = NULL; + ptr++; } - ret = -ENOENT; - goto errout; + segment = ptr; + continue; } + + /* Entry not found! Report the error. Also, if this is the last + * segment, then report the parent directory sector. + */ + + if (*ptr == '\0') + { + *parentdirsector = dirstack[depth]; + *filename = segment; + } + else + { + *parentdirsector = 0xffff; + *filename = NULL; + } + + ret = -ENOENT; + goto errout; } errout:
