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) == '/') {
