From: Paul Eggert Date: Sat, 23 Sep 2023 08:15:08 +0000 (-0700) Subject: factor,tail: avoid quadratic reallocation X-Git-Tag: v9.5~142 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=769ace51e8a1129c44ee4e7e209c3b2df2111524;p=thirdparty%2Fcoreutils.git factor,tail: avoid quadratic reallocation * src/factor.c (struct mp_factors): New member nalloc. (mp_factor_init): Initialize it. * src/factor.c (mp_factor_insert): * src/tail.c (parse_options): Use xpalloc to avoid quadratic worst-case behavior on reallocation. * src/tail.c (pids_alloc): New static var. --- diff --git a/src/factor.c b/src/factor.c index c47250a488..8848ac2ac6 100644 --- a/src/factor.c +++ b/src/factor.c @@ -247,6 +247,7 @@ struct mp_factors mpz_t *p; unsigned long int *e; idx_t nfactors; + idx_t nalloc; }; static void factor (uintmax_t, uintmax_t, struct factors *); @@ -595,6 +596,7 @@ mp_factor_init (struct mp_factors *factors) factors->p = nullptr; factors->e = nullptr; factors->nfactors = 0; + factors->nalloc = 0; } static void @@ -624,11 +626,14 @@ mp_factor_insert (struct mp_factors *factors, mpz_t prime) if (i < 0 || mpz_cmp (p[i], prime) != 0) { - p = xireallocarray (p, nfactors + 1, sizeof p[0]); - e = xireallocarray (e, nfactors + 1, sizeof e[0]); + if (factors->nfactors == factors->nalloc) + { + p = xpalloc (p, &factors->nalloc, 1, -1, sizeof *p); + e = xireallocarray (e, factors->nalloc, sizeof *e); + } mpz_init (p[nfactors]); - for (long j = nfactors - 1; j > i; j--) + for (ptrdiff_t j = nfactors - 1; j > i; j--) { mpz_set (p[j + 1], p[j]); e[j + 1] = e[j]; diff --git a/src/tail.c b/src/tail.c index 4c3c7b5905..c45f3b65af 100644 --- a/src/tail.c +++ b/src/tail.c @@ -206,6 +206,7 @@ static uintmax_t max_n_unchanged_stats_between_opens = files, or perhaps other processes the user cares about). */ static int nbpids = 0; static pid_t * pids = nullptr; +static idx_t pids_alloc; /* True if we have ever read standard input. */ static bool have_read_stdin; @@ -2208,13 +2209,11 @@ parse_options (int argc, char **argv, break; case PID_OPTION: - { - pid_t pid = - xdectoumax (optarg, 0, PID_T_MAX, "", _("invalid PID"), 0); - pids = xreallocarray (pids, nbpids + 1, sizeof (pid_t)); - pids[nbpids] = pid; - nbpids++; - } + if (nbpids == pids_alloc) + pids = xpalloc (pids, &pids_alloc, 1, + MIN (INT_MAX, PTRDIFF_MAX), sizeof *pids); + pids[nbpids++] = xdectoumax (optarg, 0, PID_T_MAX, "", + _("invalid PID"), 0); break; case PRESUME_INPUT_PIPE_OPTION: