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 80f5237eb5b40d7b3191e3883e65132e1e95796e
Author: Marco Casaroli <[email protected]>
AuthorDate: Tue Oct 20 18:27:09 2026 +0200

    libs/libc/fnmatch: Fix the match of a set.
    
    A set without ranges skipped every second character: "[xyz]" did not
    match "y", and "[a-cxyz]" did not match "y".  The loop read one
    character as a possible start of a range and then stepped over the next
    one.  A '-' before the closing ']' ("[a-]") was taken as a range to ']'.
    
    Read the set one item at a time: a character, or a range when a '-' and
    one more character other than ']' follow.  A set without the closing ']'
    does not match any more.
    
    Assisted-by: Claude Code:claude-opus-5-5
    Signed-off-by: Marco Casaroli <[email protected]>
---
 libs/libc/misc/lib_fnmatch.c | 48 ++++++++++++--------------------------------
 1 file changed, 13 insertions(+), 35 deletions(-)

diff --git a/libs/libc/misc/lib_fnmatch.c b/libs/libc/misc/lib_fnmatch.c
index e736ee7dcf1..9a00d4c94a7 100644
--- a/libs/libc/misc/lib_fnmatch.c
+++ b/libs/libc/misc/lib_fnmatch.c
@@ -72,56 +72,34 @@ static int fnmatch_one(FAR const char *pattern, int patlen,
 
       if (*p == '[' && *string != '\0')
         {
+          /* 'i' tells if a character or a range of the set matches */
+
           i = 0;
+          p++;
           while (*p != ']' && *p != '\0')
             {
-              p++;
-
-              if (*string == *p)
+              first = *p++;
+              if (*p == '-' && p[1] != ']' && p[1] != '\0')
                 {
-                  /* Match found.  Advance to the ']' */
-
-                  i = 1;
-                  while (*p != ']' && *p != '\0')
+                  if (*string >= first && *string <= p[1])
                     {
-                      p++;
+                      i = 1;
                     }
 
-                  break;
+                  p += 2;
                 }
-
-              /* Prepare to test for range */
-
-              if (*p != '\0')
+              else if (*string == first)
                 {
-                  first = *p++;
-                  if (*p == '-')
-                    {
-                      p++;
-                      if (*string >= first && *string <= *p)
-                        {
-                          /* Match found.  Advance to the ']' */
-
-                          i = 1;
-                          while (*p != ']' && *p != '\0')
-                            {
-                              p++;
-                            }
-
-                          break;
-                        }
-                    }
+                  i = 1;
                 }
             }
 
-          /* We reuse 'i' above to indicate match found */
-
-          if (i)
+          if (i == 0 || *p == '\0')
             {
-              continue;
+              return FNM_NOMATCH;
             }
 
-          return FNM_NOMATCH;
+          continue;
         }
 
       if (*p == '*')

Reply via email to