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:

Reply via email to