boot: Add xstrdup8/16

This commit is contained in:
Jan Janssen
2022-05-31 15:15:01 +02:00
parent bbc1f2eac5
commit 101f68ff33
6 changed files with 124 additions and 23 deletions
+1 -1
View 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;
+35
View 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);
+6
View 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
+82
View 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);
-20
View 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;
-2
View 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);