]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
boot: Add xstrdup8/16
authorJan Janssen <medhefgo@web.de>
Wed, 25 May 2022 08:59:01 +0000 (10:59 +0200)
committerJan Janssen <medhefgo@web.de>
Tue, 31 May 2022 13:15:01 +0000 (15:15 +0200)
src/boot/efi/cpio.c
src/boot/efi/efi-string.c
src/boot/efi/efi-string.h
src/boot/efi/test-efi-string.c
src/boot/efi/util.c
src/boot/efi/util.h

index 8345f957f7e60df1458d95f7fb323d9cc6ba5d36..18689d9d6b78d33d343d56c4201f5ccfd0d273c6 100644 (file)
@@ -255,7 +255,7 @@ static EFI_STATUS pack_cpio_prefix(
                 if (e > p) {
                         _cleanup_freepool_ CHAR8 *t = NULL;
 
-                        t = xstrndup8(path, e - path);
+                        t = (CHAR8 *) xstrndup8((const char *) path, e - path);
                         if (!t)
                                 return EFI_OUT_OF_RESOURCES;
 
index 1626ccf2049c8025b10dcb564f1d40e7a66b1d00..b93d0ed46a5da1674be441108d17b2844e15c90e 100644 (file)
@@ -5,6 +5,15 @@
 
 #include "efi-string.h"
 
+#ifdef SD_BOOT
+#  include "util.h"
+#  define xmalloc(n) xallocate_pool(n)
+#else
+#  include <stdlib.h>
+#  include "macro.h"
+#  define xmalloc(n) ASSERT_SE_PTR(malloc(n))
+#endif
+
 /* String functions for both char and char16_t that should behave the same way as their respective
  * counterpart in userspace. Where it makes sense, these accept NULL and do something sensible whereas
  * userspace does not allow for this (strlen8(NULL) returns 0 like strlen_ptr(NULL) for example). To make it
@@ -138,6 +147,32 @@ DEFINE_STRCPY(char16_t, strcpy16);
 DEFINE_STRCHR(char, strchr8);
 DEFINE_STRCHR(char16_t, strchr16);
 
+#define DEFINE_STRNDUP(type, name, len_func)              \
+        type *name(const type *s, size_t n) {             \
+                if (!s)                                   \
+                        return NULL;                      \
+                                                          \
+                size_t len = len_func(s, n);              \
+                size_t size = len * sizeof(type);         \
+                                                          \
+                type *dup = xmalloc(size + sizeof(type)); \
+                efi_memcpy(dup, s, size);                 \
+                dup[len] = '\0';                          \
+                                                          \
+                return dup;                               \
+        }
+
+DEFINE_STRNDUP(char, xstrndup8, strnlen8);
+DEFINE_STRNDUP(char16_t, xstrndup16, strnlen16);
+
+char *xstrdup8(const char *s) {
+        return xstrndup8(s, SIZE_MAX);
+}
+
+char16_t *xstrdup16(const char16_t *s) {
+        return xstrndup16(s, SIZE_MAX);
+}
+
 int efi_memcmp(const void *p1, const void *p2, size_t n) {
         if (!p1 || !p2)
                 return CMP(p1, p2);
index 79d810402218c041ec4c1b3a2a0d5d084d7f12be..c203c63c550117fea333c4ba222c69c058b1202c 100644 (file)
@@ -74,6 +74,12 @@ char16_t *strcpy16(char16_t * restrict dest, const char16_t * restrict src);
 char *strchr8(const char *s, char c);
 char16_t *strchr16(const char16_t *s, char16_t c);
 
+char *xstrndup8(const char *s, size_t n);
+char16_t *xstrndup16(const char16_t *s, size_t n);
+
+char *xstrdup8(const char *s);
+char16_t *xstrdup16(const char16_t *s);
+
 #ifdef SD_BOOT
 /* The compiler normaly has knowledge about standard functions such as memcmp, but this is not the case when
  * compiling with -ffreestanding. By referring to builtins, the compiler can check arguments and do
index 087f9d7e9958a0241ef6707449576db05b07203c..d5044d801c719006940f4025e07c89ce89fdcd1f 100644 (file)
@@ -240,6 +240,88 @@ TEST(strchr16) {
         assert_se(strchr16(str, 'B') == &str[4]);
 }
 
+TEST(xstrndup8) {
+        char *s = NULL;
+
+        assert_se(xstrndup8(NULL, 0) == NULL);
+        assert_se(xstrndup8(NULL, 10) == NULL);
+
+        assert_se(s = xstrndup8("", 10));
+        assert_se(streq8(s, ""));
+        free(s);
+
+        assert_se(s = xstrndup8("abc", 0));
+        assert_se(streq8(s, ""));
+        free(s);
+
+        assert_se(s = xstrndup8("ABC", 3));
+        assert_se(streq8(s, "ABC"));
+        free(s);
+
+        assert_se(s = xstrndup8("123abcDEF", 5));
+        assert_se(streq8(s, "123ab"));
+        free(s);
+}
+
+TEST(xstrdup8) {
+        char *s = NULL;
+
+        assert_se(xstrdup8(NULL) == NULL);
+
+        assert_se(s = xstrdup8(""));
+        assert_se(streq8(s, ""));
+        free(s);
+
+        assert_se(s = xstrdup8("1"));
+        assert_se(streq8(s, "1"));
+        free(s);
+
+        assert_se(s = xstrdup8("123abcDEF"));
+        assert_se(streq8(s, "123abcDEF"));
+        free(s);
+}
+
+TEST(xstrndup16) {
+        char16_t *s = NULL;
+
+        assert_se(xstrndup16(NULL, 0) == NULL);
+        assert_se(xstrndup16(NULL, 10) == NULL);
+
+        assert_se(s = xstrndup16(u"", 10));
+        assert_se(streq16(s, u""));
+        free(s);
+
+        assert_se(s = xstrndup16(u"abc", 0));
+        assert_se(streq16(s, u""));
+        free(s);
+
+        assert_se(s = xstrndup16(u"ABC", 3));
+        assert_se(streq16(s, u"ABC"));
+        free(s);
+
+        assert_se(s = xstrndup16(u"123abcDEF", 5));
+        assert_se(streq16(s, u"123ab"));
+        free(s);
+}
+
+TEST(xstrdup16) {
+        char16_t *s = NULL;
+
+        assert_se(xstrdup16(NULL) == NULL);
+
+        assert_se(s = xstrdup16(u""));
+        assert_se(streq16(s, u""));
+        free(s);
+
+        assert_se(s = xstrdup16(u"1"));
+        assert_se(streq16(s, u"1"));
+        free(s);
+
+        assert_se(s = xstrdup16(u"123abcDEF"));
+        assert_se(streq16(s, u"123abcDEF"));
+        free(s);
+}
+
 TEST(efi_memcmp) {
         assert_se(efi_memcmp(NULL, NULL, 0) == 0);
         assert_se(efi_memcmp(NULL, NULL, 1) == 0);
index 83e03fa835d4171929079db218d26314ece78d85..06859d2f3a3a22f987071b7ee80f8eec46fa6f19 100644 (file)
@@ -552,26 +552,6 @@ EFI_STATUS readdir_harder(
         return EFI_SUCCESS;
 }
 
-CHAR8 *xstrndup8(const CHAR8 *p, UINTN sz) {
-        CHAR8 *n;
-
-        /* Following efilib's naming scheme this function would be called strndupa(), but we already have a
-         * function named like this in userspace, and it does something different there, hence to minimize
-         * confusion, let's pick a different name here */
-
-        assert(p || sz == 0);
-
-        sz = strnlen8((const char *) p, sz);
-
-        n = xallocate_pool(sz + 1);
-
-        if (sz > 0)
-                memcpy(n, p, sz);
-        n[sz] = 0;
-
-        return n;
-}
-
 BOOLEAN is_ascii(const CHAR16 *f) {
         if (!f)
                 return FALSE;
index 2a50336f324d328b46591e2f7a9d583d4d9116de..fcfadf3a6eb8560a02fc0fd9303b9be65bd275ba 100644 (file)
@@ -119,8 +119,6 @@ EFI_STATUS get_file_info_harder(EFI_FILE *handle, EFI_FILE_INFO **ret, UINTN *re
 
 EFI_STATUS readdir_harder(EFI_FILE *handle, EFI_FILE_INFO **buffer, UINTN *buffer_size);
 
-CHAR8 *xstrndup8(const CHAR8 *p, UINTN sz);
-
 BOOLEAN is_ascii(const CHAR16 *f);
 
 CHAR16 **strv_free(CHAR16 **l);