With the latest Gnulib (2cf60fe51e 2026-10-09), regexec does not find
case-insensitive matches of bracket expressions in single-byte locales
when the input character has a different case than the one in the
bracket.

Test program icase.c:

#include <config.h>
#include <locale.h>
#include <regex.h>
#include <stdio.h>
int
main (void)
{
  const char *pats[] = { "[A]", "[Ab]", "A" };
  setlocale (LC_ALL, "");
  for (int p = 0; p < 3; p++)
    {
      regex_t re;
      regcomp (&re, pats[p], REG_ICASE);
      printf ("%s->", pats[p]);
      for (const char *c = "aAbB"; *c; c++)
        {
          char s[2] = { *c, 0 };
          if (regexec (&re, s, 0, NULL, 0) == 0)
            putchar (*c);
        }
      printf (" ");
      regfree (&re);
    }
  printf ("\n");
  return 0;
}

Output:

$ LC_ALL=C ./icase
[A]->A [Ab]->AB A->aA
$ LC_ALL=en_US.ISO-8859-15 ./icase
[A]->A [Ab]->AB A->aA
$ LC_ALL=C.UTF-8 ./icase
[A]->aA [Ab]->aAbB A->aA

Expected in all locales: [A]->aA [Ab]->aAbB A->aA.

I attach a suggestion for a fix.

Cheers,
Arno
--- a/lib/regcomp.c
+++ b/lib/regcomp.c
@@ -345,7 +345,11 @@
 	      bitset_word_t w = dfa->nodes[node].opr.sbcset[i];
 	      for (j = 0; j < BITSET_WORD_BITS; ++j, ++ch)
 		if (w & ((bitset_word_t) 1 << j))
-		  re_set_fastmap (fastmap, ch);
+		  {
+		    re_set_fastmap (fastmap, ch);
+		    if (bufp->syntax & RE_ICASE)
+		      re_set_fastmap (fastmap, tolower (ch));
+		  }
 	    }
 	}
       else if (type == COMPLEX_BRACKET)

Reply via email to