summaryrefslogtreecommitdiff
path: root/util/libreboot-utils/lib/string.c
diff options
context:
space:
mode:
authorLeah Rowe <leah@libreboot.org>2026-03-29 10:32:12 +0100
committerLeah Rowe <leah@libreboot.org>2026-03-29 10:35:33 +0100
commitcec3de5c9eacb92e45fcd4ff88998d9b35e38663 (patch)
treee912416b5778f594fc575079d746b6e9defd7df1 /util/libreboot-utils/lib/string.c
parent1539aff30236b0302c92df2c1d2b635d58f08812 (diff)
mkhtemp: generalised string concatenation
scatn in strings.c was buggy, so i replaced it; it concatenates any number of things. Signed-off-by: Leah Rowe <leah@libreboot.org>
Diffstat (limited to 'util/libreboot-utils/lib/string.c')
-rw-r--r--util/libreboot-utils/lib/string.c56
1 files changed, 26 insertions, 30 deletions
diff --git a/util/libreboot-utils/lib/string.c b/util/libreboot-utils/lib/string.c
index c7f90f5d..9adbb120 100644
--- a/util/libreboot-utils/lib/string.c
+++ b/util/libreboot-utils/lib/string.c
@@ -174,49 +174,45 @@ sdup(const char *s,
}
/* concatenate N number of strings */
-/* slen already checks null/termination */
int
scatn(ssize_t sc, const char **sv,
size_t max, char **rval)
{
- ssize_t i = 0;
-
- size_t ts = 0;
- size_t *size = NULL;
-
- char *ct = NULL;
int saved_errno = errno;
- if (if_err(sc <= 0, EINVAL) ||
- if_err(sc > SIZE_MAX / sizeof(size_t), EOVERFLOW) ||
- if_err(sv == NULL, EINVAL))
- goto err;
+ char *final = NULL;
+ char *rcur = NULL;
+ char *rtmp = NULL;
+ size_t i;
- vmalloc((void **)&size, sizeof(size_t) * sc);
+ if (if_err(sc < 2, EINVAL) ||
+ if_err(sv == NULL, EFAULT) ||
+ if_err(rval == NULL || *rval != NULL, EFAULT))
+ goto err;
- for (i = 0; i < sc; i++, ts += size[i])
- if (if_err(sv[i] == NULL, EINVAL) ||
- slen(sv[i], max, &size[i]) < 0 ||
- if_err(size[i] > max - 1, EOVERFLOW) ||
- if_err((size[i] + ts) < ts, EOVERFLOW))
- goto err;
+ for (i = 0; i < sc; i++) {
- if (if_err(ts > SIZE_MAX - 1, EOVERFLOW) ||
- if_err(ts > max - 1, EOVERFLOW))
- goto err;
+ if (i == 0) {
+ if (sdup(sv[0], max, &final) < 0)
+ goto err;
+ continue;
+ }
- smalloc(&ct, ts + 1);
- for (ts = i = 0; i < sc; i++, ts += size[i])
- memcpy(ct + ts, sv[i], size[i]);
+ rtmp = NULL;
+ if (scat(final, sv[i], max, &rtmp) < 0)
+ goto err;
- *(ct + ts) = '\0';
- *rval = ct;
+ free_and_set_null(&final);
+ final = rtmp;
+ rtmp = NULL;
+ }
- errno = saved_errno;
+ *rval = final;
return 0;
err:
- free_and_set_null(&ct);
- free_and_set_null((char **)&size);
+ free_and_set_null(&rcur);
+ free_and_set_null(&rtmp);
+ free_and_set_null(&final);
return set_errno(saved_errno, EFAULT);
}
@@ -230,7 +226,7 @@ scat(const char *s1, const char *s2,
size_t size2;
char *rval = NULL;
- if (dest == NULL ||
+ if (if_err(dest == NULL || *dest != NULL, EFAULT) ||
slen(s1, n, &size1) < 0 ||
slen(s2, n, &size2) < 0 ||
if_err(size1 > SIZE_MAX - size2 - 1, EOVERFLOW)) {