Do not allocate for repeat inside loop but allocate up front and just

copy in the loop.

(cherry picked from commit 389908d001)
This commit is contained in:
nicm
2026-09-28 16:52:55 +00:00
committed by Nicholas Marriott
parent 02a0bef92b
commit 83d26411c7

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: format.c,v 1.420 2026/09/28 16:23:56 nicm Exp $ */ /* $OpenBSD: format.c,v 1.421 2026/09/28 16:52:55 nicm Exp $ */
/* /*
* Copyright (c) 2011 Nicholas Marriott <nicholas.marriott@gmail.com> * Copyright (c) 2011 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -6019,7 +6019,7 @@ format_replace(struct format_expand_state *es, const char *key, size_t keylen,
char *time_format = NULL; char *time_format = NULL;
char *copy0, *condition, *found, *new; char *copy0, *condition, *found, *new;
char *value, *left, *right; char *value, *left, *right;
size_t valuelen; size_t n;
uint64_t modifiers = 0; uint64_t modifiers = 0;
int limit = 0, width = 0; int limit = 0, width = 0;
int j, c; int j, c;
@@ -6426,17 +6426,15 @@ format_replace(struct format_expand_state *es, const char *key, size_t keylen,
if (errstr != NULL) if (errstr != NULL)
value = xstrdup(""); value = xstrdup("");
else { else {
value = xstrdup(""); n = strlen(left);
for (i = 0; i < nrep; i++) { if (n != 0 && nrep > (SIZE_MAX - 1) / n) {
if (!format_check_time(es, NULL)) { format_log(es, "repeat is too long: %s", copy);
free(right); value = xstrdup("");
free(left); } else {
free(value); value = xmalloc((nrep * n) + 1);
goto fail; for (i = 0; i < nrep; i++)
} memcpy(value + (i * n), left, n);
xasprintf(&new, "%s%s", value, left); value[nrep * n] = '\0';
free(value);
value = new;
} }
} }
free(right); free(right);
@@ -6670,13 +6668,13 @@ done:
} }
/* Expand the buffer and copy in the value. */ /* Expand the buffer and copy in the value. */
valuelen = strlen(value); n = strlen(value);
while (*len - *off < valuelen + 1) { while (*len - *off < n + 1) {
*buf = xreallocarray(*buf, 2, *len); *buf = xreallocarray(*buf, 2, *len);
*len *= 2; *len *= 2;
} }
memcpy(*buf + *off, value, valuelen); memcpy(*buf + *off, value, n);
*off += valuelen; *off += n;
format_log(es, "replaced '%s' with '%s'", copy0, value); format_log(es, "replaced '%s' with '%s'", copy0, value);
free(value); free(value);