From 58ce1d74c0915f9a5acf6336f5707663d2bbb2da Mon Sep 17 00:00:00 2001 From: Leah Rowe Date: Thu, 26 Mar 2026 01:09:10 +0000 Subject: libreboot-utils: new function, scatn() concatenate an arbitrary number of strings, pointed to by char ** i'll use this and the next function, dcatn, in an upcoming feature planned for mkhtemp. Signed-off-by: Leah Rowe --- util/libreboot-utils/include/common.h | 2 ++ util/libreboot-utils/lib/string.c | 51 +++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) (limited to 'util/libreboot-utils') diff --git a/util/libreboot-utils/include/common.h b/util/libreboot-utils/include/common.h index ebad01bf..dac87fac 100644 --- a/util/libreboot-utils/include/common.h +++ b/util/libreboot-utils/include/common.h @@ -375,6 +375,8 @@ int scmp(const char *a, const char *b, size_t maxlen, int *rval); int sdup(const char *s, size_t n, char **dest); +int scatn(ssize_t sc, const char **sv, + size_t max, char **rval); int scat(const char *s1, const char *s2, size_t n, char **dest); int dcat(const char *s, size_t n, diff --git a/util/libreboot-utils/lib/string.c b/util/libreboot-utils/lib/string.c index 0329c6c3..b639f0a4 100644 --- a/util/libreboot-utils/lib/string.c +++ b/util/libreboot-utils/lib/string.c @@ -117,6 +117,57 @@ sdup(const char *s, return 0; } +/* 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) || + if_err((size = malloc(sizeof(size_t) * sc)) == NULL, ENOMEM)) + 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; + + if (if_err(ts > SIZE_MAX - 1, EOVERFLOW) || + if_err(ts > max - 1, EOVERFLOW) || + if_err((ct = malloc(ts + 1)) == NULL, ENOMEM)) + goto err; + + for (ts = i = 0; i < sc; i++, ts += size[i]) + memcpy(ct + ts, sv[i], size[i]); + + *(ct + ts) = '\0'; + *rval = ct; + + errno = saved_errno; + return 0; +err: + if (ct != NULL) + free(ct); + if (size != NULL) + free(size); + if (errno == saved_errno) + errno = EFAULT; + + return -1; +} + /* strict strcat */ int scat(const char *s1, const char *s2, -- cgit v1.2.1