[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)); }