diff options
| author | Leah Rowe <leah@libreboot.org> | 2026-03-29 22:15:27 +0100 |
|---|---|---|
| committer | Leah Rowe <leah@libreboot.org> | 2026-03-29 23:55:38 +0100 |
| commit | 7fb0b2f69293f0fb0e83e9b125fbd658503147f0 (patch) | |
| tree | f7c119ee9dc7ffbb6ad62bc360ddc52212413167 /util/libreboot-utils/lib/string.c | |
| parent | 01aa95ec15ed5a6e519f1d3887e105a40e17b84c (diff) | |
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.c | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/util/libreboot-utils/lib/string.c b/util/libreboot-utils/lib/string.c index 39b31cb0..49c23663 100644 --- a/util/libreboot-utils/lib/string.c +++ b/util/libreboot-utils/lib/string.c @@ -292,6 +292,39 @@ err: return -1; } +/* because no libc reimagination is complete + * without a reimplementation of memcmp. and + * no safe one is complete without null checks. + */ +int +vcmp(const void *s1, const void *s2, size_t n) +{ + size_t i = 0; + size_t a; + size_t b; + + if (if_err(s1 == NULL || s2 == NULL, EFAULT)) + err_exit(EFAULT, "vcmp: null input"); + + const unsigned char *x = s1; + const unsigned char *y = s2; + + for ( ; i + sizeof(size_t) <= n; i += sizeof(size_t)) { + + memcpy(&a, x + i, sizeof(size_t)); + memcpy(&b, y + i, sizeof(size_t)); + + if (a != b) + break; + } + + for ( ; i < n; i++) + if (x[i] != y[i]) + return (int)x[i] - (int)y[i]; + + return 0; +} + /* on functions that return with errno, * i sometimes have a default fallback, * which is set if errno wasn't changed, |
