summaryrefslogtreecommitdiff
path: root/util/nvmutil/lib/string.c
diff options
context:
space:
mode:
Diffstat (limited to 'util/nvmutil/lib/string.c')
-rw-r--r--util/nvmutil/lib/string.c83
1 files changed, 83 insertions, 0 deletions
diff --git a/util/nvmutil/lib/string.c b/util/nvmutil/lib/string.c
new file mode 100644
index 00000000..4139c354
--- /dev/null
+++ b/util/nvmutil/lib/string.c
@@ -0,0 +1,83 @@
+/* SPDX-License-Identifier: MIT
+ * Copyright (c) 2026 Leah Rowe <leah@libreboot.org>
+ *
+ * String handling.
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <stddef.h>
+#include <unistd.h>
+
+#include "../include/common.h"
+
+/*
+ * Portable strcmp() but blocks NULL/empty/unterminated
+ * strings. Even stricter than strncmp().
+ */
+int
+xstrxcmp(const char *a, const char *b, unsigned long maxlen)
+{
+ unsigned long i;
+
+ if (a == NULL || b == NULL)
+ err(EINVAL, "NULL input to xstrxcmp");
+
+ if (*a == '\0' || *b == '\0')
+ err(EINVAL, "Empty string in xstrxcmp");
+
+ for (i = 0; i < maxlen; i++) {
+
+ unsigned char ac = (unsigned char)a[i];
+ unsigned char bc = (unsigned char)b[i];
+
+ if (ac == '\0' || bc == '\0') {
+ if (ac == bc)
+ return 0;
+ return ac - bc;
+ }
+
+ if (ac != bc)
+ return ac - bc;
+ }
+
+ /*
+ * We reached maxlen, so assume unterminated string.
+ */
+ err(EINVAL, "Unterminated string in xstrxcmp");
+
+ /*
+ * Should never reach here. This keeps compilers happy.
+ */
+ errno = EINVAL;
+ return -1;
+}
+
+/*
+ * strnlen() but aborts on NULL input, and empty strings.
+ * Our version also prohibits unterminated strings.
+ * strnlen() was standardized in POSIX.1-2008 and is not
+ * available on some older systems, so we provide our own.
+ */
+unsigned long
+xstrxlen(const char *scmp, unsigned long maxlen)
+{
+ unsigned long xstr_index;
+
+ if (scmp == NULL)
+ err(EINVAL, "NULL input to xstrxlen");
+
+ if (*scmp == '\0')
+ err(EINVAL, "Empty string in xstrxlen");
+
+ for (xstr_index = 0;
+ xstr_index < maxlen && scmp[xstr_index] != '\0';
+ xstr_index++);
+
+ if (xstr_index == maxlen)
+ err(EINVAL, "Unterminated string in xstrxlen");
+
+ return xstr_index;
+}