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 24d371c0fe89e6f8f9628662c9427b1ef5112c1a
Author: guohao15 <[email protected]>
AuthorDate: Mon Sep 15 16:28:51 2025 +0800

    fs/inode: return ENAMETOOLONG for path/filename longer than NAME_MAX
    
    Add a helper _inode_checkpath() that validates the path before the
    search: it returns -ENOENT for an empty path and -ENAMETOOLONG when any
    single path component exceeds NAME_MAX or the whole path exceeds
    PATH_MAX.  inode_search() now runs this check first so that oversized
    paths and file names are rejected with the correct POSIX error code.
    
    Signed-off-by: guohao15 <[email protected]>
---
 fs/inode/fs_inodesearch.c | 80 +++++++++++++++++++++++++++++++----------------
 1 file changed, 53 insertions(+), 27 deletions(-)

diff --git a/fs/inode/fs_inodesearch.c b/fs/inode/fs_inodesearch.c
index ce7ae41f517..2f01a63c485 100644
--- a/fs/inode/fs_inodesearch.c
+++ b/fs/inode/fs_inodesearch.c
@@ -240,6 +240,40 @@ static int _compute_path_depth(FAR const char *path)
   return depth;
 }
 
+/****************************************************************************
+ * Name: _inode_checkpath
+ ****************************************************************************/
+
+static int _inode_checkpath(const char *path)
+{
+  int namelen = 0;
+  int pathlen = 0;
+
+  if (*path == '\0')
+    {
+      return -ENOENT;
+    }
+
+  /* Check each segment of the path */
+
+  while (*path != '\0' && namelen < NAME_MAX && pathlen < PATH_MAX)
+    {
+      if (*path == '/')
+        {
+          namelen = 0;
+        }
+      else
+        {
+          namelen++;
+        }
+
+      path++;
+      pathlen++;
+    }
+
+  return *path != '\0' ? -ENAMETOOLONG : OK;
+}
+
 /****************************************************************************
  * Name: _inode_search
  *
@@ -268,20 +302,31 @@ static int _inode_search(FAR struct inode_search_s *desc)
   FAR struct inode *left    = NULL;
   FAR struct inode *above   = NULL;
   FAR const char   *relpath = NULL;
-  int ret = -ENOENT;
+  int ret;
 
-  /* Get the search path, skipping over the leading '/'.  The leading '/' is
-   * mandatory because only absolute paths are expected in this context.
-   */
+  ret = _inode_checkpath(desc->path);
+  if (ret < 0)
+    {
+      return ret;
+    }
 
-  DEBUGASSERT(desc != NULL && desc->path != NULL);
-  name  = desc->path;
+  /* Convert the relative path to the absolute path */
 
-  if (*name != '/')
+  if (*desc->path != '/')
     {
-      return -EINVAL;
+      desc->buffer = lib_get_tempbuffer(PATH_MAX);
+      if (desc->buffer == NULL)
+        {
+          return -ENOMEM;
+        }
+
+      snprintf(desc->buffer, PATH_MAX, "%s/%s", _inode_getcwd(), desc->path);
+      desc->path = desc->buffer;
     }
 
+  name = desc->path;
+  ret = -ENOENT;
+
   /* Traverse the pseudo file system node tree until either (1) all nodes
    * have been examined without finding the matching node, or (2) the
    * matching node is found.
@@ -557,25 +602,6 @@ int inode_search(FAR struct inode_search_s *desc)
 
   DEBUGASSERT(desc != NULL && desc->path != NULL);
 
-  if (*desc->path == '\0')
-    {
-      return -ENOENT;
-    }
-
-  /* Convert the relative path to the absolute path */
-
-  if (*desc->path != '/')
-    {
-      desc->buffer = lib_get_tempbuffer(PATH_MAX);
-      if (desc->buffer == NULL)
-        {
-          return -ENOMEM;
-        }
-
-      snprintf(desc->buffer, PATH_MAX, "%s/%s", _inode_getcwd(), desc->path);
-      desc->path = desc->buffer;
-    }
-
   ret = _inode_search(desc);
 
 #ifdef CONFIG_FS_LINKS

Reply via email to