2021-04-03 Paul Eggert <eggert@cs.ucla.edu>
+ quotearg: avoid undefined and/or O(N**2)
+ Avoid undefined and O(N**2) behavior in some very unlikely cases.
+ * lib/quotearg.c (quotearg_n_options): Document that N must
+ be less than MIN (INT_MAX, IDX_MAX), and add this to the
+ abort test; this also avoids a conditional branch.
+ Use xpalloc instead of xrealloc, to avoid O(N**2) behavior in
+ very-unlikely cases.
+
xgethostname: reorganize / simplify
xgethostname and xgetdomainname were essentially copies long
ago, but they’ve diverged. Bring them back together again
OPTIONS specifies the quoting options.
The returned value points to static storage that can be
reused by the next call to this function with the same value of N.
- N must be nonnegative. N is deliberately declared with type "int"
+ N must be nonnegative; it is typically small, and must be
+ less than MIN (INT_MAX, IDX_MAX). The type of N is signed
to allow for future extensions (using negative values). */
static char *
quotearg_n_options (int n, char const *arg, size_t argsize,
struct slotvec *sv = slotvec;
- if (n < 0)
+ int nslots_max = MIN (INT_MAX, IDX_MAX);
+ if (! (0 <= n && n < nslots_max))
abort ();
if (nslots <= n)
{
bool preallocated = (sv == &slotvec0);
- int nmax = MIN (INT_MAX, MIN (PTRDIFF_MAX, SIZE_MAX) / sizeof *sv) - 1;
+ idx_t new_nslots = nslots;
- if (nmax < n)
- xalloc_die ();
-
- slotvec = sv = xrealloc (preallocated ? NULL : sv, (n + 1) * sizeof *sv);
+ slotvec = sv = xpalloc (preallocated ? NULL : sv, &new_nslots,
+ n - nslots + 1, nslots_max, sizeof *sv);
if (preallocated)
*sv = slotvec0;
- memset (sv + nslots, 0, (n + 1 - nslots) * sizeof *sv);
- nslots = n + 1;
+ memset (sv + nslots, 0, (new_nslots - nslots) * sizeof *sv);
+ nslots = new_nslots;
}
{