diff options
author | Scott Soule Cheloha <cheloha@cvs.openbsd.org> | 2021-11-02 03:09:16 +0000 |
---|---|---|
committer | Scott Soule Cheloha <cheloha@cvs.openbsd.org> | 2021-11-02 03:09:16 +0000 |
commit | 33a3cd13731b498f4f2e410cc6726c4281a123f0 (patch) | |
tree | a5ee03cae6a676766423fafca63f80f68d16e83d | |
parent | 082d3af23d9eb21f8e228d0de5b6e651d3bbf164 (diff) |
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@
-rw-r--r-- | usr.bin/tr/str.c | 36 |
1 files 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; |