Merge pull request #23512 from medhefgo/efi-clang
boot: Add string functions
This commit is contained in:
+4
-8
@@ -7,9 +7,7 @@
|
||||
# define TEST_STATIC
|
||||
#else
|
||||
/* Provide our own "EFI API" if we are running as a unit test. */
|
||||
# include <stddef.h>
|
||||
# include <stdint.h>
|
||||
# include <uchar.h>
|
||||
# include "efi-string.h"
|
||||
# include "string-util-fundamental.h"
|
||||
|
||||
# define CHAR8 char
|
||||
@@ -19,8 +17,6 @@
|
||||
# define UINT32 uint32_t
|
||||
# define UINT64 uint64_t
|
||||
# define UINTN size_t
|
||||
# define strlena(s) strlen(s)
|
||||
# define strncaseeqa(a, b, n) strncaseeq((a), (b), (n))
|
||||
# define TEST_STATIC static
|
||||
#endif
|
||||
|
||||
@@ -139,7 +135,7 @@ static const Key *get_subkey(const UINT8 *bcd, UINT32 bcd_len, UINT32 offset, co
|
||||
return NULL;
|
||||
|
||||
for (UINT16 i = 0; i < subkey->n_entries; i++) {
|
||||
if (!strncaseeqa(name, subkey->entries[i].name_hint, sizeof(subkey->entries[i].name_hint)))
|
||||
if (!strncaseeq8((char *) name, (char *) subkey->entries[i].name_hint, sizeof(subkey->entries[i].name_hint)))
|
||||
continue;
|
||||
|
||||
const Key *key = get_key(bcd, bcd_len, subkey->entries[i].key_offset, name);
|
||||
@@ -168,7 +164,7 @@ static const Key *get_key(const UINT8 *bcd, UINT32 bcd_len, UINT32 offset, const
|
||||
return NULL;
|
||||
|
||||
if (*name) {
|
||||
if (strncaseeqa(name, key->key_name, key->key_name_len) && strlena(name) == key->key_name_len)
|
||||
if (strncaseeq8((char *) name, (char *) key->key_name, key->key_name_len) && strlen8((const char *) name) == key->key_name_len)
|
||||
name += key->key_name_len;
|
||||
else
|
||||
return NULL;
|
||||
@@ -213,7 +209,7 @@ static const KeyValue *get_key_value(const UINT8 *bcd, UINT32 bcd_len, const Key
|
||||
if (BAD_OFFSET(kv->data_offset, kv->data_size, bcd_len))
|
||||
continue;
|
||||
|
||||
if (strncaseeqa(name, kv->name, kv->name_len) && strlena(name) == kv->name_len)
|
||||
if (strncaseeq8((char *)name, (char *) kv->name, kv->name_len) && strlen8((const char *) name) == kv->name_len)
|
||||
return kv;
|
||||
}
|
||||
|
||||
|
||||
+96
-96
@@ -149,11 +149,11 @@ static BOOLEAN line_edit(
|
||||
|
||||
assert(line_in);
|
||||
|
||||
len = strlen_ptr(*line_in);
|
||||
len = strlen16(*line_in);
|
||||
size = len + 1024;
|
||||
line = xnew(CHAR16, size);
|
||||
print = xnew(CHAR16, x_max + 1);
|
||||
StrCpy(line, strempty(*line_in));
|
||||
strcpy16(line, strempty(*line_in));
|
||||
|
||||
for (;;) {
|
||||
EFI_STATUS err;
|
||||
@@ -162,7 +162,7 @@ static BOOLEAN line_edit(
|
||||
UINTN cursor_color = TEXT_ATTR_SWAP(COLOR_EDIT);
|
||||
|
||||
j = MIN(len - first, x_max);
|
||||
CopyMem(print, line + first, j * sizeof(CHAR16));
|
||||
memcpy(print, line + first, j * sizeof(CHAR16));
|
||||
while (clear > 0 && j < x_max) {
|
||||
clear--;
|
||||
print[j++] = ' ';
|
||||
@@ -317,7 +317,7 @@ static BOOLEAN line_edit(
|
||||
case KEYPRESS(0, 0, CHAR_CARRIAGE_RETURN):
|
||||
case KEYPRESS(0, CHAR_CARRIAGE_RETURN, 0): /* EZpad Mini 4s firmware sends malformed events */
|
||||
case KEYPRESS(0, CHAR_CARRIAGE_RETURN, CHAR_CARRIAGE_RETURN): /* Teclast X98+ II firmware sends malformed events */
|
||||
if (!streq(line, *line_in)) {
|
||||
if (!streq16(line, *line_in)) {
|
||||
FreePool(*line_in);
|
||||
*line_in = TAKE_PTR(line);
|
||||
}
|
||||
@@ -418,11 +418,11 @@ static CHAR16 *update_timeout_efivar(UINT32 *t, BOOLEAN inc) {
|
||||
|
||||
switch (*t) {
|
||||
case TIMEOUT_UNSET:
|
||||
return xstrdup(L"Menu timeout defined by configuration file.");
|
||||
return xstrdup16(u"Menu timeout defined by configuration file.");
|
||||
case TIMEOUT_MENU_FORCE:
|
||||
return xstrdup(L"Timeout disabled, menu will always be shown.");
|
||||
return xstrdup16(u"Timeout disabled, menu will always be shown.");
|
||||
case TIMEOUT_MENU_HIDDEN:
|
||||
return xstrdup(L"Menu disabled. Hold down key at bootup to show menu.");
|
||||
return xstrdup16(u"Menu disabled. Hold down key at bootup to show menu.");
|
||||
default:
|
||||
return xpool_print(L"Menu timeout set to %u s.", *t);
|
||||
}
|
||||
@@ -554,7 +554,7 @@ static void print_status(Config *config, CHAR16 *loaded_image_path) {
|
||||
Print(L" config entry: %" PRIuN L"/%" PRIuN L"\n", i + 1, config->entry_count);
|
||||
ps_string(L" id: %s\n", entry->id);
|
||||
ps_string(L" title: %s\n", entry->title);
|
||||
ps_string(L" title show: %s\n", streq_ptr(entry->title, entry->title_show) ? NULL : entry->title_show);
|
||||
ps_string(L" title show: %s\n", streq16(entry->title, entry->title_show) ? NULL : entry->title_show);
|
||||
ps_string(L" sort key: %s\n", entry->sort_key);
|
||||
ps_string(L" version: %s\n", entry->version);
|
||||
ps_string(L" machine-id: %s\n", entry->machine_id);
|
||||
@@ -662,7 +662,7 @@ static BOOLEAN menu_run(
|
||||
/* length of the longest entry */
|
||||
line_width = 0;
|
||||
for (UINTN i = 0; i < config->entry_count; i++)
|
||||
line_width = MAX(line_width, StrLen(config->entries[i]->title_show));
|
||||
line_width = MAX(line_width, strlen16(config->entries[i]->title_show));
|
||||
line_width = MIN(line_width + 2 * entry_padding, x_max);
|
||||
|
||||
/* offsets to center the entries on the screen */
|
||||
@@ -686,7 +686,7 @@ static BOOLEAN menu_run(
|
||||
UINTN j, padding;
|
||||
|
||||
lines[i] = xnew(CHAR16, line_width + 1);
|
||||
padding = (line_width - MIN(StrLen(config->entries[i]->title_show), line_width)) / 2;
|
||||
padding = (line_width - MIN(strlen16(config->entries[i]->title_show), line_width)) / 2;
|
||||
|
||||
for (j = 0; j < padding; j++)
|
||||
lines[i][j] = ' ';
|
||||
@@ -750,7 +750,7 @@ static BOOLEAN menu_run(
|
||||
* input. Therefore, draw one less character then we could for the status message.
|
||||
* Note that the same does not apply for the separator line as it will never be drawn
|
||||
* on the last line. */
|
||||
UINTN len = StrnLen(status, x_max - 1);
|
||||
UINTN len = strnlen16(status, x_max - 1);
|
||||
UINTN x = (x_max - len) / 2;
|
||||
status[len] = '\0';
|
||||
print_at(0, y_status, COLOR_NORMAL, clearline + x_max - x);
|
||||
@@ -861,7 +861,7 @@ static BOOLEAN menu_run(
|
||||
case KEYPRESS(0, 0, 'H'):
|
||||
case KEYPRESS(0, 0, '?'):
|
||||
/* This must stay below 80 characters! Q/v/Ctrl+l/f deliberately not advertised. */
|
||||
status = xstrdup(L"(d)efault (t/T)timeout (e)dit (r/R)resolution (p)rint (h)elp");
|
||||
status = xstrdup16(u"(d)efault (t/T)timeout (e)dit (r/R)resolution (p)rint (h)elp");
|
||||
break;
|
||||
|
||||
case KEYPRESS(0, 0, 'Q'):
|
||||
@@ -873,13 +873,13 @@ static BOOLEAN menu_run(
|
||||
case KEYPRESS(0, 0, 'D'):
|
||||
if (config->idx_default_efivar != idx_highlight) {
|
||||
FreePool(config->entry_default_efivar);
|
||||
config->entry_default_efivar = xstrdup(config->entries[idx_highlight]->id);
|
||||
config->entry_default_efivar = xstrdup16(config->entries[idx_highlight]->id);
|
||||
config->idx_default_efivar = idx_highlight;
|
||||
status = xstrdup(L"Default boot entry selected.");
|
||||
status = xstrdup16(u"Default boot entry selected.");
|
||||
} else {
|
||||
config->entry_default_efivar = mfree(config->entry_default_efivar);
|
||||
config->idx_default_efivar = IDX_INVALID;
|
||||
status = xstrdup(L"Default boot entry cleared.");
|
||||
status = xstrdup16(u"Default boot entry cleared.");
|
||||
}
|
||||
config->use_saved_entry_efivar = FALSE;
|
||||
refresh = TRUE;
|
||||
@@ -1092,7 +1092,7 @@ static CHAR8 *line_get_key_value(
|
||||
return NULL;
|
||||
|
||||
linelen = 0;
|
||||
while (line[linelen] && !strchra((CHAR8 *) "\n\r", line[linelen]))
|
||||
while (line[linelen] && !strchr8("\n\r", line[linelen]))
|
||||
linelen++;
|
||||
|
||||
/* move pos to next line */
|
||||
@@ -1108,13 +1108,13 @@ static CHAR8 *line_get_key_value(
|
||||
line[linelen] = '\0';
|
||||
|
||||
/* remove leading whitespace */
|
||||
while (strchra((CHAR8 *) " \t", *line)) {
|
||||
while (strchr8(" \t", *line)) {
|
||||
line++;
|
||||
linelen--;
|
||||
}
|
||||
|
||||
/* remove trailing whitespace */
|
||||
while (linelen > 0 && strchra((CHAR8 *) " \t", line[linelen - 1]))
|
||||
while (linelen > 0 && strchr8(" \t", line[linelen - 1]))
|
||||
linelen--;
|
||||
line[linelen] = '\0';
|
||||
|
||||
@@ -1123,13 +1123,13 @@ static CHAR8 *line_get_key_value(
|
||||
|
||||
/* split key/value */
|
||||
value = line;
|
||||
while (*value && !strchra(sep, *value))
|
||||
while (*value && !strchr8((char *) sep, *value))
|
||||
value++;
|
||||
if (*value == '\0')
|
||||
continue;
|
||||
*value = '\0';
|
||||
value++;
|
||||
while (*value && strchra(sep, *value))
|
||||
while (*value && strchr8((char *) sep, *value))
|
||||
value++;
|
||||
|
||||
/* unquote */
|
||||
@@ -1154,10 +1154,10 @@ static void config_defaults_load_from_file(Config *config, CHAR8 *content) {
|
||||
assert(content);
|
||||
|
||||
while ((line = line_get_key_value(content, (CHAR8 *)" \t", &pos, &key, &value))) {
|
||||
if (strcmpa((CHAR8 *)"timeout", key) == 0) {
|
||||
if (strcmpa((CHAR8*) "menu-force", value) == 0)
|
||||
if (streq8((char *) key, "timeout")) {
|
||||
if (streq8((char *) value, "menu-force"))
|
||||
config->timeout_sec_config = TIMEOUT_MENU_FORCE;
|
||||
else if (strcmpa((CHAR8*) "menu-hidden", value) == 0)
|
||||
else if (streq8((char *) value, "menu-hidden"))
|
||||
config->timeout_sec_config = TIMEOUT_MENU_HIDDEN;
|
||||
else {
|
||||
_cleanup_freepool_ CHAR16 *s = NULL;
|
||||
@@ -1169,8 +1169,8 @@ static void config_defaults_load_from_file(Config *config, CHAR8 *content) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmpa((CHAR8 *)"default", key) == 0) {
|
||||
if (value[0] == '@' && strcmpa((CHAR8 *)"@saved", value) != 0) {
|
||||
if (streq8((char *) key, "default")) {
|
||||
if (value[0] == '@' && !streq8((char *) value, "@saved")) {
|
||||
log_error_stall(L"Unsupported special entry identifier: %a", value);
|
||||
continue;
|
||||
}
|
||||
@@ -1179,47 +1179,47 @@ static void config_defaults_load_from_file(Config *config, CHAR8 *content) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmpa((CHAR8 *)"editor", key) == 0) {
|
||||
if (streq8((char *) key, "editor")) {
|
||||
err = parse_boolean(value, &config->editor);
|
||||
if (EFI_ERROR(err))
|
||||
log_error_stall(L"Error parsing 'editor' config option: %a", value);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmpa((CHAR8 *)"auto-entries", key) == 0) {
|
||||
if (streq8((char *) key, "auto-entries")) {
|
||||
err = parse_boolean(value, &config->auto_entries);
|
||||
if (EFI_ERROR(err))
|
||||
log_error_stall(L"Error parsing 'auto-entries' config option: %a", value);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmpa((CHAR8 *)"auto-firmware", key) == 0) {
|
||||
if (streq8((char *) key, "auto-firmware")) {
|
||||
err = parse_boolean(value, &config->auto_firmware);
|
||||
if (EFI_ERROR(err))
|
||||
log_error_stall(L"Error parsing 'auto-firmware' config option: %a", value);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmpa((CHAR8 *)"beep", key) == 0) {
|
||||
if (streq8((char *) key, "beep")) {
|
||||
err = parse_boolean(value, &config->beep);
|
||||
if (EFI_ERROR(err))
|
||||
log_error_stall(L"Error parsing 'beep' config option: %a", value);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmpa((CHAR8 *)"reboot-for-bitlocker", key) == 0) {
|
||||
if (streq8((char *) key, "reboot-for-bitlocker")) {
|
||||
err = parse_boolean(value, &config->reboot_for_bitlocker);
|
||||
if (EFI_ERROR(err))
|
||||
log_error_stall(L"Error parsing 'reboot-for-bitlocker' config option: %a", value);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmpa((CHAR8 *)"console-mode", key) == 0) {
|
||||
if (strcmpa((CHAR8 *)"auto", value) == 0)
|
||||
if (streq8((char *) key, "console-mode")) {
|
||||
if (streq8((char *) value, "auto"))
|
||||
config->console_mode = CONSOLE_MODE_AUTO;
|
||||
else if (strcmpa((CHAR8 *)"max", value) == 0)
|
||||
else if (streq8((char *) value, "max"))
|
||||
config->console_mode = CONSOLE_MODE_FIRMWARE_MAX;
|
||||
else if (strcmpa((CHAR8 *)"keep", value) == 0)
|
||||
else if (streq8((char *) value, "keep"))
|
||||
config->console_mode = CONSOLE_MODE_KEEP;
|
||||
else {
|
||||
_cleanup_freepool_ CHAR16 *s = NULL;
|
||||
@@ -1230,12 +1230,12 @@ static void config_defaults_load_from_file(Config *config, CHAR8 *content) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmpa((CHAR8*) "random-seed-mode", key) == 0) {
|
||||
if (strcmpa((CHAR8*) "off", value) == 0)
|
||||
if (streq8((char *) key, "random-seed-mode")) {
|
||||
if (streq8((char *) value, "off"))
|
||||
config->random_seed_mode = RANDOM_SEED_OFF;
|
||||
else if (strcmpa((CHAR8*) "with-system-token", value) == 0)
|
||||
else if (streq8((char *) value, "with-system-token"))
|
||||
config->random_seed_mode = RANDOM_SEED_WITH_SYSTEM_TOKEN;
|
||||
else if (strcmpa((CHAR8*) "always", value) == 0)
|
||||
else if (streq8((char *) value, "always"))
|
||||
config->random_seed_mode = RANDOM_SEED_ALWAYS;
|
||||
else {
|
||||
BOOLEAN on;
|
||||
@@ -1277,13 +1277,13 @@ static void config_entry_parse_tries(
|
||||
* foobar+4-0.efi → foobar+3-1.efi → foobar+2-2.efi → foobar+1-3.efi → foobar+0-4.efi → STOP!
|
||||
*/
|
||||
|
||||
i = StrLen(file);
|
||||
i = strlen16(file);
|
||||
|
||||
/* Chop off any suffix such as ".conf" or ".efi" */
|
||||
if (suffix) {
|
||||
UINTN suffix_length;
|
||||
|
||||
suffix_length = StrLen(suffix);
|
||||
suffix_length = strlen16(suffix);
|
||||
if (i < suffix_length)
|
||||
return;
|
||||
|
||||
@@ -1360,13 +1360,13 @@ good:
|
||||
entry->tries_left = left;
|
||||
entry->tries_done = done;
|
||||
|
||||
entry->path = xstrdup(path);
|
||||
entry->current_name = xstrdup(file);
|
||||
entry->path = xstrdup16(path);
|
||||
entry->current_name = xstrdup16(file);
|
||||
|
||||
next_left = left <= 0 ? 0 : left - 1;
|
||||
next_done = done >= (UINTN) -2 ? (UINTN) -2 : done + 1;
|
||||
|
||||
prefix = xstrdup(file);
|
||||
prefix = xstrdup16(file);
|
||||
prefix[i] = 0;
|
||||
|
||||
entry->next_name = xpool_print(L"%s+%" PRIuN L"-%" PRIuN L"%s", prefix, next_left, next_done, strempty(suffix));
|
||||
@@ -1399,7 +1399,7 @@ static void config_entry_bump_counters(ConfigEntry *entry, EFI_FILE *root_dir) {
|
||||
return;
|
||||
|
||||
/* And rename the file */
|
||||
StrCpy(file_info->FileName, entry->next_name);
|
||||
strcpy16(file_info->FileName, entry->next_name);
|
||||
err = handle->SetInfo(handle, &GenericFileInfo, file_info_size, file_info);
|
||||
if (EFI_ERROR(err)) {
|
||||
log_error_stall(L"Failed to rename '%s' to '%s', ignoring: %r", old_path, entry->next_name, err);
|
||||
@@ -1415,7 +1415,7 @@ static void config_entry_bump_counters(ConfigEntry *entry, EFI_FILE *root_dir) {
|
||||
efivar_set(LOADER_GUID, L"LoaderBootCountPath", new_path, 0);
|
||||
|
||||
/* If the file we just renamed is the loader path, then let's update that. */
|
||||
if (StrCmp(entry->loader, old_path) == 0) {
|
||||
if (streq16(entry->loader, old_path)) {
|
||||
FreePool(entry->loader);
|
||||
entry->loader = TAKE_PTR(new_path);
|
||||
}
|
||||
@@ -1450,31 +1450,31 @@ static void config_entry_add_type1(
|
||||
};
|
||||
|
||||
while ((line = line_get_key_value(content, (CHAR8 *)" \t", &pos, &key, &value))) {
|
||||
if (strcmpa((CHAR8 *)"title", key) == 0) {
|
||||
if (streq8((char *) key, "title")) {
|
||||
FreePool(entry->title);
|
||||
entry->title = xstra_to_str(value);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmpa((CHAR8 *)"sort-key", key) == 0) {
|
||||
if (streq8((char *) key, "sort-key")) {
|
||||
FreePool(entry->sort_key);
|
||||
entry->sort_key = xstra_to_str(value);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmpa((CHAR8 *)"version", key) == 0) {
|
||||
if (streq8((char *) key, "version")) {
|
||||
FreePool(entry->version);
|
||||
entry->version = xstra_to_str(value);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmpa((CHAR8 *)"machine-id", key) == 0) {
|
||||
if (streq8((char *) key, "machine-id")) {
|
||||
FreePool(entry->machine_id);
|
||||
entry->machine_id = xstra_to_str(value);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmpa((CHAR8 *)"linux", key) == 0) {
|
||||
if (streq8((char *) key, "linux")) {
|
||||
FreePool(entry->loader);
|
||||
entry->type = LOADER_LINUX;
|
||||
entry->loader = xstra_to_path(value);
|
||||
@@ -1482,35 +1482,35 @@ static void config_entry_add_type1(
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmpa((CHAR8 *)"efi", key) == 0) {
|
||||
if (streq8((char *) key, "efi")) {
|
||||
entry->type = LOADER_EFI;
|
||||
FreePool(entry->loader);
|
||||
entry->loader = xstra_to_path(value);
|
||||
|
||||
/* do not add an entry for ourselves */
|
||||
if (loaded_image_path && StriCmp(entry->loader, loaded_image_path) == 0) {
|
||||
if (loaded_image_path && strcaseeq16(entry->loader, loaded_image_path)) {
|
||||
entry->type = LOADER_UNDEFINED;
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmpa((CHAR8 *)"architecture", key) == 0) {
|
||||
if (streq8((char *) key, "architecture")) {
|
||||
/* do not add an entry for an EFI image of architecture not matching with that of the image */
|
||||
if (strcmpa((CHAR8 *)EFI_MACHINE_TYPE_NAME, value) != 0) {
|
||||
if (!streq8((char *) value, EFI_MACHINE_TYPE_NAME)) {
|
||||
entry->type = LOADER_UNDEFINED;
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmpa((CHAR8 *)"devicetree", key) == 0) {
|
||||
if (streq8((char *) key, "devicetree")) {
|
||||
FreePool(entry->devicetree);
|
||||
entry->devicetree = xstra_to_path(value);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmpa((CHAR8 *)"initrd", key) == 0) {
|
||||
if (streq8((char *) key, "initrd")) {
|
||||
entry->initrd = xreallocate_pool(
|
||||
entry->initrd,
|
||||
n_initrd == 0 ? 0 : (n_initrd + 1) * sizeof(UINT16 *),
|
||||
@@ -1520,7 +1520,7 @@ static void config_entry_add_type1(
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmpa((CHAR8 *)"options", key) == 0) {
|
||||
if (streq8((char *) key, "options")) {
|
||||
_cleanup_freepool_ CHAR16 *new = NULL;
|
||||
|
||||
new = xstra_to_str(value);
|
||||
@@ -1547,8 +1547,8 @@ static void config_entry_add_type1(
|
||||
return;
|
||||
|
||||
entry->device = device;
|
||||
entry->id = xstrdup(file);
|
||||
StrLwr(entry->id);
|
||||
entry->id = xstrdup16(file);
|
||||
strtolower16(entry->id);
|
||||
|
||||
config_add_entry(config, entry);
|
||||
|
||||
@@ -1606,8 +1606,8 @@ static void config_load_defaults(Config *config, EFI_FILE *root_dir) {
|
||||
|
||||
(void) efivar_get(LOADER_GUID, L"LoaderEntryDefault", &config->entry_default_efivar);
|
||||
|
||||
config->use_saved_entry = streq_ptr(config->entry_default_config, L"@saved");
|
||||
config->use_saved_entry_efivar = streq_ptr(config->entry_default_efivar, L"@saved");
|
||||
config->use_saved_entry = streq16(config->entry_default_config, L"@saved");
|
||||
config->use_saved_entry_efivar = streq16(config->entry_default_efivar, L"@saved");
|
||||
if (config->use_saved_entry || config->use_saved_entry_efivar)
|
||||
(void) efivar_get(LOADER_GUID, L"LoaderEntryLastBooted", &config->entry_saved);
|
||||
}
|
||||
@@ -1656,8 +1656,8 @@ static void config_load_entries(
|
||||
}
|
||||
}
|
||||
|
||||
static INTN config_entry_compare(const ConfigEntry *a, const ConfigEntry *b) {
|
||||
INTN r;
|
||||
static int config_entry_compare(const ConfigEntry *a, const ConfigEntry *b) {
|
||||
int r;
|
||||
|
||||
assert(a);
|
||||
assert(b);
|
||||
@@ -1676,12 +1676,12 @@ static INTN config_entry_compare(const ConfigEntry *a, const ConfigEntry *b) {
|
||||
return r;
|
||||
|
||||
if (a->sort_key && b->sort_key) {
|
||||
r = strcmp(a->sort_key, b->sort_key);
|
||||
r = strcmp16(a->sort_key, b->sort_key);
|
||||
if (r != 0)
|
||||
return r;
|
||||
|
||||
/* If multiple installations of the same OS are around, group by machine ID */
|
||||
r = strcmp_ptr(a->machine_id, b->machine_id);
|
||||
r = strcmp16(a->machine_id, b->machine_id);
|
||||
if (r != 0)
|
||||
return r;
|
||||
|
||||
@@ -1773,7 +1773,7 @@ static BOOLEAN entries_unique(ConfigEntry **entries, BOOLEAN *unique, UINTN entr
|
||||
|
||||
for (UINTN i = 0; i < entry_count; i++)
|
||||
for (UINTN k = i + 1; k < entry_count; k++) {
|
||||
if (StrCmp(entries[i]->title_show, entries[k]->title_show) != 0)
|
||||
if (!streq16(entries[i]->title_show, entries[k]->title_show))
|
||||
continue;
|
||||
|
||||
is_unique = unique[i] = unique[k] = FALSE;
|
||||
@@ -1792,7 +1792,7 @@ static void config_title_generate(Config *config) {
|
||||
for (UINTN i = 0; i < config->entry_count; i++) {
|
||||
assert(!config->entries[i]->title_show);
|
||||
unique[i] = TRUE;
|
||||
config->entries[i]->title_show = xstrdup(config->entries[i]->title ?: config->entries[i]->id);
|
||||
config->entries[i]->title_show = xstrdup16(config->entries[i]->title ?: config->entries[i]->id);
|
||||
}
|
||||
|
||||
if (entries_unique(config->entries, unique, config->entry_count))
|
||||
@@ -1829,7 +1829,7 @@ static void config_title_generate(Config *config) {
|
||||
config->entries[i]->title_show = xpool_print(
|
||||
L"%s (%.*s)",
|
||||
t,
|
||||
StrnLen(config->entries[i]->machine_id, 8),
|
||||
strnlen16(config->entries[i]->machine_id, 8),
|
||||
config->entries[i]->machine_id);
|
||||
}
|
||||
|
||||
@@ -1866,7 +1866,7 @@ static BOOLEAN is_sd_boot(EFI_FILE *root_dir, const CHAR16 *loader_path) {
|
||||
if (EFI_ERROR(err) || size != read)
|
||||
return FALSE;
|
||||
|
||||
return CompareMem(content, magic, sizeof(magic)) == 0;
|
||||
return memcmp(content, magic, sizeof(magic)) == 0;
|
||||
}
|
||||
|
||||
static ConfigEntry *config_entry_add_loader_auto(
|
||||
@@ -1897,7 +1897,7 @@ static ConfigEntry *config_entry_add_loader_auto(
|
||||
*
|
||||
* If the default loader is not us, it might be shim. It would
|
||||
* chainload GRUBX64.EFI in that case, which might be us.*/
|
||||
if (StriCmp(loader, loaded_image_path) == 0 ||
|
||||
if (strcaseeq16(loader, loaded_image_path) ||
|
||||
is_sd_boot(root_dir, loader) ||
|
||||
is_sd_boot(root_dir, L"\\EFI\\BOOT\\GRUB" EFI_MACHINE_TYPE_NAME L".EFI"))
|
||||
return NULL;
|
||||
@@ -1911,11 +1911,11 @@ static ConfigEntry *config_entry_add_loader_auto(
|
||||
|
||||
ConfigEntry *entry = xnew(ConfigEntry, 1);
|
||||
*entry = (ConfigEntry) {
|
||||
.id = xstrdup(id),
|
||||
.id = xstrdup16(id),
|
||||
.type = LOADER_AUTO,
|
||||
.title = xstrdup(title),
|
||||
.title = xstrdup16(title),
|
||||
.device = device,
|
||||
.loader = xstrdup(loader),
|
||||
.loader = xstrdup16(loader),
|
||||
.key = key,
|
||||
.tries_done = UINTN_MAX,
|
||||
.tries_left = UINTN_MAX,
|
||||
@@ -1986,7 +1986,7 @@ static EFI_STATUS boot_windows_bitlocker(void) {
|
||||
if (EFI_ERROR(err))
|
||||
continue;
|
||||
|
||||
if (CompareMem(buf + 3, "-FVE-FS-", STRLEN("-FVE-FS-")) == 0) {
|
||||
if (memcmp(buf + 3, "-FVE-FS-", STRLEN("-FVE-FS-")) == 0) {
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
@@ -2021,7 +2021,7 @@ static EFI_STATUS boot_windows_bitlocker(void) {
|
||||
if (buf_size < offset + sizeof(CHAR16))
|
||||
continue;
|
||||
|
||||
if (streq((CHAR16 *) (buf + offset), L"Windows Boot Manager")) {
|
||||
if (streq16((CHAR16 *) (buf + offset), L"Windows Boot Manager")) {
|
||||
err = efivar_set_raw(
|
||||
EFI_GLOBAL_GUID,
|
||||
L"BootNext",
|
||||
@@ -2132,49 +2132,49 @@ static void config_entry_add_unified(
|
||||
|
||||
/* read properties from the embedded os-release file */
|
||||
while ((line = line_get_key_value(content, (CHAR8 *)"=", &pos, &key, &value))) {
|
||||
if (strcmpa((const CHAR8*) "PRETTY_NAME", key) == 0) {
|
||||
if (streq8((char *) key, "PRETTY_NAME")) {
|
||||
FreePool(os_pretty_name);
|
||||
os_pretty_name = xstra_to_str(value);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmpa((const CHAR8*) "IMAGE_ID", key) == 0) {
|
||||
if (streq8((char *) key, "IMAGE_ID")) {
|
||||
FreePool(os_image_id);
|
||||
os_image_id = xstra_to_str(value);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmpa((const CHAR8*) "NAME", key) == 0) {
|
||||
if (streq8((char *) key, "NAME")) {
|
||||
FreePool(os_name);
|
||||
os_name = xstra_to_str(value);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmpa((const CHAR8*) "ID", key) == 0) {
|
||||
if (streq8((char *) key, "ID")) {
|
||||
FreePool(os_id);
|
||||
os_id = xstra_to_str(value);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmpa((const CHAR8*) "IMAGE_VERSION", key) == 0) {
|
||||
if (streq8((char *) key, "IMAGE_VERSION")) {
|
||||
FreePool(os_image_version);
|
||||
os_image_version = xstra_to_str(value);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmpa((const CHAR8*) "VERSION", key) == 0) {
|
||||
if (streq8((char *) key, "VERSION")) {
|
||||
FreePool(os_version);
|
||||
os_version = xstra_to_str(value);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmpa((const CHAR8*) "VERSION_ID", key) == 0) {
|
||||
if (streq8((char *) key, "VERSION_ID")) {
|
||||
FreePool(os_version_id);
|
||||
os_version_id = xstra_to_str(value);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmpa((const CHAR8*) "BUILD_ID", key) == 0) {
|
||||
if (streq8((char *) key, "BUILD_ID")) {
|
||||
FreePool(os_build_id);
|
||||
os_build_id = xstra_to_str(value);
|
||||
continue;
|
||||
@@ -2197,19 +2197,19 @@ static void config_entry_add_unified(
|
||||
|
||||
ConfigEntry *entry = xnew(ConfigEntry, 1);
|
||||
*entry = (ConfigEntry) {
|
||||
.id = xstrdup(f->FileName),
|
||||
.id = xstrdup16(f->FileName),
|
||||
.type = LOADER_UNIFIED_LINUX,
|
||||
.title = xstrdup(good_name),
|
||||
.version = good_version ? xstrdup(good_version) : NULL,
|
||||
.title = xstrdup16(good_name),
|
||||
.version = xstrdup16(good_version),
|
||||
.device = device,
|
||||
.loader = xpool_print(L"\\EFI\\Linux\\%s", f->FileName),
|
||||
.sort_key = good_sort_key ? xstrdup(good_sort_key) : NULL,
|
||||
.sort_key = xstrdup16(good_sort_key),
|
||||
.key = 'l',
|
||||
.tries_done = UINTN_MAX,
|
||||
.tries_left = UINTN_MAX,
|
||||
};
|
||||
|
||||
StrLwr(entry->id);
|
||||
strtolower16(entry->id);
|
||||
config_add_entry(config, entry);
|
||||
config_entry_parse_tries(entry, L"\\EFI\\Linux", f->FileName, L".efi");
|
||||
|
||||
@@ -2375,7 +2375,7 @@ static EFI_STATUS image_start(
|
||||
CHAR16 *options = options_initrd ?: entry->options;
|
||||
if (options) {
|
||||
loaded_image->LoadOptions = options;
|
||||
loaded_image->LoadOptionsSize = StrSize(options);
|
||||
loaded_image->LoadOptionsSize = strsize16(options);
|
||||
|
||||
/* Try to log any options to the TPM, especially to catch manually edited options */
|
||||
(void) tpm_log_load_options(options);
|
||||
@@ -2426,15 +2426,15 @@ static void config_write_entries_to_variable(Config *config) {
|
||||
assert(config);
|
||||
|
||||
for (UINTN i = 0; i < config->entry_count; i++)
|
||||
sz += StrSize(config->entries[i]->id);
|
||||
sz += strsize16(config->entries[i]->id);
|
||||
|
||||
p = buffer = xallocate_pool(sz);
|
||||
|
||||
for (UINTN i = 0; i < config->entry_count; i++) {
|
||||
UINTN l;
|
||||
|
||||
l = StrSize(config->entries[i]->id);
|
||||
CopyMem(p, config->entries[i]->id, l);
|
||||
l = strsize16(config->entries[i]->id);
|
||||
memcpy(p, config->entries[i]->id, l);
|
||||
|
||||
p += l;
|
||||
}
|
||||
@@ -2454,12 +2454,12 @@ static void save_selected_entry(const Config *config, const ConfigEntry *entry)
|
||||
(void) efivar_set(LOADER_GUID, L"LoaderEntrySelected", entry->id, 0);
|
||||
|
||||
/* Do not save or delete if this was a oneshot boot. */
|
||||
if (streq_ptr(config->entry_oneshot, entry->id))
|
||||
if (streq16(config->entry_oneshot, entry->id))
|
||||
return;
|
||||
|
||||
if (config->use_saved_entry_efivar || (!config->entry_default_efivar && config->use_saved_entry)) {
|
||||
/* Avoid unnecessary NVRAM writes. */
|
||||
if (streq_ptr(config->entry_saved, entry->id))
|
||||
if (streq16(config->entry_saved, entry->id))
|
||||
return;
|
||||
|
||||
(void) efivar_set(LOADER_GUID, L"LoaderEntryLastBooted", entry->id, EFI_VARIABLE_NON_VOLATILE);
|
||||
@@ -2545,8 +2545,8 @@ static void config_load_all_entries(
|
||||
if (config->auto_firmware && FLAGS_SET(get_os_indications_supported(), EFI_OS_INDICATIONS_BOOT_TO_FW_UI)) {
|
||||
ConfigEntry *entry = xnew(ConfigEntry, 1);
|
||||
*entry = (ConfigEntry) {
|
||||
.id = xstrdup(L"auto-reboot-to-firmware-setup"),
|
||||
.title = xstrdup(L"Reboot Into Firmware Interface"),
|
||||
.id = xstrdup16(u"auto-reboot-to-firmware-setup"),
|
||||
.title = xstrdup16(u"Reboot Into Firmware Interface"),
|
||||
.call = reboot_into_firmware,
|
||||
.tries_done = UINTN_MAX,
|
||||
.tries_left = UINTN_MAX,
|
||||
|
||||
+14
-14
@@ -81,12 +81,12 @@ static EFI_STATUS pack_cpio_one(
|
||||
|
||||
l = 6 + 13*8 + 1 + 1; /* Fixed CPIO header size, slash separator, and NUL byte after the file name*/
|
||||
|
||||
target_dir_prefix_size = strlena(target_dir_prefix);
|
||||
target_dir_prefix_size = strlen8((const char *) target_dir_prefix);
|
||||
if (l > UINTN_MAX - target_dir_prefix_size)
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
l += target_dir_prefix_size;
|
||||
|
||||
fname_size = StrLen(fname);
|
||||
fname_size = strlen16(fname);
|
||||
if (l > UINTN_MAX - fname_size)
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
l += fname_size; /* append space for file name */
|
||||
@@ -116,7 +116,7 @@ static EFI_STATUS pack_cpio_one(
|
||||
*cpio_buffer = a;
|
||||
a = (CHAR8*) *cpio_buffer + *cpio_buffer_size;
|
||||
|
||||
CopyMem(a, "070701", 6); /* magic ID */
|
||||
memcpy(a, "070701", 6); /* magic ID */
|
||||
a += 6;
|
||||
|
||||
a = write_cpio_word(a, (*inode_counter)++); /* inode */
|
||||
@@ -139,7 +139,7 @@ static EFI_STATUS pack_cpio_one(
|
||||
a = write_cpio_word(a, target_dir_prefix_size + fname_size + 2); /* fname size */
|
||||
a = write_cpio_word(a, 0); /* "crc" */
|
||||
|
||||
CopyMem(a, target_dir_prefix, target_dir_prefix_size);
|
||||
memcpy(a, target_dir_prefix, target_dir_prefix_size);
|
||||
a += target_dir_prefix_size;
|
||||
*(a++) = '/';
|
||||
a = mangle_filename(a, fname);
|
||||
@@ -147,7 +147,7 @@ static EFI_STATUS pack_cpio_one(
|
||||
/* Pad to next multiple of 4 */
|
||||
a = pad4(a, *cpio_buffer);
|
||||
|
||||
CopyMem(a, contents, contents_size);
|
||||
memcpy(a, contents, contents_size);
|
||||
a += contents_size;
|
||||
|
||||
/* Pad to next multiple of 4 */
|
||||
@@ -182,7 +182,7 @@ static EFI_STATUS pack_cpio_dir(
|
||||
|
||||
l = 6 + 13*8 + 1; /* Fixed CPIO header size, and NUL byte after the file name*/
|
||||
|
||||
path_size = strlena(path);
|
||||
path_size = strlen8((const char *) path);
|
||||
if (l > UINTN_MAX - path_size)
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
l += path_size;
|
||||
@@ -198,7 +198,7 @@ static EFI_STATUS pack_cpio_dir(
|
||||
*cpio_buffer = a = xreallocate_pool(*cpio_buffer, *cpio_buffer_size, *cpio_buffer_size + l);
|
||||
a = (CHAR8*) *cpio_buffer + *cpio_buffer_size;
|
||||
|
||||
CopyMem(a, "070701", 6); /* magic ID */
|
||||
memcpy(a, "070701", 6); /* magic ID */
|
||||
a += 6;
|
||||
|
||||
a = write_cpio_word(a, (*inode_counter)++); /* inode */
|
||||
@@ -215,7 +215,7 @@ static EFI_STATUS pack_cpio_dir(
|
||||
a = write_cpio_word(a, path_size + 1); /* fname size */
|
||||
a = write_cpio_word(a, 0); /* "crc" */
|
||||
|
||||
CopyMem(a, path, path_size + 1);
|
||||
memcpy(a, path, path_size + 1);
|
||||
a += path_size + 1;
|
||||
|
||||
/* Pad to next multiple of 4 */
|
||||
@@ -248,14 +248,14 @@ static EFI_STATUS pack_cpio_prefix(
|
||||
for (const CHAR8 *p = path;;) {
|
||||
const CHAR8 *e;
|
||||
|
||||
e = strchra(p, '/');
|
||||
e = (const CHAR8 *) strchr8((const char *) p, '/');
|
||||
if (!e)
|
||||
break;
|
||||
|
||||
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;
|
||||
|
||||
@@ -298,7 +298,7 @@ static EFI_STATUS pack_cpio_trailer(
|
||||
assert_cc(sizeof(trailer) % 4 == 0);
|
||||
|
||||
*cpio_buffer = xreallocate_pool(*cpio_buffer, *cpio_buffer_size, *cpio_buffer_size + sizeof(trailer));
|
||||
CopyMem((UINT8*) *cpio_buffer + *cpio_buffer_size, trailer, sizeof(trailer));
|
||||
memcpy((UINT8*) *cpio_buffer + *cpio_buffer_size, trailer, sizeof(trailer));
|
||||
*cpio_buffer_size += sizeof(trailer);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
@@ -388,10 +388,10 @@ EFI_STATUS pack_cpio(
|
||||
continue;
|
||||
if (!is_ascii(dirent->FileName))
|
||||
continue;
|
||||
if (StrLen(dirent->FileName) > 255) /* Max filename size on Linux */
|
||||
if (strlen16(dirent->FileName) > 255) /* Max filename size on Linux */
|
||||
continue;
|
||||
|
||||
d = xstrdup(dirent->FileName);
|
||||
d = xstrdup16(dirent->FileName);
|
||||
|
||||
if (n_items+2 > n_allocated) {
|
||||
UINTN m;
|
||||
@@ -418,7 +418,7 @@ EFI_STATUS pack_cpio(
|
||||
|
||||
/* Now, sort the files we found, to make this uniform and stable (and to ensure the TPM measurements
|
||||
* are not dependent on read order) */
|
||||
sort_pointer_array((void**) items, n_items, (compare_pointer_func_t) StrCmp);
|
||||
sort_pointer_array((void**) items, n_items, (compare_pointer_func_t) strcmp16);
|
||||
|
||||
/* Generate the leading directory inodes right before adding the first files, to the
|
||||
* archive. Otherwise the cpio archive cannot be unpacked, since the leading dirs won't exist. */
|
||||
|
||||
@@ -51,7 +51,7 @@ static EFI_STATUS devicetree_fixup(struct devicetree_state *state, UINTN len) {
|
||||
if (EFI_ERROR(err))
|
||||
return err;
|
||||
|
||||
CopyMem(PHYSICAL_ADDRESS_TO_POINTER(state->addr), oldptr, len);
|
||||
memcpy(PHYSICAL_ADDRESS_TO_POINTER(state->addr), oldptr, len);
|
||||
err = BS->FreePages(oldaddr, oldpages);
|
||||
if (EFI_ERROR(err))
|
||||
return err;
|
||||
@@ -122,7 +122,7 @@ EFI_STATUS devicetree_install_from_memory(struct devicetree_state *state,
|
||||
if (EFI_ERROR(err))
|
||||
return err;
|
||||
|
||||
CopyMem(PHYSICAL_ADDRESS_TO_POINTER(state->addr), dtb_buffer, dtb_length);
|
||||
memcpy(PHYSICAL_ADDRESS_TO_POINTER(state->addr), dtb_buffer, dtb_length);
|
||||
|
||||
err = devicetree_fixup(state, dtb_length);
|
||||
if (EFI_ERROR(err))
|
||||
|
||||
@@ -0,0 +1,233 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#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
|
||||
* easier to tell in code which kind of string they work on, we use 8/16 suffixes. This also makes is easier
|
||||
* to unit test them. */
|
||||
|
||||
#define DEFINE_STRNLEN(type, name) \
|
||||
size_t name(const type *s, size_t n) { \
|
||||
if (!s) \
|
||||
return 0; \
|
||||
\
|
||||
size_t len = 0; \
|
||||
while (len < n && *s) { \
|
||||
s++; \
|
||||
len++; \
|
||||
} \
|
||||
\
|
||||
return len; \
|
||||
}
|
||||
|
||||
DEFINE_STRNLEN(char, strnlen8);
|
||||
DEFINE_STRNLEN(char16_t, strnlen16);
|
||||
|
||||
size_t strlen8(const char *s) {
|
||||
return strnlen8(s, SIZE_MAX);
|
||||
}
|
||||
|
||||
size_t strlen16(const char16_t *s) {
|
||||
return strnlen16(s, SIZE_MAX);
|
||||
}
|
||||
|
||||
#define TOLOWER(c) \
|
||||
({ \
|
||||
typeof(c) _c = (c); \
|
||||
(_c >= 'A' && _c <= 'Z') ? _c + ('a' - 'A') : _c; \
|
||||
})
|
||||
|
||||
#define DEFINE_STRTOLOWER(type, name) \
|
||||
void name(type *s) { \
|
||||
if (!s) \
|
||||
return; \
|
||||
for (; *s; s++) \
|
||||
*s = TOLOWER(*s); \
|
||||
}
|
||||
|
||||
DEFINE_STRTOLOWER(char, strtolower8);
|
||||
DEFINE_STRTOLOWER(char16_t, strtolower16);
|
||||
|
||||
#define DEFINE_STRNCASECMP(type, name, tolower) \
|
||||
int name(const type *s1, const type *s2, size_t n) { \
|
||||
if (!s1 || !s2) \
|
||||
return CMP(s1, s2); \
|
||||
\
|
||||
while (n > 0) { \
|
||||
int c1 = *s1; \
|
||||
int c2 = *s2; \
|
||||
if (tolower) { \
|
||||
c1 = TOLOWER(c1); \
|
||||
c2 = TOLOWER(c2); \
|
||||
} \
|
||||
if (!c1 || c1 != c2) \
|
||||
return c1 - c2; \
|
||||
\
|
||||
s1++; \
|
||||
s2++; \
|
||||
n--; \
|
||||
} \
|
||||
\
|
||||
return 0; \
|
||||
}
|
||||
|
||||
DEFINE_STRNCASECMP(char, strncmp8, false);
|
||||
DEFINE_STRNCASECMP(char16_t, strncmp16, false);
|
||||
|
||||
int strcmp8(const char *s1, const char *s2) {
|
||||
return strncmp8(s1, s2, SIZE_MAX);
|
||||
}
|
||||
|
||||
int strcmp16(const char16_t *s1, const char16_t *s2) {
|
||||
return strncmp16(s1, s2, SIZE_MAX);
|
||||
}
|
||||
|
||||
DEFINE_STRNCASECMP(char, strncasecmp8, true);
|
||||
DEFINE_STRNCASECMP(char16_t, strncasecmp16, true);
|
||||
|
||||
int strcasecmp8(const char *s1, const char *s2) {
|
||||
return strncasecmp8(s1, s2, SIZE_MAX);
|
||||
}
|
||||
|
||||
int strcasecmp16(const char16_t *s1, const char16_t *s2) {
|
||||
return strncasecmp16(s1, s2, SIZE_MAX);
|
||||
}
|
||||
|
||||
#define DEFINE_STRCPY(type, name) \
|
||||
type *name(type * restrict dest, const type * restrict src) { \
|
||||
assert(dest); \
|
||||
type *ret = dest; \
|
||||
\
|
||||
if (!src) { \
|
||||
*dest = '\0'; \
|
||||
return ret; \
|
||||
} \
|
||||
\
|
||||
while (*src) { \
|
||||
*dest = *src; \
|
||||
dest++; \
|
||||
src++; \
|
||||
} \
|
||||
\
|
||||
*dest = '\0'; \
|
||||
return ret; \
|
||||
}
|
||||
|
||||
DEFINE_STRCPY(char, strcpy8);
|
||||
DEFINE_STRCPY(char16_t, strcpy16);
|
||||
|
||||
#define DEFINE_STRCHR(type, name) \
|
||||
type *name(const type *s, type c) { \
|
||||
if (!s) \
|
||||
return NULL; \
|
||||
\
|
||||
while (*s) { \
|
||||
if (*s == c) \
|
||||
return (type *) s; \
|
||||
s++; \
|
||||
} \
|
||||
\
|
||||
return NULL; \
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
const uint8_t *up1 = p1, *up2 = p2;
|
||||
while (n > 0) {
|
||||
if (*up1 != *up2)
|
||||
return *up1 - *up2;
|
||||
|
||||
up1++;
|
||||
up2++;
|
||||
n--;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *efi_memcpy(void * restrict dest, const void * restrict src, size_t n) {
|
||||
if (!dest || !src || n == 0)
|
||||
return dest;
|
||||
|
||||
uint8_t *d = dest;
|
||||
const uint8_t *s = src;
|
||||
|
||||
while (n > 0) {
|
||||
*d = *s;
|
||||
d++;
|
||||
s++;
|
||||
n--;
|
||||
}
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
void *efi_memset(void *p, int c, size_t n) {
|
||||
if (!p || n == 0)
|
||||
return p;
|
||||
|
||||
uint8_t *q = p;
|
||||
while (n > 0) {
|
||||
*q = c;
|
||||
q++;
|
||||
n--;
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
#ifdef SD_BOOT
|
||||
# undef memcmp
|
||||
# undef memcpy
|
||||
# undef memset
|
||||
/* Provide the actual implementation for the builtins. To prevent a linker error, we mark memcpy/memset as
|
||||
* weak, because gnu-efi is currently providing them. */
|
||||
__attribute__((alias("efi_memcmp"))) int memcmp(const void *p1, const void *p2, size_t n);
|
||||
__attribute__((weak, alias("efi_memcpy"))) void *memcpy(void * restrict dest, const void * restrict src, size_t n);
|
||||
__attribute__((weak, alias("efi_memset"))) void *memset(void *p, int c, size_t n);
|
||||
#endif
|
||||
@@ -0,0 +1,96 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <uchar.h>
|
||||
|
||||
#include "macro-fundamental.h"
|
||||
|
||||
size_t strnlen8(const char *s, size_t n);
|
||||
size_t strnlen16(const char16_t *s, size_t n);
|
||||
|
||||
size_t strlen8(const char *s);
|
||||
size_t strlen16(const char16_t *s);
|
||||
|
||||
static inline size_t strsize8(const char *s) {
|
||||
return s ? (strlen8(s) + 1) * sizeof(*s) : 0;
|
||||
}
|
||||
|
||||
static inline size_t strsize16(const char16_t *s) {
|
||||
return s ? (strlen16(s) + 1) * sizeof(*s) : 0;
|
||||
}
|
||||
|
||||
void strtolower8(char *s);
|
||||
void strtolower16(char16_t *s);
|
||||
|
||||
int strncmp8(const char *s1, const char *s2, size_t n);
|
||||
int strncmp16(const char16_t *s1, const char16_t *s2, size_t n);
|
||||
|
||||
int strcmp8(const char *s1, const char *s2);
|
||||
int strcmp16(const char16_t *s1, const char16_t *s2);
|
||||
|
||||
int strncasecmp8(const char *s1, const char *s2, size_t n);
|
||||
int strncasecmp16(const char16_t *s1, const char16_t *s2, size_t n);
|
||||
|
||||
int strcasecmp8(const char *s1, const char *s2);
|
||||
int strcasecmp16(const char16_t *s1, const char16_t *s2);
|
||||
|
||||
static inline bool strneq8(const char *s1, const char *s2, size_t n) {
|
||||
return strncmp8(s1, s2, n) == 0;
|
||||
}
|
||||
|
||||
static inline bool strneq16(const char16_t *s1, const char16_t *s2, size_t n) {
|
||||
return strncmp16(s1, s2, n) == 0;
|
||||
}
|
||||
|
||||
static inline bool streq8(const char *s1, const char *s2) {
|
||||
return strcmp8(s1, s2) == 0;
|
||||
}
|
||||
|
||||
static inline bool streq16(const char16_t *s1, const char16_t *s2) {
|
||||
return strcmp16(s1, s2) == 0;
|
||||
}
|
||||
|
||||
static inline int strncaseeq8(const char *s1, const char *s2, size_t n) {
|
||||
return strncasecmp8(s1, s2, n) == 0;
|
||||
}
|
||||
|
||||
static inline int strncaseeq16(const char16_t *s1, const char16_t *s2, size_t n) {
|
||||
return strncasecmp16(s1, s2, n) == 0;
|
||||
}
|
||||
|
||||
static inline bool strcaseeq8(const char *s1, const char *s2) {
|
||||
return strcasecmp8(s1, s2) == 0;
|
||||
}
|
||||
|
||||
static inline bool strcaseeq16(const char16_t *s1, const char16_t *s2) {
|
||||
return strcasecmp16(s1, s2) == 0;
|
||||
}
|
||||
|
||||
char *strcpy8(char * restrict dest, const char * restrict src);
|
||||
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
|
||||
* optimizations again. Note that we still need to provide implementations as the compiler is free to not
|
||||
* inline its own implementation and instead issue a library call. */
|
||||
# define memcmp __builtin_memcmp
|
||||
# define memcpy __builtin_memcpy
|
||||
# define memset __builtin_memset
|
||||
#endif
|
||||
|
||||
/* The actual implementations of builtins with efi_ prefix so we can unit test them. */
|
||||
int efi_memcmp(const void *p1, const void *p2, size_t n);
|
||||
void *efi_memcpy(void * restrict dest, const void * restrict src, size_t n);
|
||||
void *efi_memset(void *p, int c, size_t n);
|
||||
@@ -61,7 +61,7 @@ EFIAPI EFI_STATUS initrd_load_file(
|
||||
return EFI_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
CopyMem(buffer, loader->address, loader->length);
|
||||
memcpy(buffer, loader->address, loader->length);
|
||||
*buffer_size = loader->length;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ static EFI_STATUS loaded_image_register(
|
||||
/* if a cmdline is set convert it to UCS2 */
|
||||
if (cmdline) {
|
||||
loaded_image->LoadOptions = xstra_to_str(cmdline);
|
||||
loaded_image->LoadOptionsSize = StrSize(loaded_image->LoadOptions);
|
||||
loaded_image->LoadOptionsSize = strsize16(loaded_image->LoadOptions);
|
||||
}
|
||||
|
||||
/* install a new LoadedImage protocol. ret_handle is a new image handle */
|
||||
@@ -145,9 +145,9 @@ EFI_STATUS linux_exec(
|
||||
if (EFI_ERROR(err))
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
new_buffer = PHYSICAL_ADDRESS_TO_POINTER(ALIGN_TO(kernel.addr, kernel_alignment));
|
||||
CopyMem(new_buffer, linux_buffer, linux_length);
|
||||
memcpy(new_buffer, linux_buffer, linux_length);
|
||||
/* zero out rest of memory (probably not needed, but BSS section should be 0) */
|
||||
SetMem((UINT8 *)new_buffer + linux_length, kernel_size_of_image - linux_length, 0);
|
||||
memset((UINT8 *)new_buffer + linux_length, 0, kernel_size_of_image - linux_length);
|
||||
|
||||
/* get the entry point inside the relocated kernel */
|
||||
kernel_entry = (EFI_IMAGE_ENTRY_POINT) ((const UINT8 *)new_buffer + kernel_entry_address);
|
||||
|
||||
@@ -159,7 +159,7 @@ EFI_STATUS linux_exec(
|
||||
return err;
|
||||
|
||||
boot_params = (struct boot_params *) PHYSICAL_ADDRESS_TO_POINTER(addr);
|
||||
ZeroMem(boot_params, 0x4000);
|
||||
memset(boot_params, 0, 0x4000);
|
||||
boot_params->hdr = image_params->hdr;
|
||||
boot_params->hdr.type_of_loader = 0xff;
|
||||
setup_sectors = image_params->hdr.setup_sects > 0 ? image_params->hdr.setup_sects : 4;
|
||||
@@ -176,7 +176,7 @@ EFI_STATUS linux_exec(
|
||||
if (EFI_ERROR(err))
|
||||
return err;
|
||||
|
||||
CopyMem(PHYSICAL_ADDRESS_TO_POINTER(addr), cmdline, cmdline_len);
|
||||
memcpy(PHYSICAL_ADDRESS_TO_POINTER(addr), cmdline, cmdline_len);
|
||||
((CHAR8 *) PHYSICAL_ADDRESS_TO_POINTER(addr))[cmdline_len] = 0;
|
||||
boot_params->hdr.cmd_line_ptr = (UINT32) addr;
|
||||
}
|
||||
|
||||
@@ -25,14 +25,14 @@ static EFI_STATUS tpm1_measure_to_pcr_and_event_log(
|
||||
assert(tcg);
|
||||
assert(description);
|
||||
|
||||
desc_len = StrSize(description);
|
||||
desc_len = strsize16(description);
|
||||
tcg_event = xallocate_zero_pool(offsetof(TCG_PCR_EVENT, Event) + desc_len);
|
||||
*tcg_event = (TCG_PCR_EVENT) {
|
||||
.EventSize = desc_len,
|
||||
.PCRIndex = pcrindex,
|
||||
.EventType = EV_IPL,
|
||||
};
|
||||
CopyMem(tcg_event->Event, description, desc_len);
|
||||
memcpy(tcg_event->Event, description, desc_len);
|
||||
|
||||
return tcg->HashLogExtendEvent(
|
||||
(EFI_TCG *) tcg,
|
||||
@@ -56,7 +56,7 @@ static EFI_STATUS tpm2_measure_to_pcr_and_event_log(
|
||||
assert(tcg);
|
||||
assert(description);
|
||||
|
||||
desc_len = StrSize(description);
|
||||
desc_len = strsize16(description);
|
||||
tcg_event = xallocate_zero_pool(offsetof(EFI_TCG2_EVENT, Event) + desc_len);
|
||||
*tcg_event = (EFI_TCG2_EVENT) {
|
||||
.Size = offsetof(EFI_TCG2_EVENT, Event) + desc_len,
|
||||
@@ -66,7 +66,7 @@ static EFI_STATUS tpm2_measure_to_pcr_and_event_log(
|
||||
.Header.EventType = EV_IPL,
|
||||
};
|
||||
|
||||
CopyMem(tcg_event->Event, description, desc_len);
|
||||
memcpy(tcg_event->Event, description, desc_len);
|
||||
|
||||
return tcg->HashLogExtendEvent(
|
||||
tcg,
|
||||
@@ -171,7 +171,7 @@ EFI_STATUS tpm_log_load_options(const CHAR16 *load_options) {
|
||||
|
||||
err = tpm_log_event(pcr,
|
||||
POINTER_TO_PHYSICAL_ADDRESS(load_options),
|
||||
StrSize(load_options), load_options);
|
||||
strsize16(load_options), load_options);
|
||||
if (EFI_ERROR(err))
|
||||
return log_error_status_stall(err, L"Unable to add load options (i.e. kernel command) line measurement to PCR %u: %r", pcr, err);
|
||||
}
|
||||
|
||||
@@ -194,6 +194,7 @@ efi_cflags = cc.get_supported_arguments(
|
||||
'-isystem', efi_incdir,
|
||||
'-isystem', efi_incdir / efi_arch[1],
|
||||
'-I', fundamental_path,
|
||||
'-I', meson.current_source_dir(),
|
||||
'-DSD_BOOT',
|
||||
'-DGNU_EFI_USE_MS_ABI',
|
||||
'-include', efi_config_h,
|
||||
@@ -331,6 +332,7 @@ efi_headers = files(
|
||||
'devicetree.h',
|
||||
'disk.h',
|
||||
'drivers.h',
|
||||
'efi-string.h',
|
||||
'graphics.h',
|
||||
'initrd.h',
|
||||
'linux.h',
|
||||
@@ -350,6 +352,7 @@ common_sources = files(
|
||||
'assert.c',
|
||||
'devicetree.c',
|
||||
'disk.c',
|
||||
'efi-string.c',
|
||||
'graphics.c',
|
||||
'initrd.c',
|
||||
'measure.c',
|
||||
@@ -380,18 +383,22 @@ else
|
||||
stub_sources += files('linux.c')
|
||||
endif
|
||||
|
||||
tests += [
|
||||
[files('test-efi-string.c', 'efi-string.c')],
|
||||
]
|
||||
|
||||
# BCD parser only makes sense on arches that Windows supports.
|
||||
if efi_arch[1] in ['ia32', 'x86_64', 'arm', 'aarch64']
|
||||
systemd_boot_sources += files('bcd.c')
|
||||
tests += [
|
||||
[files('test-bcd.c'),
|
||||
[files('test-bcd.c', 'efi-string.c'),
|
||||
[],
|
||||
[libzstd],
|
||||
[],
|
||||
'HAVE_ZSTD'],
|
||||
]
|
||||
fuzzers += [
|
||||
[files('fuzz-bcd.c')],
|
||||
[files('fuzz-bcd.c', 'efi-string.c')],
|
||||
]
|
||||
endif
|
||||
|
||||
|
||||
+3
-3
@@ -119,12 +119,12 @@ struct PeSectionHeader {
|
||||
|
||||
static inline BOOLEAN verify_dos(const struct DosFileHeader *dos) {
|
||||
assert(dos);
|
||||
return CompareMem(dos->Magic, DOS_FILE_MAGIC, STRLEN(DOS_FILE_MAGIC)) == 0;
|
||||
return memcmp(dos->Magic, DOS_FILE_MAGIC, STRLEN(DOS_FILE_MAGIC)) == 0;
|
||||
}
|
||||
|
||||
static inline BOOLEAN verify_pe(const struct PeFileHeader *pe, BOOLEAN allow_compatibility) {
|
||||
assert(pe);
|
||||
return CompareMem(pe->Magic, PE_FILE_MAGIC, STRLEN(PE_FILE_MAGIC)) == 0 &&
|
||||
return memcmp(pe->Magic, PE_FILE_MAGIC, STRLEN(PE_FILE_MAGIC)) == 0 &&
|
||||
(pe->FileHeader.Machine == TARGET_MACHINE_TYPE ||
|
||||
(allow_compatibility && pe->FileHeader.Machine == TARGET_MACHINE_TYPE_COMPATIBILITY)) &&
|
||||
pe->FileHeader.NumberOfSections > 0 &&
|
||||
@@ -154,7 +154,7 @@ static void locate_sections(
|
||||
const struct PeSectionHeader *sect = section_table + i;
|
||||
|
||||
for (UINTN j = 0; sections[j]; j++) {
|
||||
if (CompareMem(sect->Name, sections[j], strlena(sections[j])) != 0)
|
||||
if (memcmp(sect->Name, sections[j], strlen8((const char *) sections[j])) != 0)
|
||||
continue;
|
||||
|
||||
if (addrs)
|
||||
|
||||
@@ -220,10 +220,10 @@ static void validate_sha256(void) {
|
||||
uint8_t result[HASH_VALUE_SIZE];
|
||||
|
||||
sha256_init_ctx(&hash);
|
||||
sha256_process_bytes(array[i].string, strlena((const CHAR8*) array[i].string), &hash);
|
||||
sha256_process_bytes(array[i].string, strlen8(array[i].string), &hash);
|
||||
sha256_finish_ctx(&hash, result);
|
||||
|
||||
assert(CompareMem(result, array[i].hash, HASH_VALUE_SIZE) == 0);
|
||||
assert(memcmp(result, array[i].hash, HASH_VALUE_SIZE) == 0);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -271,7 +271,7 @@ EFI_STATUS graphics_splash(const UINT8 *content, UINTN len, const EFI_GRAPHICS_O
|
||||
assert(content);
|
||||
|
||||
if (!background) {
|
||||
if (StriCmp(L"Apple", ST->FirmwareVendor) == 0) {
|
||||
if (strcaseeq16(u"Apple", ST->FirmwareVendor)) {
|
||||
pixel.Red = 0xc0;
|
||||
pixel.Green = 0xc0;
|
||||
pixel.Blue = 0xc0;
|
||||
|
||||
+5
-5
@@ -68,28 +68,28 @@ static EFI_STATUS combine_initrd(
|
||||
|
||||
/* Order matters, the real initrd must come first, since it might include microcode updates
|
||||
* which the kernel only looks for in the first cpio archive */
|
||||
CopyMem(p, PHYSICAL_ADDRESS_TO_POINTER(initrd_base), initrd_size);
|
||||
memcpy(p, PHYSICAL_ADDRESS_TO_POINTER(initrd_base), initrd_size);
|
||||
p += initrd_size;
|
||||
|
||||
pad = ALIGN_TO(initrd_size, 4) - initrd_size;
|
||||
if (pad > 0) {
|
||||
ZeroMem(p, pad);
|
||||
memset(p, 0, pad);
|
||||
p += pad;
|
||||
}
|
||||
}
|
||||
|
||||
if (credential_initrd) {
|
||||
CopyMem(p, credential_initrd, credential_initrd_size);
|
||||
memcpy(p, credential_initrd, credential_initrd_size);
|
||||
p += credential_initrd_size;
|
||||
}
|
||||
|
||||
if (global_credential_initrd) {
|
||||
CopyMem(p, global_credential_initrd, global_credential_initrd_size);
|
||||
memcpy(p, global_credential_initrd, global_credential_initrd_size);
|
||||
p += global_credential_initrd_size;
|
||||
}
|
||||
|
||||
if (sysext_initrd) {
|
||||
CopyMem(p, sysext_initrd, sysext_initrd_size);
|
||||
memcpy(p, sysext_initrd, sysext_initrd_size);
|
||||
p += sysext_initrd_size;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,376 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include "efi-string.h"
|
||||
#include "tests.h"
|
||||
|
||||
TEST(strlen8) {
|
||||
assert_se(strlen8(NULL) == 0);
|
||||
assert_se(strlen8("") == 0);
|
||||
assert_se(strlen8("1") == 1);
|
||||
assert_se(strlen8("11") == 2);
|
||||
assert_se(strlen8("123456789") == 9);
|
||||
assert_se(strlen8("12\0004") == 2);
|
||||
}
|
||||
|
||||
TEST(strlen16) {
|
||||
assert_se(strlen16(NULL) == 0);
|
||||
assert_se(strlen16(u"") == 0);
|
||||
assert_se(strlen16(u"1") == 1);
|
||||
assert_se(strlen16(u"11") == 2);
|
||||
assert_se(strlen16(u"123456789") == 9);
|
||||
assert_se(strlen16(u"12\0004") == 2);
|
||||
}
|
||||
|
||||
TEST(strnlen8) {
|
||||
assert_se(strnlen8(NULL, 0) == 0);
|
||||
assert_se(strnlen8(NULL, 10) == 0);
|
||||
assert_se(strnlen8("", 10) == 0);
|
||||
assert_se(strnlen8("1", 10) == 1);
|
||||
assert_se(strnlen8("11", 1) == 1);
|
||||
assert_se(strnlen8("123456789", 7) == 7);
|
||||
assert_se(strnlen8("12\0004", 5) == 2);
|
||||
}
|
||||
|
||||
TEST(strnlen16) {
|
||||
assert_se(strnlen16(NULL, 0) == 0);
|
||||
assert_se(strnlen16(NULL, 10) == 0);
|
||||
assert_se(strnlen16(u"", 10) == 0);
|
||||
assert_se(strnlen16(u"1", 10) == 1);
|
||||
assert_se(strnlen16(u"11", 1) == 1);
|
||||
assert_se(strnlen16(u"123456789", 7) == 7);
|
||||
assert_se(strnlen16(u"12\0004", 5) == 2);
|
||||
}
|
||||
|
||||
TEST(strsize8) {
|
||||
assert_se(strsize8(NULL) == 0);
|
||||
assert_se(strsize8("") == 1);
|
||||
assert_se(strsize8("1") == 2);
|
||||
assert_se(strsize8("11") == 3);
|
||||
assert_se(strsize8("123456789") == 10);
|
||||
assert_se(strsize8("12\0004") == 3);
|
||||
}
|
||||
|
||||
TEST(strsize16) {
|
||||
assert_se(strsize16(NULL) == 0);
|
||||
assert_se(strsize16(u"") == 2);
|
||||
assert_se(strsize16(u"1") == 4);
|
||||
assert_se(strsize16(u"11") == 6);
|
||||
assert_se(strsize16(u"123456789") == 20);
|
||||
assert_se(strsize16(u"12\0004") == 6);
|
||||
}
|
||||
|
||||
TEST(strtolower8) {
|
||||
char s[] = "\0001234abcDEF!\0zZ";
|
||||
|
||||
strtolower8(NULL);
|
||||
|
||||
strtolower8(s);
|
||||
assert_se(memcmp(s, "\0001234abcDEF!\0zZ", sizeof(s)) == 0);
|
||||
|
||||
s[0] = '#';
|
||||
strtolower8(s);
|
||||
assert_se(memcmp(s, "#1234abcdef!\0zZ", sizeof(s)) == 0);
|
||||
}
|
||||
|
||||
TEST(strtolower16) {
|
||||
char16_t s[] = u"\0001234abcDEF!\0zZ";
|
||||
|
||||
strtolower16(NULL);
|
||||
|
||||
strtolower16(s);
|
||||
assert_se(memcmp(s, u"\0001234abcDEF!\0zZ", sizeof(s)) == 0);
|
||||
|
||||
s[0] = '#';
|
||||
strtolower16(s);
|
||||
assert_se(memcmp(s, u"#1234abcdef!\0zZ", sizeof(s)) == 0);
|
||||
}
|
||||
|
||||
TEST(strncmp8) {
|
||||
assert_se(strncmp8(NULL, "", 10) < 0);
|
||||
assert_se(strncmp8("", NULL, 10) > 0);
|
||||
assert_se(strncmp8(NULL, NULL, 0) == 0);
|
||||
assert_se(strncmp8(NULL, NULL, 10) == 0);
|
||||
assert_se(strncmp8("", "", 10) == 0);
|
||||
assert_se(strncmp8("abc", "abc", 2) == 0);
|
||||
assert_se(strncmp8("aBc", "aBc", 3) == 0);
|
||||
assert_se(strncmp8("aBC", "aBC", 4) == 0);
|
||||
assert_se(strncmp8("", "a", 0) == 0);
|
||||
assert_se(strncmp8("b", "a", 0) == 0);
|
||||
assert_se(strncmp8("", "a", 3) < 0);
|
||||
assert_se(strncmp8("=", "=", 1) == 0);
|
||||
assert_se(strncmp8("A", "a", 1) < 0);
|
||||
assert_se(strncmp8("a", "A", 2) > 0);
|
||||
assert_se(strncmp8("a", "Aa", 2) > 0);
|
||||
assert_se(strncmp8("12\00034", "12345", 4) < 0);
|
||||
assert_se(strncmp8("12\00034", "12345", SIZE_MAX) < 0);
|
||||
assert_se(strncmp8("abc\0def", "abc", SIZE_MAX) == 0);
|
||||
assert_se(strncmp8("abc\0def", "abcdef", SIZE_MAX) < 0);
|
||||
|
||||
assert_se(strncmp8((char[]){ CHAR_MIN }, (char[]){ CHAR_MIN }, 1) == 0);
|
||||
assert_se(strncmp8((char[]){ CHAR_MAX }, (char[]){ CHAR_MAX }, 1) == 0);
|
||||
assert_se(strncmp8((char[]){ CHAR_MIN }, (char[]){ CHAR_MAX }, 1) < 0);
|
||||
assert_se(strncmp8((char[]){ CHAR_MAX }, (char[]){ CHAR_MIN }, 1) > 0);
|
||||
}
|
||||
|
||||
TEST(strncmp16) {
|
||||
assert_se(strncmp16(NULL, u"", 10) < 0);
|
||||
assert_se(strncmp16(u"", NULL, 10) > 0);
|
||||
assert_se(strncmp16(NULL, NULL, 0) == 0);
|
||||
assert_se(strncmp16(NULL, NULL, 10) == 0);
|
||||
assert_se(strncmp16(u"", u"", 0) == 0);
|
||||
assert_se(strncmp16(u"", u"", 10) == 0);
|
||||
assert_se(strncmp16(u"abc", u"abc", 2) == 0);
|
||||
assert_se(strncmp16(u"aBc", u"aBc", 3) == 0);
|
||||
assert_se(strncmp16(u"aBC", u"aBC", 4) == 0);
|
||||
assert_se(strncmp16(u"", u"a", 0) == 0);
|
||||
assert_se(strncmp16(u"b", u"a", 0) == 0);
|
||||
assert_se(strncmp16(u"", u"a", 3) < 0);
|
||||
assert_se(strncmp16(u"=", u"=", 1) == 0);
|
||||
assert_se(strncmp16(u"A", u"a", 1) < 0);
|
||||
assert_se(strncmp16(u"a", u"A", 2) > 0);
|
||||
assert_se(strncmp16(u"a", u"Aa", 2) > 0);
|
||||
assert_se(strncmp16(u"12\00034", u"12345", 4) < 0);
|
||||
assert_se(strncmp16(u"12\00034", u"12345", SIZE_MAX) < 0);
|
||||
assert_se(strncmp16(u"abc\0def", u"abc", SIZE_MAX) == 0);
|
||||
assert_se(strncmp16(u"abc\0def", u"abcdef", SIZE_MAX) < 0);
|
||||
|
||||
assert_se(strncmp16((char16_t[]){ UINT16_MAX }, (char16_t[]){ UINT16_MAX }, 1) == 0);
|
||||
assert_se(strncmp16((char16_t[]){ 0 }, (char16_t[]){ UINT16_MAX }, 1) < 0);
|
||||
assert_se(strncmp16((char16_t[]){ UINT16_MAX }, (char16_t[]){ 0 }, 1) > 0);
|
||||
}
|
||||
|
||||
TEST(strncasecmp8) {
|
||||
assert_se(strncasecmp8(NULL, "", 10) < 0);
|
||||
assert_se(strncasecmp8("", NULL, 10) > 0);
|
||||
assert_se(strncasecmp8(NULL, NULL, 0) == 0);
|
||||
assert_se(strncasecmp8(NULL, NULL, 10) == 0);
|
||||
assert_se(strncasecmp8("", "", 10) == 0);
|
||||
assert_se(strncasecmp8("abc", "abc", 2) == 0);
|
||||
assert_se(strncasecmp8("aBc", "AbC", 3) == 0);
|
||||
assert_se(strncasecmp8("aBC", "Abc", 4) == 0);
|
||||
assert_se(strncasecmp8("", "a", 0) == 0);
|
||||
assert_se(strncasecmp8("b", "a", 0) == 0);
|
||||
assert_se(strncasecmp8("", "a", 3) < 0);
|
||||
assert_se(strncasecmp8("=", "=", 1) == 0);
|
||||
assert_se(strncasecmp8("A", "a", 1) == 0);
|
||||
assert_se(strncasecmp8("a", "A", 2) == 0);
|
||||
assert_se(strncasecmp8("a", "Aa", 2) < 0);
|
||||
assert_se(strncasecmp8("12\00034", "12345", 4) < 0);
|
||||
assert_se(strncasecmp8("12\00034", "12345", SIZE_MAX) < 0);
|
||||
assert_se(strncasecmp8("abc\0def", "ABC", SIZE_MAX) == 0);
|
||||
assert_se(strncasecmp8("abc\0def", "ABCDEF", SIZE_MAX) < 0);
|
||||
|
||||
assert_se(strncasecmp8((char[]){ CHAR_MIN }, (char[]){ CHAR_MIN }, 1) == 0);
|
||||
assert_se(strncasecmp8((char[]){ CHAR_MAX }, (char[]){ CHAR_MAX }, 1) == 0);
|
||||
assert_se(strncasecmp8((char[]){ CHAR_MIN }, (char[]){ CHAR_MAX }, 1) < 0);
|
||||
assert_se(strncasecmp8((char[]){ CHAR_MAX }, (char[]){ CHAR_MIN }, 1) > 0);
|
||||
}
|
||||
|
||||
TEST(strncasecmp16) {
|
||||
assert_se(strncasecmp16(NULL, u"", 10) < 0);
|
||||
assert_se(strncasecmp16(u"", NULL, 10) > 0);
|
||||
assert_se(strncasecmp16(NULL, NULL, 0) == 0);
|
||||
assert_se(strncasecmp16(NULL, NULL, 10) == 0);
|
||||
assert_se(strncasecmp16(u"", u"", 10) == 0);
|
||||
assert_se(strncasecmp16(u"abc", u"abc", 2) == 0);
|
||||
assert_se(strncasecmp16(u"aBc", u"AbC", 3) == 0);
|
||||
assert_se(strncasecmp16(u"aBC", u"Abc", 4) == 0);
|
||||
assert_se(strncasecmp16(u"", u"a", 0) == 0);
|
||||
assert_se(strncasecmp16(u"b", u"a", 0) == 0);
|
||||
assert_se(strncasecmp16(u"", u"a", 3) < 0);
|
||||
assert_se(strncasecmp16(u"=", u"=", 1) == 0);
|
||||
assert_se(strncasecmp16(u"A", u"a", 1) == 0);
|
||||
assert_se(strncasecmp16(u"a", u"A", 2) == 0);
|
||||
assert_se(strncasecmp16(u"a", u"Aa", 2) < 0);
|
||||
assert_se(strncasecmp16(u"12\00034", u"12345", 4) < 0);
|
||||
assert_se(strncasecmp16(u"12\00034", u"12345", SIZE_MAX) < 0);
|
||||
assert_se(strncasecmp16(u"abc\0def", u"ABC", SIZE_MAX) == 0);
|
||||
assert_se(strncasecmp16(u"abc\0def", u"ABCDEF", SIZE_MAX) < 0);
|
||||
|
||||
assert_se(strncasecmp16((char16_t[]){ UINT16_MAX }, (char16_t[]){ UINT16_MAX }, 1) == 0);
|
||||
assert_se(strncasecmp16((char16_t[]){ 0 }, (char16_t[]){ UINT16_MAX }, 1) < 0);
|
||||
assert_se(strncasecmp16((char16_t[]){ UINT16_MAX }, (char16_t[]){ 0 }, 1) > 0);
|
||||
}
|
||||
|
||||
TEST(strcpy8) {
|
||||
char buf[128];
|
||||
|
||||
assert_se(strcpy8(buf, "123") == buf);
|
||||
assert_se(streq8(buf, "123"));
|
||||
assert_se(strcpy8(buf, "") == buf);
|
||||
assert_se(streq8(buf, ""));
|
||||
assert_se(strcpy8(buf, "A") == buf);
|
||||
assert_se(streq8(buf, "A"));
|
||||
assert_se(strcpy8(buf, NULL) == buf);
|
||||
assert_se(streq8(buf, ""));
|
||||
}
|
||||
|
||||
TEST(strcpy16) {
|
||||
char16_t buf[128];
|
||||
|
||||
assert_se(strcpy16(buf, u"123") == buf);
|
||||
assert_se(streq16(buf, u"123"));
|
||||
assert_se(strcpy16(buf, u"") == buf);
|
||||
assert_se(streq16(buf, u""));
|
||||
assert_se(strcpy16(buf, u"A") == buf);
|
||||
assert_se(streq16(buf, u"A"));
|
||||
assert_se(strcpy16(buf, NULL) == buf);
|
||||
assert_se(streq16(buf, u""));
|
||||
}
|
||||
|
||||
TEST(strchr8) {
|
||||
assert_se(!strchr8(NULL, 'a'));
|
||||
assert_se(!strchr8("", 'a'));
|
||||
assert_se(!strchr8("123", 'a'));
|
||||
|
||||
const char str[] = "abcaBc";
|
||||
assert_se(strchr8(str, 'a') == &str[0]);
|
||||
assert_se(strchr8(str, 'c') == &str[2]);
|
||||
assert_se(strchr8(str, 'B') == &str[4]);
|
||||
}
|
||||
|
||||
TEST(strchr16) {
|
||||
assert_se(!strchr16(NULL, 'a'));
|
||||
assert_se(!strchr16(u"", 'a'));
|
||||
assert_se(!strchr16(u"123", 'a'));
|
||||
|
||||
const char16_t str[] = u"abcaBc";
|
||||
assert_se(strchr16(str, 'a') == &str[0]);
|
||||
assert_se(strchr16(str, 'c') == &str[2]);
|
||||
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);
|
||||
assert_se(efi_memcmp(NULL, "", 1) < 0);
|
||||
assert_se(efi_memcmp("", NULL, 1) > 0);
|
||||
assert_se(efi_memcmp("", "", 0) == 0);
|
||||
assert_se(efi_memcmp("", "", 1) == 0);
|
||||
assert_se(efi_memcmp("1", "1", 1) == 0);
|
||||
assert_se(efi_memcmp("1", "2", 1) < 0);
|
||||
assert_se(efi_memcmp("A", "a", 1) < 0);
|
||||
assert_se(efi_memcmp("a", "A", 1) > 0);
|
||||
assert_se(efi_memcmp("abc", "ab", 2) == 0);
|
||||
assert_se(efi_memcmp("ab", "abc", 3) < 0);
|
||||
assert_se(efi_memcmp("ab\000bd", "ab\000bd", 6) == 0);
|
||||
assert_se(efi_memcmp("ab\000b\0", "ab\000bd", 6) < 0);
|
||||
}
|
||||
|
||||
TEST(efi_memcpy) {
|
||||
char buf[10];
|
||||
|
||||
assert_se(!efi_memcpy(NULL, NULL, 0));
|
||||
assert_se(!efi_memcpy(NULL, "", 1));
|
||||
assert_se(efi_memcpy(buf, NULL, 0) == buf);
|
||||
assert_se(efi_memcpy(buf, NULL, 1) == buf);
|
||||
assert_se(efi_memcpy(buf, "a", 0) == buf);
|
||||
|
||||
assert_se(efi_memcpy(buf, "", 1) == buf);
|
||||
assert_se(memcmp(buf, "", 1) == 0);
|
||||
assert_se(efi_memcpy(buf, "1", 1) == buf);
|
||||
assert_se(memcmp(buf, "1", 1) == 0);
|
||||
assert_se(efi_memcpy(buf, "23", 3) == buf);
|
||||
assert_se(memcmp(buf, "23", 3) == 0);
|
||||
assert_se(efi_memcpy(buf, "45\0ab\0\0\0c", 9) == buf);
|
||||
assert_se(memcmp(buf, "45\0ab\0\0\0c", 9) == 0);
|
||||
}
|
||||
|
||||
TEST(efi_memset) {
|
||||
char buf[10];
|
||||
|
||||
assert_se(!efi_memset(NULL, '1', 0));
|
||||
assert_se(!efi_memset(NULL, '1', 1));
|
||||
assert_se(efi_memset(buf, '1', 0) == buf);
|
||||
|
||||
assert_se(efi_memset(buf, '2', 1) == buf);
|
||||
assert_se(memcmp(buf, "2", 1) == 0);
|
||||
assert_se(efi_memset(buf, '4', 4) == buf);
|
||||
assert_se(memcmp(buf, "4444", 4) == 0);
|
||||
assert_se(efi_memset(buf, 'a', 10) == buf);
|
||||
assert_se(memcmp(buf, "aaaaaaaaaa", 10) == 0);
|
||||
}
|
||||
|
||||
DEFINE_TEST_MAIN(LOG_INFO);
|
||||
+9
-83
@@ -12,22 +12,14 @@ EFI_STATUS parse_boolean(const CHAR8 *v, BOOLEAN *b) {
|
||||
if (!v)
|
||||
return EFI_INVALID_PARAMETER;
|
||||
|
||||
if (strcmpa(v, (CHAR8 *)"1") == 0 ||
|
||||
strcmpa(v, (CHAR8 *)"yes") == 0 ||
|
||||
strcmpa(v, (CHAR8 *)"y") == 0 ||
|
||||
strcmpa(v, (CHAR8 *)"true") == 0 ||
|
||||
strcmpa(v, (CHAR8 *)"t") == 0 ||
|
||||
strcmpa(v, (CHAR8 *)"on") == 0) {
|
||||
if (streq8((char *) v, "1") || streq8((char *) v, "yes") || streq8((char *) v, "y") ||
|
||||
streq8((char *) v, "true") || streq8((char *) v, "t") || streq8((char *) v, "on")) {
|
||||
*b = TRUE;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
if (strcmpa(v, (CHAR8 *)"0") == 0 ||
|
||||
strcmpa(v, (CHAR8 *)"no") == 0 ||
|
||||
strcmpa(v, (CHAR8 *)"n") == 0 ||
|
||||
strcmpa(v, (CHAR8 *)"false") == 0 ||
|
||||
strcmpa(v, (CHAR8 *)"f") == 0 ||
|
||||
strcmpa(v, (CHAR8 *)"off") == 0) {
|
||||
if (streq8((char *) v, "0") || streq8((char *) v, "no") || streq8((char *) v, "n") ||
|
||||
streq8((char *) v, "false") || streq8((char *) v, "f") || streq8((char *) v, "off")) {
|
||||
*b = FALSE;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
@@ -48,7 +40,7 @@ EFI_STATUS efivar_set(const EFI_GUID *vendor, const CHAR16 *name, const CHAR16 *
|
||||
assert(vendor);
|
||||
assert(name);
|
||||
|
||||
return efivar_set_raw(vendor, name, value, value ? StrSize(value) : 0, flags);
|
||||
return efivar_set_raw(vendor, name, value, value ? strsize16(value) : 0, flags);
|
||||
}
|
||||
|
||||
EFI_STATUS efivar_set_uint_string(const EFI_GUID *vendor, const CHAR16 *name, UINTN i, UINT32 flags) {
|
||||
@@ -125,7 +117,7 @@ EFI_STATUS efivar_get(const EFI_GUID *vendor, const CHAR16 *name, CHAR16 **value
|
||||
/* Make sure a terminating NUL is available at the end */
|
||||
val = xallocate_pool(size + sizeof(CHAR16));
|
||||
|
||||
CopyMem(val, buf, size);
|
||||
memcpy(val, buf, size);
|
||||
val[size / sizeof(CHAR16) - 1] = 0; /* NUL terminate */
|
||||
|
||||
*value = val;
|
||||
@@ -306,7 +298,7 @@ CHAR16 *xstra_to_str(const CHAR8 *stra) {
|
||||
|
||||
assert(stra);
|
||||
|
||||
len = strlena(stra);
|
||||
len = strlen8((const char *) stra);
|
||||
str = xnew(CHAR16, len + 1);
|
||||
|
||||
strlen = 0;
|
||||
@@ -336,7 +328,7 @@ CHAR16 *xstra_to_path(const CHAR8 *stra) {
|
||||
|
||||
assert(stra);
|
||||
|
||||
len = strlena(stra);
|
||||
len = strlen8((const char *) stra);
|
||||
str = xnew(CHAR16, len + 2);
|
||||
|
||||
str[0] = '\\';
|
||||
@@ -367,18 +359,6 @@ CHAR16 *xstra_to_path(const CHAR8 *stra) {
|
||||
return str;
|
||||
}
|
||||
|
||||
CHAR8 *strchra(const CHAR8 *s, CHAR8 c) {
|
||||
if (!s)
|
||||
return NULL;
|
||||
|
||||
do {
|
||||
if (*s == c)
|
||||
return (CHAR8*) s;
|
||||
} while (*s++);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EFI_STATUS file_read(EFI_FILE *dir, const CHAR16 *name, UINTN off, UINTN size, CHAR8 **ret, UINTN *ret_size) {
|
||||
_cleanup_(file_closep) EFI_FILE *handle = NULL;
|
||||
_cleanup_freepool_ CHAR8 *buf = NULL;
|
||||
@@ -417,7 +397,7 @@ EFI_STATUS file_read(EFI_FILE *dir, const CHAR16 *name, UINTN off, UINTN size, C
|
||||
return err;
|
||||
|
||||
/* Note that handle->Read() changes size to reflect the actually bytes read. */
|
||||
ZeroMem(buf + size, extra);
|
||||
memset(buf + size, 0, extra);
|
||||
|
||||
*ret = TAKE_PTR(buf);
|
||||
if (ret_size)
|
||||
@@ -572,60 +552,6 @@ EFI_STATUS readdir_harder(
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
UINTN strnlena(const CHAR8 *p, UINTN maxlen) {
|
||||
UINTN c;
|
||||
|
||||
if (!p)
|
||||
return 0;
|
||||
|
||||
for (c = 0; c < maxlen; c++)
|
||||
if (p[c] == 0)
|
||||
break;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
INTN strncasecmpa(const CHAR8 *a, const CHAR8 *b, UINTN maxlen) {
|
||||
if (!a || !b)
|
||||
return CMP(a, b);
|
||||
|
||||
while (maxlen > 0) {
|
||||
CHAR8 ca = *a, cb = *b;
|
||||
if (ca >= 'A' && ca <= 'Z')
|
||||
ca += 'a' - 'A';
|
||||
if (cb >= 'A' && cb <= 'Z')
|
||||
cb += 'a' - 'A';
|
||||
if (!ca || ca != cb)
|
||||
return ca - cb;
|
||||
|
||||
a++;
|
||||
b++;
|
||||
maxlen--;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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 = strnlena(p, sz);
|
||||
|
||||
n = xallocate_pool(sz + 1);
|
||||
|
||||
if (sz > 0)
|
||||
CopyMem(n, p, sz);
|
||||
n[sz] = 0;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
BOOLEAN is_ascii(const CHAR16 *f) {
|
||||
if (!f)
|
||||
return FALSE;
|
||||
|
||||
+2
-12
@@ -3,11 +3,10 @@
|
||||
|
||||
#include <efi.h>
|
||||
#include <efilib.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "string-util-fundamental.h"
|
||||
|
||||
#define offsetof(type, member) __builtin_offsetof(type, member)
|
||||
|
||||
#define UINTN_MAX (~(UINTN)0)
|
||||
#define INTN_MAX ((INTN)(UINTN_MAX>>1))
|
||||
#ifndef UINT32_MAX
|
||||
@@ -42,7 +41,6 @@ assert_cc(sizeof(int) == sizeof(UINT32));
|
||||
#define xallocate_zero_pool(size) ASSERT_SE_PTR(AllocateZeroPool(size))
|
||||
#define xreallocate_pool(p, old_size, new_size) ASSERT_SE_PTR(ReallocatePool((p), (old_size), (new_size)))
|
||||
#define xpool_print(fmt, ...) ((CHAR16 *) ASSERT_SE_PTR(PoolPrint((fmt), ##__VA_ARGS__)))
|
||||
#define xstrdup(str) ((CHAR16 *) ASSERT_SE_PTR(StrDuplicate(str)))
|
||||
#define xnew(type, n) xnew_alloc(type, (n), xallocate_pool)
|
||||
#define xnew0(type, n) xnew_alloc(type, (n), xallocate_zero_pool)
|
||||
|
||||
@@ -62,7 +60,6 @@ EFI_STATUS efivar_get_uint32_le(const EFI_GUID *vendor, const CHAR16 *name, UINT
|
||||
EFI_STATUS efivar_get_uint64_le(const EFI_GUID *vendor, const CHAR16 *name, UINT64 *ret);
|
||||
EFI_STATUS efivar_get_boolean_u8(const EFI_GUID *vendor, const CHAR16 *name, BOOLEAN *ret);
|
||||
|
||||
CHAR8 *strchra(const CHAR8 *s, CHAR8 c);
|
||||
CHAR16 *xstra_to_path(const CHAR8 *stra);
|
||||
CHAR16 *xstra_to_str(const CHAR8 *stra);
|
||||
|
||||
@@ -114,20 +111,13 @@ EFI_STATUS log_oom(void);
|
||||
void print_at(UINTN x, UINTN y, UINTN attr, const CHAR16 *str);
|
||||
void clear_screen(UINTN attr);
|
||||
|
||||
typedef INTN (*compare_pointer_func_t)(const void *a, const void *b);
|
||||
typedef int (*compare_pointer_func_t)(const void *a, const void *b);
|
||||
void sort_pointer_array(void **array, UINTN n_members, compare_pointer_func_t compare);
|
||||
|
||||
EFI_STATUS get_file_info_harder(EFI_FILE *handle, EFI_FILE_INFO **ret, UINTN *ret_size);
|
||||
|
||||
EFI_STATUS readdir_harder(EFI_FILE *handle, EFI_FILE_INFO **buffer, UINTN *buffer_size);
|
||||
|
||||
UINTN strnlena(const CHAR8 *p, UINTN maxlen);
|
||||
CHAR8 *xstrndup8(const CHAR8 *p, UINTN sz);
|
||||
INTN strncasecmpa(const CHAR8 *a, const CHAR8 *b, UINTN maxlen);
|
||||
static inline BOOLEAN strncaseeqa(const CHAR8 *a, const CHAR8 *b, UINTN maxlen) {
|
||||
return strncasecmpa(a, b, maxlen) == 0;
|
||||
}
|
||||
|
||||
BOOLEAN is_ascii(const CHAR16 *f);
|
||||
|
||||
CHAR16 **strv_free(CHAR16 **l);
|
||||
|
||||
@@ -19,7 +19,7 @@ static EFI_DEVICE_PATH *path_chop(EFI_DEVICE_PATH *path, EFI_DEVICE_PATH *node)
|
||||
UINTN len = (UINT8 *) node - (UINT8 *) path;
|
||||
EFI_DEVICE_PATH *chopped = xallocate_pool(len + END_DEVICE_PATH_LENGTH);
|
||||
|
||||
CopyMem(chopped, path, len);
|
||||
memcpy(chopped, path, len);
|
||||
SetDevicePathEndNode((EFI_DEVICE_PATH *) ((UINT8 *) chopped + len));
|
||||
|
||||
return chopped;
|
||||
@@ -35,7 +35,7 @@ static BOOLEAN verify_gpt(union GptHeaderBuffer *gpt_header_buffer, EFI_LBA lba_
|
||||
h = &gpt_header_buffer->gpt_header;
|
||||
|
||||
/* Some superficial validation of the GPT header */
|
||||
if (CompareMem(&h->Header.Signature, "EFI PART", sizeof(h->Header.Signature)) != 0)
|
||||
if (memcmp(&h->Header.Signature, "EFI PART", sizeof(h->Header.Signature)) != 0)
|
||||
return FALSE;
|
||||
|
||||
if (h->Header.HeaderSize < 92 || h->Header.HeaderSize > 512)
|
||||
@@ -123,12 +123,12 @@ static EFI_STATUS try_gpt(
|
||||
|
||||
entry = (EFI_PARTITION_ENTRY*) ((UINT8*) entries + gpt.gpt_header.SizeOfPartitionEntry * i);
|
||||
|
||||
if (CompareMem(&entry->PartitionTypeGUID, XBOOTLDR_GUID, sizeof(entry->PartitionTypeGUID)) != 0)
|
||||
if (memcmp(&entry->PartitionTypeGUID, XBOOTLDR_GUID, sizeof(entry->PartitionTypeGUID)) != 0)
|
||||
continue;
|
||||
|
||||
/* Let's use memcpy(), in case the structs are not aligned (they really should be though) */
|
||||
CopyMem(&start, &entry->StartingLBA, sizeof(start));
|
||||
CopyMem(&end, &entry->EndingLBA, sizeof(end));
|
||||
memcpy(&start, &entry->StartingLBA, sizeof(start));
|
||||
memcpy(&end, &entry->EndingLBA, sizeof(end));
|
||||
|
||||
if (end < start) /* Bogus? */
|
||||
continue;
|
||||
@@ -138,7 +138,7 @@ static EFI_STATUS try_gpt(
|
||||
ret_hd->PartitionSize = end - start + 1;
|
||||
ret_hd->MBRType = MBR_TYPE_EFI_PARTITION_TABLE_HEADER;
|
||||
ret_hd->SignatureType = SIGNATURE_TYPE_GUID;
|
||||
CopyMem(ret_hd->Signature, &entry->UniquePartitionGUID, sizeof(ret_hd->Signature));
|
||||
memcpy(ret_hd->Signature, &entry->UniquePartitionGUID, sizeof(ret_hd->Signature));
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
@@ -227,7 +227,7 @@ static EFI_STATUS find_device(EFI_HANDLE *device, EFI_DEVICE_PATH **ret_device_p
|
||||
|
||||
/* Patch in the data we found */
|
||||
EFI_DEVICE_PATH *xboot_path = ASSERT_SE_PTR(DuplicateDevicePath(partition_path));
|
||||
CopyMem((UINT8 *) xboot_path + ((UINT8 *) part_node - (UINT8 *) partition_path), &hd, sizeof(hd));
|
||||
memcpy((UINT8 *) xboot_path + ((UINT8 *) part_node - (UINT8 *) partition_path), &hd, sizeof(hd));
|
||||
*ret_device_path = xboot_path;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -77,7 +77,6 @@
|
||||
#define static_assert _Static_assert
|
||||
#define assert_se(expr) ({ _likely_(expr) ? VOID_0 : efi_assert(#expr, __FILE__, __LINE__, __PRETTY_FUNCTION__); })
|
||||
|
||||
#define memcpy(a, b, c) CopyMem((a), (b), (c))
|
||||
#define free(a) FreePool(a)
|
||||
#endif
|
||||
|
||||
|
||||
@@ -23,8 +23,10 @@
|
||||
|
||||
/* Written by Ulrich Drepper <drepper@redhat.com>, 2007. */
|
||||
|
||||
#ifndef SD_BOOT
|
||||
#include <string.h>
|
||||
#ifdef SD_BOOT
|
||||
# include "efi-string.h"
|
||||
#else
|
||||
# include <string.h>
|
||||
#endif
|
||||
|
||||
#include "macro-fundamental.h"
|
||||
|
||||
@@ -2,31 +2,30 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef SD_BOOT
|
||||
#include <efi.h>
|
||||
#include <efilib.h>
|
||||
# include <efi.h>
|
||||
# include <efilib.h>
|
||||
# include "efi-string.h"
|
||||
#else
|
||||
#include <string.h>
|
||||
# include <string.h>
|
||||
#endif
|
||||
|
||||
#include "macro-fundamental.h"
|
||||
|
||||
#ifdef SD_BOOT
|
||||
#define strlen(a) StrLen((a))
|
||||
#define strcmp(a, b) StrCmp((a), (b))
|
||||
#define strncmp(a, b, n) StrnCmp((a), (b), (n))
|
||||
#define strcasecmp(a, b) StriCmp((a), (b))
|
||||
#define STR_C(str) (L ## str)
|
||||
#define memcmp(a, b, n) CompareMem(a, b, n)
|
||||
# define strlen strlen16
|
||||
# define strcmp strcmp16
|
||||
# define strncmp strncmp16
|
||||
# define strcasecmp strcasecmp16
|
||||
# define strncasecmp strncasecmp16
|
||||
# define STR_C(str) (L ## str)
|
||||
#else
|
||||
#define STR_C(str) (str)
|
||||
# define STR_C(str) (str)
|
||||
#endif
|
||||
|
||||
#define streq(a,b) (strcmp((a),(b)) == 0)
|
||||
#define strneq(a, b, n) (strncmp((a), (b), (n)) == 0)
|
||||
#define strcaseeq(a,b) (strcasecmp((a),(b)) == 0)
|
||||
#ifndef SD_BOOT
|
||||
#define strncaseeq(a, b, n) (strncasecmp((a), (b), (n)) == 0)
|
||||
#endif
|
||||
|
||||
static inline sd_int strcmp_ptr(const sd_char *a, const sd_char *b) {
|
||||
if (a && b)
|
||||
|
||||
Reference in New Issue
Block a user