| // SPDX-License-Identifier: GPL-2.0+ |
| /* |
| * efi_selftest_unicode_collation |
| * |
| * Copyright (c) 2018 Heinrich Schuchardt <xypron.glpk@gmx.de> |
| * |
| * Test unicode collation protocol. |
| */ |
| |
| #include <efi_selftest.h> |
| |
| static const efi_guid_t unicode_collation_protocol_guid = |
| EFI_UNICODE_COLLATION_PROTOCOL2_GUID; |
| |
| static struct efi_boot_services *boottime; |
| |
| static struct efi_unicode_collation_protocol *unicode_collation_protocol; |
| |
| /** |
| * setup() - setup unit test. |
| * |
| * @handle: handle of the loaded image |
| * @systable: system table |
| * ReturnValue: EFI_ST_SUCCESS for success |
| */ |
| static int setup(const efi_handle_t handle, |
| const struct efi_system_table *systable) |
| { |
| efi_status_t ret; |
| |
| boottime = systable->boottime; |
| |
| ret = boottime->locate_protocol(&unicode_collation_protocol_guid, NULL, |
| (void **)&unicode_collation_protocol); |
| if (ret != EFI_SUCCESS) { |
| unicode_collation_protocol = NULL; |
| efi_st_error("Unicode collation protocol is not available.\n"); |
| return EFI_ST_FAILURE; |
| } |
| |
| return EFI_ST_SUCCESS; |
| } |
| |
| static int test_stri_coll(void) |
| { |
| efi_intn_t ret; |
| u16 c1[] = u"first"; |
| u16 c2[] = u"FIRST"; |
| u16 c3[] = u"second"; |
| |
| ret = unicode_collation_protocol->stri_coll(unicode_collation_protocol, |
| c1, c2); |
| if (ret) { |
| efi_st_error( |
| "stri_coll(\"%ps\", \"%ps\") = %d\n", c1, c2, (int)ret); |
| return EFI_ST_FAILURE; |
| } |
| |
| ret = unicode_collation_protocol->stri_coll(unicode_collation_protocol, |
| c1, c3); |
| if (ret >= 0) { |
| efi_st_error( |
| "stri_coll(\"%ps\", \"%ps\") = %d\n", c1, c3, (int)ret); |
| return EFI_ST_FAILURE; |
| } |
| |
| ret = unicode_collation_protocol->stri_coll(unicode_collation_protocol, |
| c3, c1); |
| if (ret <= 0) { |
| efi_st_error( |
| "stri_coll(\"%ps\", \"%ps\") = %d\n", c3, c1, (int)ret); |
| return EFI_ST_FAILURE; |
| } |
| |
| return EFI_ST_SUCCESS; |
| } |
| |
| static int test_metai_match(void) |
| { |
| bool ret; |
| const u16 c[] = u"Das U-Boot"; |
| |
| ret = unicode_collation_protocol->metai_match( |
| unicode_collation_protocol, c, u"*"); |
| if (!ret) { |
| efi_st_error("metai_match returned %u\n", ret); |
| return EFI_ST_FAILURE; |
| } |
| |
| ret = unicode_collation_protocol->metai_match( |
| unicode_collation_protocol, c, u"Da[rstu] U-Boot"); |
| if (!ret) { |
| efi_st_error("metai_match returned %u\n", ret); |
| return EFI_ST_FAILURE; |
| } |
| |
| ret = unicode_collation_protocol->metai_match( |
| unicode_collation_protocol, c, u"Da[q-v] U-Boot"); |
| if (!ret) { |
| efi_st_error("metai_match returned %u\n", ret); |
| return EFI_ST_FAILURE; |
| } |
| |
| ret = unicode_collation_protocol->metai_match( |
| unicode_collation_protocol, c, u"Da? U-Boot"); |
| if (!ret) { |
| efi_st_error("metai_match returned %u\n", ret); |
| return EFI_ST_FAILURE; |
| } |
| |
| ret = unicode_collation_protocol->metai_match( |
| unicode_collation_protocol, c, u"D*Bo*t"); |
| if (!ret) { |
| efi_st_error("metai_match returned %u\n", ret); |
| return EFI_ST_FAILURE; |
| } |
| |
| ret = unicode_collation_protocol->metai_match( |
| unicode_collation_protocol, c, u"Da[xyz] U-Boot"); |
| if (ret) { |
| efi_st_error("metai_match returned %u\n", ret); |
| return EFI_ST_FAILURE; |
| } |
| |
| ret = unicode_collation_protocol->metai_match( |
| unicode_collation_protocol, c, u"Da[a-d] U-Boot"); |
| if (ret) { |
| efi_st_error("metai_match returned %u\n", ret); |
| return EFI_ST_FAILURE; |
| } |
| |
| ret = unicode_collation_protocol->metai_match( |
| unicode_collation_protocol, c, u"Da?? U-Boot"); |
| if (ret) { |
| efi_st_error("metai_match returned %u\n", ret); |
| return EFI_ST_FAILURE; |
| } |
| |
| ret = unicode_collation_protocol->metai_match( |
| unicode_collation_protocol, c, u"D*Bo*tt"); |
| if (ret) { |
| efi_st_error("metai_match returned %u\n", ret); |
| return EFI_ST_FAILURE; |
| } |
| |
| return EFI_ST_SUCCESS; |
| } |
| |
| static int test_str_lwr(void) |
| { |
| u16 c[] = u"U-Boot"; |
| |
| unicode_collation_protocol->str_lwr(unicode_collation_protocol, c); |
| if (efi_st_strcmp_16_8(c, "u-boot")) { |
| efi_st_error("str_lwr returned \"%ps\"\n", c); |
| return EFI_ST_FAILURE; |
| } |
| |
| return EFI_ST_SUCCESS; |
| } |
| |
| static int test_str_upr(void) |
| { |
| u16 c[] = u"U-Boot"; |
| |
| unicode_collation_protocol->str_upr(unicode_collation_protocol, c); |
| if (efi_st_strcmp_16_8(c, "U-BOOT")) { |
| efi_st_error("str_lwr returned \"%ps\"\n", c); |
| return EFI_ST_FAILURE; |
| } |
| |
| return EFI_ST_SUCCESS; |
| } |
| |
| static int test_fat_to_str(void) |
| { |
| u16 str[16]; |
| |
| boottime->set_mem(str, sizeof(str), 0); |
| unicode_collation_protocol->fat_to_str(unicode_collation_protocol, 6, |
| "U-BOOT!", str); |
| if (efi_st_strcmp_16_8(str, "U-BOOT")) { |
| efi_st_error("fat_to_str returned \"%ps\"\n", str); |
| return EFI_ST_FAILURE; |
| } |
| |
| boottime->set_mem(str, sizeof(str), 0); |
| unicode_collation_protocol->fat_to_str(unicode_collation_protocol, 13, |
| "Kafb\240tur\000xyz", str); |
| if (str[10]) { |
| efi_st_error("fat_to_str returned to many characters\n"); |
| return EFI_ST_FAILURE; |
| } |
| if (efi_st_strcmp_16_8(str, "Kafb\341tur")) { |
| efi_st_error("fat_to_str returned \"%ps\"\n", str); |
| return EFI_ST_FAILURE; |
| } |
| |
| return EFI_ST_SUCCESS; |
| } |
| |
| static int test_str_to_fat(void) |
| { |
| char fat[16]; |
| bool ret; |
| |
| boottime->set_mem(fat, sizeof(fat), 0); |
| ret = unicode_collation_protocol->str_to_fat(unicode_collation_protocol, |
| u"U -Boo.t", 6, fat); |
| if (ret || efi_st_strcmp_16_8(u"U-BOOT", fat)) { |
| efi_st_error("str_to_fat returned %u, \"%s\"\n", ret, fat); |
| return EFI_ST_FAILURE; |
| } |
| |
| boottime->set_mem(fat, 16, 0); |
| ret = unicode_collation_protocol->str_to_fat(unicode_collation_protocol, |
| u"U\\Boot", 6, fat); |
| if (!ret || efi_st_strcmp_16_8(u"U_BOOT", fat)) { |
| efi_st_error("str_to_fat returned %u, \"%s\"\n", ret, fat); |
| return EFI_ST_FAILURE; |
| } |
| |
| /* |
| * Test unicode code points which map to CP 437 0x01 - 0x1f are |
| * converted to '_'. |
| */ |
| boottime->set_mem(fat, 16, 0); |
| ret = unicode_collation_protocol->str_to_fat(unicode_collation_protocol, |
| u"\u263a\u2666\u2022\u25d8\u2642\u2194\u00b6\u203c", 8, fat); |
| if (!ret || efi_st_strcmp_16_8(u"________", fat)) { |
| efi_st_error("str_to_fat returned %u, \"%s\"\n", ret, fat); |
| return EFI_ST_FAILURE; |
| } |
| |
| return EFI_ST_SUCCESS; |
| } |
| |
| /** |
| * execute() - Execute unit test. |
| * |
| * ReturnValue: EFI_ST_SUCCESS for success |
| */ |
| static int execute(void) |
| { |
| int ret; |
| |
| if (!unicode_collation_protocol) { |
| efi_st_printf("Unicode collation protocol missing\n"); |
| return EFI_ST_FAILURE; |
| } |
| |
| ret = test_stri_coll(); |
| if (ret != EFI_ST_SUCCESS) |
| return ret; |
| |
| ret = test_metai_match(); |
| if (ret != EFI_ST_SUCCESS) |
| return ret; |
| |
| ret = test_str_lwr(); |
| if (ret != EFI_ST_SUCCESS) |
| return ret; |
| |
| ret = test_str_upr(); |
| if (ret != EFI_ST_SUCCESS) |
| return ret; |
| |
| ret = test_fat_to_str(); |
| if (ret != EFI_ST_SUCCESS) |
| return ret; |
| |
| ret = test_str_to_fat(); |
| if (ret != EFI_ST_SUCCESS) |
| return ret; |
| |
| return EFI_ST_SUCCESS; |
| } |
| |
| EFI_UNIT_TEST(unicoll) = { |
| .name = "unicode collation", |
| .phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT, |
| .execute = execute, |
| .setup = setup, |
| }; |