From ef9f478a48f98897d16ae506ef847af35e37dd94 Mon Sep 17 00:00:00 2001 From: cheloha Date: Tue, 2 Nov 2021 03:09:15 +0000 Subject: [PATCH] tr(1): plug leak in genclass() If we have already generated a given character class we don't need to do it again. We can also return some of the memory we allocated for the class. NCHARS is an upper bound, most character classes are small. This fixes a small leak in genclass(). While here, switch to an ANSI function definition. Thread: https://marc.info/?l=openbsd-tech&m=163571942030440&w=2 ok millert@ --- usr.bin/tr/str.c | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/usr.bin/tr/str.c b/usr.bin/tr/str.c index 26e706d29ba..b8249c0516d 100644 --- a/usr.bin/tr/str.c +++ b/usr.bin/tr/str.c @@ -1,4 +1,4 @@ -/* $OpenBSD: str.c,v 1.13 2021/10/31 21:34:16 cheloha Exp $ */ +/* $OpenBSD: str.c,v 1.14 2021/11/02 03:09:15 cheloha Exp $ */ /* $NetBSD: str.c,v 1.7 1995/08/31 22:13:47 jtc Exp $ */ /*- @@ -164,24 +164,38 @@ static CLASS classes[] = { }; static void -genclass(s) - STR *s; +genclass(STR *s) { - int cnt, (*func)(int); CLASS *cp, tmp; - int *p; + size_t len; + int i; tmp.name = (char *)s->str; if ((cp = (CLASS *)bsearch(&tmp, classes, sizeof(classes) / sizeof(CLASS), sizeof(CLASS), c_class)) == NULL) errx(1, "unknown class %s", s->str); - if ((cp->set = p = calloc(NCHARS + 1, sizeof(int))) == NULL) - errx(1, "no memory for a class"); - for (cnt = 0, func = cp->func; cnt < NCHARS; ++cnt) - if ((func)(cnt)) - *p++ = cnt; - *p = OOBCH; + /* + * Generate the set of characters in the class if we haven't + * already done so. + */ + if (cp->set == NULL) { + cp->set = reallocarray(NULL, NCHARS + 1, sizeof(*cp->set)); + if (cp->set == NULL) + err(1, NULL); + len = 0; + for (i = 0; i < NCHARS; i++) { + if (cp->func(i)) { + cp->set[len] = i; + len++; + } + } + cp->set[len] = OOBCH; + len++; + cp->set = reallocarray(cp->set, len, sizeof(*cp->set)); + if (cp->set == NULL) + err(1, NULL); + } s->cnt = 0; s->state = SET; -- 2.20.1