This is an automated email from the ASF dual-hosted git repository.

GUIDINGLI pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit be16f230e3392849bd50685b8873ac4e098751f1
Author: zhaoxingyu1 <[email protected]>
AuthorDate: Fri Nov 7 13:01:39 2025 +0800

    fs/inode: support path ending with '..' and '.' in inode_search
    
    example: stat(".", buf) and stat("..", buf)
    
    Signed-off-by: zhaoxingyu1 <[email protected]>
---
 fs/inode/fs_inodesearch.c | 50 ++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 39 insertions(+), 11 deletions(-)

diff --git a/fs/inode/fs_inodesearch.c b/fs/inode/fs_inodesearch.c
index 640dee936fc..ce7ae41f517 100644
--- a/fs/inode/fs_inodesearch.c
+++ b/fs/inode/fs_inodesearch.c
@@ -59,6 +59,25 @@ 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
+ ****************************************************************************/
+
+static inline bool _inode_isdot(FAR const char *name)
+{
+  return name[0] == '.' && (name[1] == '\0' || name[1] == '/');
+}
+
 /****************************************************************************
  * Name: _inode_compare
  *
@@ -203,7 +222,7 @@ static int _compute_path_depth(FAR const char *path)
 
   while (*name != '\0')
     {
-      if (strncmp(name, "../", 3) == 0)
+      if (_inode_isdotdot(name))
         {
           if (--depth < 0)
             {
@@ -322,21 +341,30 @@ static int _inode_search(FAR struct inode_search_s *desc)
               ret = OK;
               break;
             }
-          else if (strncmp(name, "../", 3) == 0)
+          else if (_inode_isdotdot(name))
             {
-              above = inode;
-              left  = NULL;
-              inode = inode->i_child;
-
-              while (strncmp(name, "../", 3) == 0)
+              do
                 {
-                  name = inode_nextname(name);
-                  if (above != g_root_inode)
+                  if (above != NULL)
                     {
+                      inode = above;
                       above = above->i_parent;
-                      inode = above->i_child;
                     }
+
+                  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
             {
@@ -632,7 +660,7 @@ FAR const char *inode_nextname(FAR const char *name)
    * ".", rather than resolving to the node the search already reached.
    */
 
-  if (*name == '.' && (*(name + 1) == '/' || *(name + 1) == '\0'))
+  if (_inode_isdot(name))
     {
       if (*(name + 1) == '/')
         {

Reply via email to