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

Florian Weimer via Glibc-cvs <[email protected]>
Newsgroups gmane.comp.lib.glibc.cvs
Message-ID <[email protected]>
https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=6144ef08960e1db191db2054abef02d361042018

commit 6144ef08960e1db191db2054abef02d361042018
Author: Florian Weimer <[email protected]>
Date:   Sat Aug 15 12:36:16 2026 +0200

    stdlib: Remove cache from rpmatch (bug 34526)
    
    It is not thread-safe.  Furthermore, the cache invalidation logic did
    not account for deallocation in uselocale (which could change the regexp
    without changing 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.
    
    Reviewed-by: Collin Funk <[email protected]>

Diff:
---
 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));
 }
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.