[PATCH] stdlib: Remove cache from rpmatch (bug 34526)

Florian Weimer fweimer@redhat.com
Sat Aug 15 12:30:17 GMT 2026


It is not thread-safe.  Furthermore, the cache invalidation logic did
not account for deallocation in uselocale (which could change the regexp
without change its pointer).

Given that this code is unlikely to be performance-senstive
(it is for interactive use) and the regular expressions are very
short, allocate and deallocate the regular expressions on each
call.

---
 stdlib/rpmatch.c | 39 +++++++++++++++------------------------
 1 file changed, 15 insertions(+), 24 deletions(-)

diff --git a/stdlib/rpmatch.c b/stdlib/rpmatch.c
index 8e76b1e84e..3710f2d2ec 100644
--- a/stdlib/rpmatch.c
+++ b/stdlib/rpmatch.c
@@ -25,37 +25,28 @@
 /* Match against one of the response patterns, compiling the pattern
    first if necessary.  */
 static int
-try (const char *response,
-     const int tag, const int match, const int nomatch,
-     const char **lastp, regex_t *re)
+try (const char *response, const int tag, const int match, const int nomatch)
 {
   const char *pattern = nl_langinfo (tag);
-  if (pattern != *lastp)
+  regex_t re;
+  if (__regcomp (&re, pattern, REG_EXTENDED) != 0)
+    return -1;
+  int ret = __regexec (&re, response, 0, NULL, 0);
+  __regfree (&re);
+  switch (ret)
     {
-      /* The pattern has changed.  */
-      if (*lastp != NULL)
-        {
-          /* Free the old compiled pattern.  */
-          __regfree (re);
-          *lastp = NULL;
-        }
-      /* Compile the pattern and cache it for future runs.  */
-      if (__regcomp (re, pattern, REG_EXTENDED) != 0)
-        return -1;
-      *lastp = pattern;
+    case 0:
+      return match;
+    case REG_NOMATCH:
+      return nomatch;
+    default:
+      return -1;
     }
-
-  /* Try the pattern.  */
-  return __regexec (re, response, 0, NULL, 0) == 0 ? match : nomatch;
 }
 
 int
 rpmatch (const char *response)
 {
-  /* We cache the response patterns and compiled regexps here.  */
-  static const char *yesexpr, *noexpr;
-  static regex_t yesre, nore;
-
-  return (try (response, YESEXPR, 1, 0, &yesexpr, &yesre) ?:
-	  try (response, NOEXPR, 0, -1, &noexpr, &nore));
+  return (try (response, YESEXPR, 1, 0)
+	  ?: try (response, NOEXPR, 0, -1));
 }

base-commit: 40ddd85420c11446d5b670a6245e076b11f3173b



More information about the Libc-alpha mailing list