efi_loader: EFI_UNICODE_COLLATION_PROTOCOL
Subsystems (2)
cover efi_loader: EFI_UNICODE_COLLATION_PROTOCOL
This patchset implements the EFI_UNICODE_COLLATION_PROTOCOL and provides unit tests.
Additionally some errors when handling Unicode strings are fixed.
* possible stack overflow
* incorrect handling of precision attribute in printf()
* incorrect limit on variable length
Some old Unicode functions are replaced.
An error in Unicode handling in the FAT file system shall be fixed after merging Takahiro's FAT patches. Until then some redundancy between old and new Unicode functions remains.
Heinrich Schuchardt (15):
lib: build charset.o only if needed
efi_loader: rename utf16_strlen, utf16_strnlen
lib: charset: utility functions for Unicode
test: unit tests for Unicode functions
lib: vsprintf: correct printing of Unicode strings
test: test printing Unicode
efi_loader: remove limit on variable length
efi_loader: don't use unlimited stack as buffer
efi_loader: buffer size for load options
lib: charset: remove obsolete functions
efi_loader: capitalization table
lib: charset: upper/lower case conversion
test: tests for utf_to_lower() utf_to_upper().
efi_loader: EFI_UNICODE_COLLATION_PROTOCOL
efi_selftest: EFI_UNICODE_COLLATION_PROTOCOL
MAINTAINERS | 4 + cmd/bootefi.c | 6 +- include/capitalization.h | 1909 +++++++++++++++++ include/charset.h | 181 +- include/cp1250.h | 40 + include/cp437.h | 40 + include/efi_api.h | 21 + include/efi_loader.h | 5 + include/test/suites.h | 3 +- lib/Makefile | 5 + lib/charset.c | 359 +++- lib/efi_loader/Makefile | 18 +- lib/efi_loader/efi_bootmgr.c | 2 +- lib/efi_loader/efi_boottime.c | 6 + lib/efi_loader/efi_console.c | 20 +- lib/efi_loader/efi_file.c | 2 +- lib/efi_loader/efi_unicode_collation.c | 218 ++ lib/efi_loader/efi_variable.c | 52 +- lib/efi_selftest/Makefile | 1 + .../efi_selftest_unicode_collation.c | 257 +++ lib/vsprintf.c | 34 +- test/Kconfig | 8 + test/Makefile | 1 + test/cmd_ut.c | 14 +- test/unicode_ut.c | 545 +++++ 25 files changed, 3587 insertions(+), 164 deletions(-) create mode 100644 include/capitalization.h create mode 100644 include/cp1250.h create mode 100644 include/cp437.h create mode 100644 lib/efi_loader/efi_unicode_collation.c create mode 100644 lib/efi_selftest/efi_selftest_unicode_collation.c create mode 100644 test/unicode_ut.c
Signature · 1 line
2.18.0
PATCH 1/15 lib: build charset.o only if needed
charset.o is only needed for the EFI subsystem
--- lib/Makefile | 5 ++++- lib/vsprintf.c | 12 ++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-)
lib/Makefile +4 -1
@@ -19,7 +19,10 @@ obj-$(CONFIG_ARCH_AT91) += at91/ obj-$(CONFIG_OPTEE) += optee/ obj-$(CONFIG_AES) += aes.o -obj-y += charset.o + +ifndef API_BUILD +obj-$(CONFIG_EFI_LOADER) += charset.o +endif obj-$(CONFIG_USB_TTY) += circbuf.o obj-y += crc7.o obj-y += crc8.o
lib/vsprintf.c +8 -4
@@ -274,6 +274,8 @@ static char *string(char *buf, char *end, char *s, int field_width,return buf; } +#if defined(CONFIG_EFI_LOADER ) && \ + !defined(CONFIG_SPL_BUILD ) && !defined(API_BUILD )static char *string16 (char *buf,char *end,u16 *s,int field_width,int precision,int flags) {
@@ -294,8 +296,6 @@ static char *string16(char *buf, char *end, u16 *s, int field_width,return buf; } -#if defined(CONFIG_EFI_LOADER ) && \ - !defined(CONFIG_SPL_BUILD ) && !defined(API_BUILD )static char *device_path_string (char *buf,char *end,void *dp,int field_width,int precision,int flags) {
@@ -612,10 +612,14 @@ repeat:continue ;case 's' : -if (qualifier =='l' && !IS_ENABLED (CONFIG_SPL_BUILD )) { +#if defined(CONFIG_EFI_LOADER ) && \ + !defined(CONFIG_SPL_BUILD ) && !defined(API_BUILD ) +if (qualifier =='l' ) { str = string16(str, end, va_arg(args, u16 *), field_width, precision, flags); - }else { + } else +#endif + { str = string(str, end, va_arg(args, char *), field_width, precision, flags); }
Signature · 1 line
2.18.0
PATCH 1/15 lib: build charset.o only if needed
Quoted 29 lines · Heinrich Schuchardt
charset.o is only needed for the EFI subsystem
Signed-off-by Heinrich Schuchardt <[email protected]>--- lib/Makefile | 5 ++++- lib/vsprintf.c | 12 ++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-)lib/Makefile +4
-1@@ -19,7 +19,10 @@ obj-$(CONFIG_ARCH_AT91) += at91/ obj-$(CONFIG_OPTEE) += optee/ obj-$(CONFIG_AES) += aes.o -obj-y += charset.o + +ifndef API_BUILD +obj-$(CONFIG_EFI_LOADER) += charset.o +endif obj-$(CONFIG_USB_TTY) += circbuf.o obj-y += crc7.o obj-y += crc8.olib/vsprintf.c +0
-0
lib/vsprintf.c static char *string(char *buf, char *end, char *s, int field_width, · line 278
Quoted 5 lines
lib/vsprintf.c +2
-0@@ -274,6 +274,8 @@ static char *string(char *buf, char *end, char *s, int field_width,return buf; } +#if defined(CONFIG_EFI_LOADER ) && \ + !defined(CONFIG_SPL_BUILD ) && !defined(API_BUILD )
I believe you want #if CONFIG_IS_ENABLED(EFI_LOADER) here, right? We probably should move to that at other places where we explicitly check for SPL_BUILD too.
Quoted 13 lines
lib/vsprintf.c +0
-2static char *string16 (char *buf,char *end,u16 *s,int field_width,int precision,int flags) {@@ -294,8 +296,6 @@ static char *string16(char *buf, char *end, u16 *s, int field_width,return buf; } -#if defined(CONFIG_EFI_LOADER ) && \ - !defined(CONFIG_SPL_BUILD ) && !defined(API_BUILD )static char *device_path_string (char *buf,char *end,void *dp,int field_width,int precision,int flags) {
lib/vsprintf.c repeat: · line 616
Quoted 6 lines
lib/vsprintf.c +2
-1@@ -612,10 +612,14 @@ repeat:continue ;case 's' : -if (qualifier =='l' && !IS_ENABLED (CONFIG_SPL_BUILD )) { +#if defined(CONFIG_EFI_LOADER ) && \ + !defined(CONFIG_SPL_BUILD ) && !defined(API_BUILD )
This #if deserves a comment.
Alex
Quoted 11 lines
lib/vsprintf.c +4
-1+if (qualifier =='l' ) { str = string16(str, end, va_arg(args, u16 *), field_width, precision, flags); - }else { + } else +#endif + { str = string(str, end, va_arg(args, char *), field_width, precision, flags); }
PATCH 1/15 lib: build charset.o only if needed
Quoted 35 lines · Alexander Graf
Quoted 32 lines · Heinrich Schuchardt
charset.o is only needed for the EFI subsystem
Signed-off-by Heinrich Schuchardt <[email protected]>--- lib/Makefile | 5 ++++- lib/vsprintf.c | 12 ++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-)lib/Makefile +4
-1@@ -19,7 +19,10 @@ obj-$(CONFIG_ARCH_AT91) += at91/ obj-$(CONFIG_OPTEE) += optee/ obj-$(CONFIG_AES) += aes.o -obj-y += charset.o + +ifndef API_BUILD +obj-$(CONFIG_EFI_LOADER) += charset.o +endif obj-$(CONFIG_USB_TTY) += circbuf.o obj-y += crc7.o obj-y += crc8.olib/vsprintf.c +0
-0@@ -274,6 +274,8 @@ static char *string(char *buf, char *end, char *s, int field_width,return buf; }
Quoted 6 lines
lib/vsprintf.c static char *string(char *buf, char *end, char *s, int field_width, · line 278
Quoted 2 lines
lib/vsprintf.c +2
-0+#if defined(CONFIG_EFI_LOADER ) && \ + !defined(CONFIG_SPL_BUILD ) && !defined(API_BUILD )I believe you want #if
CONFIG_IS_ENABLED(EFI_LOADER)here, right? We probably should move to that at other places where we explicitly check forSPL_BUILDtoo.
Thanks for reviewing
Yes we can use that shorthand notation here. We still have to check API_BUILD.
Quoted 16 lines
Quoted 16 lines
lib/vsprintf.c +0
-2static char *string16 (char *buf,char *end,u16 *s,int field_width,int precision,int flags) {@@ -294,8 +296,6 @@ static char *string16(char *buf, char *end, u16 *s, int field_width,return buf; } -#if defined(CONFIG_EFI_LOADER ) && \ - !defined(CONFIG_SPL_BUILD ) && !defined(API_BUILD )static char *device_path_string (char *buf,char *end,void *dp,int field_width,int precision,int flags) {@@ -612,10 +612,14 @@ repeat:continue ;
Quoted 6 lines
lib/vsprintf.c repeat: · line 616
Quoted 4 lines
lib/vsprintf.c +2
-1case 's' : -if (qualifier =='l' && !IS_ENABLED (CONFIG_SPL_BUILD )) { +#if defined(CONFIG_EFI_LOADER ) && \ + !defined(CONFIG_SPL_BUILD ) && !defined(API_BUILD )This #if deserves a comment.
ok
Best regards
Heinrich
Quoted 16 lines
Alex
Quoted 11 lines
lib/vsprintf.c +4
-1+if (qualifier =='l' ) { str = string16(str, end, va_arg(args, u16 *), field_width, precision, flags); - }else { + } else +#endif + { str = string(str, end, va_arg(args, char *), field_width, precision, flags); }
PATCH 2/15 efi_loader: rename utf16_strlen, utf16_strnlen
In reply to Heinrich SchuchardtThe function names utf16_strlen() and utf16_strnlen() are misnomers. The functions do not count utf-16 characters but non-zero words. So let's rename them to u16_strlen and u16_strnlen().
In utf16_dup() avoid assignment in if clause.
--- include/charset.h | 28 +++++++++++----------------- lib/charset.c | 10 +++++++--- lib/efi_loader/efi_bootmgr.c | 2 +- lib/efi_loader/efi_console.c | 2 +- lib/efi_loader/efi_file.c | 2 +- lib/efi_loader/efi_variable.c | 2 +- lib/vsprintf.c | 2 +- 7 files changed, 23 insertions(+), 25 deletions(-)
include/charset.h +11 -17
@@ -13,29 +13,23 @@#define MAX_UTF8_PER_UTF16 3/** -* utf16_strlen() - Get the length of an utf16 string +* u16_strlen - count non-zero words * -* Returns the number of 16 bit characters in an utf16 string, not -* including the terminating NULL character. -* -* @in the string to measure -* @return the string length +* @in: utf-16 string +* ReturnValue: number of non-zero words. +* This is not the number of utf-16 letters! */ -size_t utf16_strlen (const uint16_t *in); +size_t u16_strlen (const u16 *in);/** -* utf16_strnlen() - Get the length of a fixed-size utf16 string. -* -* Returns the number of 16 bit characters in an utf16 string, -* not including the terminating NULL character, but at most -* 'count' number of characters. In doing this, utf16_strnlen() -* looks at only the first 'count' characters. +* u16_strlen - count non-zero words * -* @in the string to measure -* @count the maximum number of characters to count -* @return the string length, up to a maximum of 'count' +* @in: utf-16 string +* @count: maximum number of words to count +* ReturnValue: number of non-zero words. +* This is not the number of utf-16 letters! */ -size_t utf16_strnlen (const uint16_t *in,size_t count); +size_t u16_strnlen (const u16 *in,size_t count);/** * utf16_strcpy() - UTF16 equivalent of strcpy()
lib/charset.c +7 -3
@@ -12,14 +12,14 @@* utf8/utf16 conversion mostly lifted from grub */ -size_t utf16_strlen (const uint16_t *in) +size_t u16_strlen (const u16 *in) {size_t i;for (i =0 ; in[i]; i++);return i; } -size_t utf16_strnlen (const uint16_t *in,size_t count) +size_t u16_strnlen (const u16 *in,size_t count) {size_t i;for (i =0 ; count-- && in[i]; i++);
@@ -39,7 +39,11 @@ uint16_t *utf16_strcpy(uint16_t *dest, const uint16_t *src)uint16_t *utf16_strdup (const uint16_t *s) {uint16_t *new; -if (!s || !(new =malloc ((utf16_strlen (s) +1 ) *2 ))) + +if (!s) +return NULL ; + new =malloc ((u16_strlen (s) +1 ) *2 ); +if (!new)return NULL ;utf16_strcpy (new, s);return new;
lib/efi_loader/efi_bootmgr.c +1 -1
@@ -60,7 +60,7 @@ static void parse_load_option(struct load_option *lo, void *ptr) ptr +=sizeof (u16); lo->label = ptr; - ptr += (utf16_strlen (lo->label) +1 ) *2 ; + ptr += (u16_strlen (lo->label) +1 ) *2 ; lo->file_path = ptr; ptr += lo->file_path_length;
lib/efi_loader/efi_console.c +1 -1
@@ -114,7 +114,7 @@ static efi_status_t EFIAPI efi_cout_output_string(EFI_ENTRY ("%p, %p" , this, string); -unsigned int n16 =utf16_strlen (string); +unsigned int n16 =u16_strlen (string);char buf[MAX_UTF8_PER_UTF16 * n16 +1 ];u16 *p;
lib/efi_loader/efi_file.c +1 -1
@@ -139,7 +139,7 @@ static struct efi_file_handle *file_open(struct file_system *fs,if (file_name) {utf16_to_utf8 ((u8 *)f0, (u16 *)file_name,1 ); - flen =utf16_strlen ((u16 *)file_name); + flen =u16_strlen ((u16 *)file_name); }/* we could have a parent, but also an absolute path: */
lib/efi_loader/efi_variable.c +1 -1
@@ -106,7 +106,7 @@ static efi_status_t efi_to_native(char *native, u16 *variable_name, {size_t len; - len =utf16_strlen ((u16 *)variable_name); + len =u16_strlen ((u16 *)variable_name);if (len >=MAX_VAR_NAME )return EFI_DEVICE_ERROR ;
lib/vsprintf.c +1 -1
@@ -280,7 +280,7 @@ static char *string16(char *buf, char *end, u16 *s, int field_width, int precision, int flags) {u16 *str = s ? s :L"<NULL>" ; -int utf16_len =utf16_strnlen (str, precision); +int utf16_len =u16_strnlen (str, precision);u8 utf8[utf16_len *MAX_UTF8_PER_UTF16 ];int utf8_len, i;
Signature · 1 line
2.18.0
PATCH 2/15 efi_loader: rename utf16_strlen, utf16_strnlen
Quoted 22 lines · Heinrich Schuchardt
The function names
utf16_strlen()andutf16_strnlen()are misnomers. The functions do not count utf-16 characters but non-zero words. So let's rename them tou16_strlenandu16_strnlen().In
utf16_dup()avoid assignment in if clause.Signed-off-by Heinrich Schuchardt <[email protected]>--- include/charset.h | 28 +++++++++++----------------- lib/charset.c | 10 +++++++--- lib/efi_loader/efi_bootmgr.c | 2 +- lib/efi_loader/efi_console.c | 2 +- lib/efi_loader/efi_file.c | 2 +- lib/efi_loader/efi_variable.c | 2 +- lib/vsprintf.c | 2 +- 7 files changed, 23 insertions(+), 25 deletions(-)include/charset.h +0
-0
include/charset.h line 16
Quoted 5 lines
include/charset.h +1
-1@@ -13,29 +13,23 @@#define MAX_UTF8_PER_UTF16 3/** -* utf16_strlen() - Get the length of an utf16 string +* u16_strlen - count non-zero words
This really just implements wcslen() now, right?
include/charset.h line 18
Quoted 7 lines
include/charset.h +1
-5* -* Returns the number of 16 bit characters in an utf16 string, not -* including the terminating NULL character. -* -* @in the string to measure -* @return the string length +* @in: utf-16 string
Is "in" really a utf-16 string? Probably rather a null-terminated string of words.
Quoted 4 lines
include/charset.h +2
-1+* ReturnValue: number of non-zero words. +* This is not the number of utf-16 letters! */ -size_t utf16_strlen (const uint16_t *in);
include/charset.h line 25
Quoted 10 lines
include/charset.h +2
-6+size_t u16_strlen (const u16 *in);/** -* utf16_strnlen() - Get the length of a fixed-size utf16 string. -* -* Returns the number of 16 bit characters in an utf16 string, -* not including the terminating NULL character, but at most -* 'count' number of characters. In doing this, utf16_strnlen() -* looks at only the first 'count' characters. +* u16_strlen - count non-zero words
This really just implements wcsnlen() now, right?
include/charset.h line 27
Quoted 5 lines
include/charset.h +1
-3* -* @in the string to measure -* @count the maximum number of characters to count -* @return the string length, up to a maximum of 'count' +* @in: utf-16 string
Same comment here.
Alex
PATCH 2/15 efi_loader: rename utf16_strlen, utf16_strnlen
Quoted 41 lines · Alexander Graf
Quoted 22 lines · Heinrich Schuchardt
The function names
utf16_strlen()andutf16_strnlen()are misnomers. The functions do not count utf-16 characters but non-zero words. So let's rename them tou16_strlenandu16_strnlen().In
utf16_dup()avoid assignment in if clause.Signed-off-by Heinrich Schuchardt <[email protected]>--- include/charset.h | 28 +++++++++++----------------- lib/charset.c | 10 +++++++--- lib/efi_loader/efi_bootmgr.c | 2 +- lib/efi_loader/efi_console.c | 2 +- lib/efi_loader/efi_file.c | 2 +- lib/efi_loader/efi_variable.c | 2 +- lib/vsprintf.c | 2 +- 7 files changed, 23 insertions(+), 25 deletions(-)include/charset.h +0
-0include/charset.h line 16
Quoted 5 lines
include/charset.h +1
-1@@ -13,29 +13,23 @@#define MAX_UTF8_PER_UTF16 3/** -* utf16_strlen() - Get the length of an utf16 string +* u16_strlen - count non-zero words This really just implements
wcslen()now, right?include/charset.h line 18
Quoted 7 lines
include/charset.h +1
-5* -* Returns the number of 16 bit characters in an utf16 string, not -* including the terminating NULL character. -* -* @in the string to measure -* @return the string length +* @in: utf-16 string
Quoted 2 lines
Is "in" really a utf-16 string? Probably rather a null-terminated string of words.
I will update the comment.
Quoted 7 lines
Quoted 7 lines
include/charset.h +3
-1+* ReturnValue: number of non-zero words. +* This is not the number of utf-16 letters! */ -size_t utf16_strlen (const uint16_t *in); +size_t u16_strlen (const u16 *in);
Quoted 10 lines
include/charset.h line 25
Quoted 8 lines
include/charset.h +1
-6/** -* utf16_strnlen() - Get the length of a fixed-size utf16 string. -* -* Returns the number of 16 bit characters in an utf16 string, -* not including the terminating NULL character, but at most -* 'count' number of characters. In doing this, utf16_strnlen() -* looks at only the first 'count' characters. +* u16_strlen - count non-zero words This really just implements
wcsnlen()now, right?
Currently we have set wchar size to 16bit using a compiler flag. In my opinion this was not necessary. In C11 we could have use the u"text" notation for utf-8 string constants instead of L"text".
This function really is for u16[] and not for wchar_t[].
I would hesitate to call this function wcsnlen() as the working of wcsnlen() depends on said compiler setting.
Quoted 7 lines
include/charset.h line 27
Quoted 6 lines
include/charset.h +1
-3* -* @in the string to measure -* @count the maximum number of characters to count -* @return the string length, up to a maximum of 'count' +* @in: utf-16 string
Yes u16 string.
Thanks for reviewing.
Heinrich
Quoted 5 lines
Same comment here.
Alex
PATCH 2/15 efi_loader: rename utf16_strlen, utf16_strnlen
Quoted 65 lines · Heinrich Schuchardt
Quoted 41 lines · Alexander Graf
Quoted 22 lines · Heinrich Schuchardt
The function names
utf16_strlen()andutf16_strnlen()are misnomers. The functions do not count utf-16 characters but non-zero words. So let's rename them tou16_strlenandu16_strnlen().In
utf16_dup()avoid assignment in if clause.Signed-off-by Heinrich Schuchardt <[email protected]>--- include/charset.h | 28 +++++++++++----------------- lib/charset.c | 10 +++++++--- lib/efi_loader/efi_bootmgr.c | 2 +- lib/efi_loader/efi_console.c | 2 +- lib/efi_loader/efi_file.c | 2 +- lib/efi_loader/efi_variable.c | 2 +- lib/vsprintf.c | 2 +- 7 files changed, 23 insertions(+), 25 deletions(-)include/charset.h +0
-0include/charset.h line 16
Quoted 5 lines
include/charset.h +1
-1@@ -13,29 +13,23 @@#define MAX_UTF8_PER_UTF16 3/** -* utf16_strlen() - Get the length of an utf16 string +* u16_strlen - count non-zero words This really just implements
wcslen()now, right?include/charset.h line 18
Quoted 7 lines
include/charset.h +1
-5* -* Returns the number of 16 bit characters in an utf16 string, not -* including the terminating NULL character. -* -* @in the string to measure -* @return the string length +* @in: utf-16 string Quoted 2 lines
Is "in" really a utf-16 string? Probably rather a null-terminated string of words.
I will update the comment.
Quoted 7 lines
Quoted 7 lines
include/charset.h +3
-1+* ReturnValue: number of non-zero words. +* This is not the number of utf-16 letters! */ -size_t utf16_strlen (const uint16_t *in); +size_t u16_strlen (const u16 *in);Quoted 10 lines
include/charset.h line 25
Quoted 8 lines
include/charset.h +1
-6/** -* utf16_strnlen() - Get the length of a fixed-size utf16 string. -* -* Returns the number of 16 bit characters in an utf16 string, -* not including the terminating NULL character, but at most -* 'count' number of characters. In doing this, utf16_strnlen() -* looks at only the first 'count' characters. +* u16_strlen - count non-zero words This really just implements
wcsnlen()now, right?
Quoted 3 lines
Currently we have set wchar size to 16bit using a compiler flag. In my opinion this was not necessary. In C11 we could have use the u"text" notation for utf-8 string constants instead of L"text".
I thought the idea was to get utf-16 string constants?
Quoted 5 lines
This function really is for u16[] and not for wchar_t[].
I would hesitate to call this function
wcsnlen()as the working ofwcsnlen()depends on said compiler setting.
*shrug* either way works for me. By calling them their official names we could've potentially given gcc the chance to optimize/inline them better.
Alex
PATCH 2/15 efi_loader: rename utf16_strlen, utf16_strnlen
Quoted 68 lines · Alexander Graf
Quoted 65 lines · Heinrich Schuchardt
Quoted 41 lines · Alexander Graf
Quoted 22 lines · Heinrich Schuchardt
The function names
utf16_strlen()andutf16_strnlen()are misnomers. The functions do not count utf-16 characters but non-zero words. So let's rename them tou16_strlenandu16_strnlen().In
utf16_dup()avoid assignment in if clause.Signed-off-by Heinrich Schuchardt <[email protected]>--- include/charset.h | 28 +++++++++++----------------- lib/charset.c | 10 +++++++--- lib/efi_loader/efi_bootmgr.c | 2 +- lib/efi_loader/efi_console.c | 2 +- lib/efi_loader/efi_file.c | 2 +- lib/efi_loader/efi_variable.c | 2 +- lib/vsprintf.c | 2 +- 7 files changed, 23 insertions(+), 25 deletions(-)include/charset.h +0
-0include/charset.h line 16
Quoted 5 lines
include/charset.h +1
-1@@ -13,29 +13,23 @@#define MAX_UTF8_PER_UTF16 3/** -* utf16_strlen() - Get the length of an utf16 string +* u16_strlen - count non-zero words This really just implements
wcslen()now, right?include/charset.h line 18
Quoted 7 lines
include/charset.h +1
-5* -* Returns the number of 16 bit characters in an utf16 string, not -* including the terminating NULL character. -* -* @in the string to measure -* @return the string length +* @in: utf-16 string Quoted 2 lines
Is "in" really a utf-16 string? Probably rather a null-terminated string of words.
I will update the comment.
Quoted 17 lines
Quoted 5 lines
include/charset.h +2
-1+* ReturnValue: number of non-zero words. +* This is not the number of utf-16 letters! */ -size_t utf16_strlen (const uint16_t *in);include/charset.h line 25
Quoted 10 lines
include/charset.h +2
-6+size_t u16_strlen (const u16 *in);/** -* utf16_strnlen() - Get the length of a fixed-size utf16 string. -* -* Returns the number of 16 bit characters in an utf16 string, -* not including the terminating NULL character, but at most -* 'count' number of characters. In doing this, utf16_strnlen() -* looks at only the first 'count' characters. +* u16_strlen - count non-zero words This really just implements
wcsnlen()now, right?
Quoted 5 lines
Quoted 3 lines
Currently we have set wchar size to 16bit using a compiler flag. In my opinion this was not necessary. In C11 we could have use the u"text" notation for utf-8 string constants instead of L"text".
I thought the idea was to get utf-16 string constants?
Yes, but the C11 way is not using a compiler flag but using the right prefix (which was not available with C99). So once we do not have to support outdated gcc versions anymore we could get rid of the compiler flag.
Quoted 9 lines
Quoted 6 lines
This function really is for u16[] and not for wchar_t[].
I would hesitate to call this function
wcsnlen()as the working ofwcsnlen()depends on said compiler setting.*shrug* either way works for me. By calling them their official names we could've potentially given gcc the chance to optimize/inline them better.
Do have any hint that gcc really provides better compilation results based on the function name?
From what I see in the gcc code only the address sanitizer is aware that wcsnlen() is accessing a memory range.
Best regards
Heinrich
Quoted 4 lines
Alex
PATCH 2/15 efi_loader: rename utf16_strlen, utf16_strnlen
Quoted 73 lines · Heinrich Schuchardt
Quoted 72 lines · Alexander Graf
Quoted 68 lines · Heinrich Schuchardt
Quoted 41 lines · Alexander Graf
Quoted 22 lines · Heinrich Schuchardt
The function names
utf16_strlen()andutf16_strnlen()are misnomers. The functions do not count utf-16 characters but non-zero words. So let's rename them tou16_strlenandu16_strnlen().In
utf16_dup()avoid assignment in if clause.Signed-off-by Heinrich Schuchardt <[email protected]>--- include/charset.h | 28 +++++++++++----------------- lib/charset.c | 10 +++++++--- lib/efi_loader/efi_bootmgr.c | 2 +- lib/efi_loader/efi_console.c | 2 +- lib/efi_loader/efi_file.c | 2 +- lib/efi_loader/efi_variable.c | 2 +- lib/vsprintf.c | 2 +- 7 files changed, 23 insertions(+), 25 deletions(-)include/charset.h +0
-0include/charset.h line 16
Quoted 5 lines
include/charset.h +1
-1@@ -13,29 +13,23 @@#define MAX_UTF8_PER_UTF16 3/** -* utf16_strlen() - Get the length of an utf16 string +* u16_strlen - count non-zero words This really just implements
wcslen()now, right?include/charset.h line 18
Quoted 7 lines
include/charset.h +1
-5* -* Returns the number of 16 bit characters in an utf16 string, not -* including the terminating NULL character. -* -* @in the string to measure -* @return the string length +* @in: utf-16 string Quoted 2 lines
Is "in" really a utf-16 string? Probably rather a null-terminated string of words.
I will update the comment.
Quoted 7 lines
Quoted 7 lines
include/charset.h +3
-1+* ReturnValue: number of non-zero words. +* This is not the number of utf-16 letters! */ -size_t utf16_strlen (const uint16_t *in); +size_t u16_strlen (const u16 *in);Quoted 10 lines
include/charset.h line 25
Quoted 8 lines
include/charset.h +1
-6/** -* utf16_strnlen() - Get the length of a fixed-size utf16 string. -* -* Returns the number of 16 bit characters in an utf16 string, -* not including the terminating NULL character, but at most -* 'count' number of characters. In doing this, utf16_strnlen() -* looks at only the first 'count' characters. +* u16_strlen - count non-zero words This really just implements
wcsnlen()now, right?Currently we have set wchar size to 16bit using a compiler flag. In my opinion this was not necessary. In C11 we could have use the u"text" notation for utf-8 string constants instead of L"text".
Quoted 5 lines
Quoted 1 line
I thought the idea was to get utf-16 string constants?
Yes, but the C11 way is not using a compiler flag but using the right prefix (which was not available with C99). So once we do not have to support outdated gcc versions anymore we could get rid of the compiler flag.
I think we are in agreement, I just wanted to point out that u"text" creates a utf-16 string rather than a utf-8 one :).
Unfortunately I don't know when we can bump the compiler requirement, but it can't be forever and we should keep it in mind, I agree.
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
This function really is for u16[] and not for wchar_t[].
Quoted 8 lines
Quoted 5 lines
Quoted 2 lines
I would hesitate to call this function
wcsnlen()as the working ofwcsnlen()depends on said compiler setting.*shrug* either way works for me. By calling them their official names we could've potentially given gcc the chance to optimize/inline them better.
Do have any hint that gcc really provides better compilation results based on the function name?
I seem to recall that gcc at least allowed for strcpy() and friends to get inlined. The point was really more about using function names that do exactly what people are used to.
I don't have a terribly string feeling towards it though, as strlen() is definitely much wider used than wcslen() and thus much more well known.
Alex
PATCH 3/15 lib: charset: utility functions for Unicode
In reply to Heinrich Schuchardtutf8_get() - get next UTF-8 code point from bufferutf8_put() - write UTF-8 code point to buffer utf8_utf16_strnlen() - length of a utf-8 string after conversion to utf-16 utf8_utf16_strncpy() - copy a utf-8 string to utf-16 utf16_get() - get next UTF-16 code point from buffer utf16_put() - write UTF-16 code point to buffer utf16_utf8_strnlen() - length of a utf-16 string after conversion to utf-8 utf16_utf8_strncpy() - copy a utf-16 string to utf-8
--- include/charset.h | 130 +++++++++++++++++++++++++ lib/Makefile | 4 +- lib/charset.c | 243 +++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 373 insertions(+), 4 deletions(-)
include/charset.h +130 -0
@@ -8,10 +8,140 @@#ifndef __CHARSET_H_#define __CHARSET_H_ +#include <linux/kernel.h> #include <linux/types.h> #define MAX_UTF8_PER_UTF16 3 +/** +* utf8_get() - get next UTF-8 code point from buffer +* +* @src: pointer to current byte, updated to point to next byte +* Return: code point, or 0 for end of string, or -1 if no legal +* code point is found. In case of an error src points to +* the incorrect byte. +*/ +s32 utf8_get (const char **src); + +/** +* utf8_put() - write UTF-8 code point to buffer +* +* @code: code point +* @dst: pointer to destination buffer, updated to next position +* Return: -1 if the input parameters are invalid +*/ +int utf8_put (s32 code,char **dst); + +/** +* utf8_utf16_strnlen() - length of a truncated utf-8 string after conversion +* to utf-16 +* +* @src: utf-8 string +* @count: maximum number of code points to convert +* Return: length in bytes after conversion to utf-16 without the +* trailing \0. If an invalid UTF-8 sequence is hit one +* word will be reserved for a replacement character. +*/ +size_t utf8_utf16_strnlen (const char *src,size_t count); + +/** +* utf8_utf16_strlen() - length of a utf-8 string after conversion to utf-16 +* +* @src: utf-8 string +* Return: length in bytes after conversion to utf-16 without the +* trailing \0. -1 if the utf-8 string is not valid. +*/ +#define utf8_utf16_strlen (a) utf8_utf16_strnlen((a), SIZE_MAX) + +/** +* utf8_utf16_strncpy() - copy utf-8 string to utf-16 string +* +* @dst: destination buffer +* @src: source buffer +* @count: maximum number of code points to copy +* Return: -1 if the input parameters are invalid +*/ +int utf8_utf16_strncpy (u16 **dst,const char *src,size_t count); + +/** +* utf8_utf16_strcpy() - copy utf-8 string to utf-16 string +* +* @dst: destination buffer +* @src: source buffer +* Return: -1 if the input parameters are invalid +*/ +#define utf8_utf16_strcpy (d, s) utf8_utf16_strncpy((d), (s), SIZE_MAX) + +/** +* utf16_get() - get next UTF-16 code point from buffer +* +* @src: pointer to current word, updated to point to next word +* Return: code point, or 0 for end of string, or -1 if no legal +* code point is found. In case of an error src points to +* the incorrect word. +*/ +s32 utf16_get (const u16 **src); + +/** +* utf16_put() - write UTF-16 code point to buffer +* +* @code: code point +* @dst: pointer to destination buffer, updated to next position +* Return: -1 if the input parameters are invalid +*/ +int utf16_put (s32 code,u16 **dst); + +/** +* utf16_strnlen() - length of a truncated utf-16 string +* +* @src: utf-16 string +* @count: maximum number of code points to convert +* Return: length in code points. If an invalid UTF-16 sequence is +* hit one position will be reserved for a replacement +* character. +*/ +size_t utf16_strnlen (const u16 *src,size_t count); + +/** +* utf16_utf8_strnlen() - length of a truncated utf-16 string after conversion +* to utf-8 +* +* @src: utf-16 string +* @count: maximum number of code points to convert +* Return: length in bytes after conversion to utf-8 without the +* trailing \0. If an invalid UTF-16 sequence is hit one +* byte will be reserved for a replacement character. +*/ +size_t utf16_utf8_strnlen (const u16 *src,size_t count); + +/** +* utf16_utf8_strlen() - length of a utf-16 string after conversion to utf-8 +* +* @src: utf-16 string +* Return: length in bytes after conversion to utf-8 without the +* trailing \0. -1 if the utf-16 string is not valid. +*/ +#define utf16_utf8_strlen (a) utf16_utf8_strnlen((a), SIZE_MAX) + +/** +* utf16_utf8_strncpy() - copy utf-16 string to utf-8 string +* +* @dst: destination buffer +* @src: source buffer +* @count: maximum number of code points to copy +* Return: -1 if the input parameters are invalid +*/ +int utf16_utf8_strncpy (char **dst,const u16 *src,size_t count); + +/** +* utf16_utf8_strcpy() - copy utf-16 string to utf-8 string +* +* @dst: destination buffer +* @src: source buffer +* Return: -1 if the input parameters are invalid +*/ +#define utf16_utf8_strcpy (d, s) utf16_utf8_strncpy((d), (s), SIZE_MAX) +/** * u16_strlen - count non-zero words *
lib/Makefile +3 -1
@@ -21,7 +21,9 @@ obj-$(CONFIG_OPTEE) += optee/ obj-$(CONFIG_AES) += aes.o ifndef API_BUILD -obj-$(CONFIG_EFI_LOADER) += charset.o +ifneq ($(CONFIG_UT_UNICODE)$(CONFIG_EFI_LOADER),) +obj-y += charset.o +endif endif obj-$(CONFIG_USB_TTY) += circbuf.o obj-y += crc7.o
lib/charset.c +240 -3
249 lines not on this page · raw message
Signature · 1 line
2.18.0
PATCH 3/15 lib: charset: utility functions for Unicode
Quoted 10 lines · Heinrich Schuchardt
utf8_get()- get next UTF-8 code point from bufferutf8_put()- write UTF-8 code point to bufferutf8_utf16_strnlen()- length of a utf-8 string after conversion to utf-16utf8_utf16_strncpy()- copy a utf-8 string to utf-16utf16_get()- get next UTF-16 code point from bufferutf16_put()- write UTF-16 code point to bufferutf16_utf8_strnlen()- length of a utf-16 string after conversion to utf-8utf16_utf8_strncpy()- copy a utf-16 string to utf-8Signed-off-by Heinrich Schuchardt <[email protected]>
I can't promise that all the conversion logic is correct though ;).
Alex
PATCH 4/15 test: unit tests for Unicode functions
In reply to Heinrich SchuchardtProvide unit tests for Unicode functions.
--- MAINTAINERS | 1 + include/test/suites.h | 3 +- test/Kconfig | 8 + test/Makefile | 1 + test/cmd_ut.c | 14 +- test/unicode_ut.c | 470 ++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 493 insertions(+), 4 deletions(-) create mode 100644 test/unicode_ut.c
MAINTAINERS +1 -0
@@ -374,6 +374,7 @@ F: include/asm-generic/pe.h F: lib/charset.c F: lib/efi*/ F: test/py/tests/test_efi* +F: test/unicode_ut.c F: cmd/bootefi.c F: tools/file2include.c
include/test/suites.h +2 -1
@@ -23,10 +23,11 @@ struct unit_test;int cmd_ut_category (const char *name,struct unit_test *tests,int n_ents,int argc,char *const argv[]); +int do_ut_compression (cmd_tbl_t *cmdtp,int flag,int argc,char *const argv[]);int do_ut_dm (cmd_tbl_t *cmdtp,int flag,int argc,char *const argv[]);int do_ut_env (cmd_tbl_t *cmdtp,int flag,int argc,char *const argv[]);int do_ut_overlay (cmd_tbl_t *cmdtp,int flag,int argc,char *const argv[]);int do_ut_time (cmd_tbl_t *cmdtp,int flag,int argc,char *const argv[]); -int do_ut_compression (cmd_tbl_t *cmdtp,int flag,int argc,char *const argv[]); +int do_ut_unicode (cmd_tbl_t *cmdtp,int flag,int argc,char *const argv[]);#endif /* __TEST_SUITES_H__ */
test/Kconfig +8 -0
@@ -15,6 +15,14 @@ config UT_TIME problems. But if you are having problems with udelay() and the like, this is a good place to start. +config UT_UNICODE + bool "Unit tests for Unicode functions" + depends on UNIT_TEST + default y + help + Enables the 'ut unicode' command which tests that the functions for + manipulating Unicode strings work correctly. + source "test/dm/Kconfig" source "test/env/Kconfig" source "test/overlay/Kconfig"
test/Makefile +1 -0
@@ -8,4 +8,5 @@ obj-$(CONFIG_SANDBOX) += command_ut.o obj-$(CONFIG_SANDBOX) += compression.o obj-$(CONFIG_SANDBOX) += print_ut.o obj-$(CONFIG_UT_TIME) += time_ut.o +obj-$(CONFIG_UT_UNICODE) += unicode_ut.o obj-$(CONFIG_$(SPL_)LOG) += log/
test/cmd_ut.c +11 -3
@@ -49,6 +49,10 @@ static cmd_tbl_t cmd_ut_sub[] = {#ifdef CONFIG_UT_TIME U_BOOT_CMD_MKENT(time, CONFIG_SYS_MAXARGS, 1, do_ut_time, "", ""),#endif +#if defined(CONFIG_UT_UNICODE ) && \ + !defined(CONFIG_SPL_BUILD ) && !defined(API_BUILD ) + U_BOOT_CMD_MKENT(unicode, CONFIG_SYS_MAXARGS, 1, do_ut_unicode, "", ""), +#endif #ifdef CONFIG_SANDBOX U_BOOT_CMD_MKENT (compression,CONFIG_SYS_MAXARGS ,1 , do_ut_compression, "", ""),
@@ -93,6 +97,9 @@ static int do_ut(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])#ifdef CONFIG_SYS_LONGHELP static char ut_help_text[] ="all - execute all enabled tests\n" +#ifdef CONFIG_SANDBOX + "ut compression - Test compressors and bootm decompression\n" +#endif #ifdef CONFIG_UT_DM "ut dm [test-name]\n" #endif
@@ -105,11 +112,12 @@ static char ut_help_text[] =#ifdef CONFIG_UT_TIME "ut time - Very basic test of time functions\n"#endif -#ifdef CONFIG_SANDBOX -"ut compression - Test compressors and bootm decompression\n" +#if defined(CONFIG_UT_UNICODE ) && \ + !defined(CONFIG_SPL_BUILD ) && !defined(API_BUILD ) +"ut unicode - test Unicode functions\n" #endif ; -#endif +#endif /* CONFIG_SYS_LONGHELP */ U_BOOT_CMD( ut, CONFIG_SYS_MAXARGS, 1, do_ut,
test/unicode_ut.c new file +470 -0
470 lines not on this page · raw message
Signature · 1 line
2.18.0
PATCH 4/15 test: unit tests for Unicode functions
Quoted 47 lines · Heinrich Schuchardt
Provide unit tests for Unicode functions.
Signed-off-by Heinrich Schuchardt <[email protected]>--- MAINTAINERS | 1 + include/test/suites.h | 3 +- test/Kconfig | 8 + test/Makefile | 1 + test/cmd_ut.c | 14 +- test/unicode_ut.c | 470 ++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 493 insertions(+), 4 deletions(-) create mode 100644 test/unicode_ut.cMAINTAINERS +1
-0@@ -374,6 +374,7 @@ F: include/asm-generic/pe.h F: lib/charset.c F: lib/efi*/ F: test/py/tests/test_efi* +F: test/unicode_ut.c F: cmd/bootefi.c F: tools/file2include.cinclude/test/suites.h +2
-1@@ -23,10 +23,11 @@ struct unit_test;int cmd_ut_category (const char *name,struct unit_test *tests,int n_ents,int argc,char *const argv[]); +int do_ut_compression (cmd_tbl_t *cmdtp,int flag,int argc,char *const argv[]);int do_ut_dm (cmd_tbl_t *cmdtp,int flag,int argc,char *const argv[]);int do_ut_env (cmd_tbl_t *cmdtp,int flag,int argc,char *const argv[]);int do_ut_overlay (cmd_tbl_t *cmdtp,int flag,int argc,char *const argv[]);int do_ut_time (cmd_tbl_t *cmdtp,int flag,int argc,char *const argv[]); -int do_ut_compression (cmd_tbl_t *cmdtp,int flag,int argc,char *const argv[]); +int do_ut_unicode (cmd_tbl_t *cmdtp,int flag,int argc,char *const argv[]);#endif /* __TEST_SUITES_H__ */ test/Kconfig +0
-0
test/Kconfig config UT_TIME · line 18
Quoted 4 lines
test/Kconfig +1
-0@@ -15,6 +15,14 @@ config UT_TIME problems. But if you are having problems with udelay() and the like, this is a good place to start. +config UT_UNICODE
You probably want to move the hunk that actually builds charset.o with CONFIG_UT_UNICODE set to this patch as well ;).
Quoted 25 lines
test/Kconfig +7
-0+ bool "Unit tests for Unicode functions" + depends on UNIT_TEST + default y + help + Enables the 'ut unicode' command which tests that the functions for + manipulating Unicode strings work correctly. + source "test/dm/Kconfig" source "test/env/Kconfig" source "test/overlay/Kconfig"test/Makefile +1
-0@@ -8,4 +8,5 @@ obj-$(CONFIG_SANDBOX) += command_ut.o obj-$(CONFIG_SANDBOX) += compression.o obj-$(CONFIG_SANDBOX) += print_ut.o obj-$(CONFIG_UT_TIME) += time_ut.o +obj-$(CONFIG_UT_UNICODE) += unicode_ut.o obj-$(CONFIG_$(SPL_)LOG) += log/test/cmd_ut.c +0
-0
test/cmd_ut.c static cmd_tbl_t cmd_ut_sub[] = { · line 53
Quoted 5 lines
test/cmd_ut.c +2
-0@@ -49,6 +49,10 @@ static cmd_tbl_t cmd_ut_sub[] = {#ifdef CONFIG_UT_TIME U_BOOT_CMD_MKENT(time, CONFIG_SYS_MAXARGS, 1, do_ut_time, "", ""),#endif +#if defined(CONFIG_UT_UNICODE ) && \ + !defined(CONFIG_SPL_BUILD ) && !defined(API_BUILD )
CONFIG_IS_ENABLED()
Alex
PATCH 4/15 test: unit tests for Unicode functions
Quoted 53 lines · Alexander Graf
Quoted 50 lines · Heinrich Schuchardt
Provide unit tests for Unicode functions.
Signed-off-by Heinrich Schuchardt <[email protected]>--- MAINTAINERS | 1 + include/test/suites.h | 3 +- test/Kconfig | 8 + test/Makefile | 1 + test/cmd_ut.c | 14 +- test/unicode_ut.c | 470 ++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 493 insertions(+), 4 deletions(-) create mode 100644 test/unicode_ut.cMAINTAINERS +1
-0@@ -374,6 +374,7 @@ F: include/asm-generic/pe.h F: lib/charset.c F: lib/efi*/ F: test/py/tests/test_efi* +F: test/unicode_ut.c F: cmd/bootefi.c F: tools/file2include.cinclude/test/suites.h +2
-1@@ -23,10 +23,11 @@ struct unit_test;int cmd_ut_category (const char *name,struct unit_test *tests,int n_ents,int argc,char *const argv[]); +int do_ut_compression (cmd_tbl_t *cmdtp,int flag,int argc,char *const argv[]);int do_ut_dm (cmd_tbl_t *cmdtp,int flag,int argc,char *const argv[]);int do_ut_env (cmd_tbl_t *cmdtp,int flag,int argc,char *const argv[]);int do_ut_overlay (cmd_tbl_t *cmdtp,int flag,int argc,char *const argv[]);int do_ut_time (cmd_tbl_t *cmdtp,int flag,int argc,char *const argv[]); -int do_ut_compression (cmd_tbl_t *cmdtp,int flag,int argc,char *const argv[]); +int do_ut_unicode (cmd_tbl_t *cmdtp,int flag,int argc,char *const argv[]);#endif /* __TEST_SUITES_H__ */ test/Kconfig +0
-0@@ -15,6 +15,14 @@ config UT_TIME problems. But if you are having problems with udelay() and the like, this is a good place to start.
Quoted 4 lines
test/Kconfig config UT_TIME · line 18
Quoted 1 line
test/Kconfig +1
-0+config UT_UNICODEYou probably want to move the hunk that actually builds charset.o with
CONFIG_UT_UNICODEset to this patch as well ;).
Yes there is a bit in patch "lib: charset: utility functions for Unicode" that could move to this patch.
Quoted 25 lines
Quoted 25 lines
test/Kconfig +7
-0+ bool "Unit tests for Unicode functions" + depends on UNIT_TEST + default y + help + Enables the 'ut unicode' command which tests that the functions for + manipulating Unicode strings work correctly. + source "test/dm/Kconfig" source "test/env/Kconfig" source "test/overlay/Kconfig"test/Makefile +1
-0@@ -8,4 +8,5 @@ obj-$(CONFIG_SANDBOX) += command_ut.o obj-$(CONFIG_SANDBOX) += compression.o obj-$(CONFIG_SANDBOX) += print_ut.o obj-$(CONFIG_UT_TIME) += time_ut.o +obj-$(CONFIG_UT_UNICODE) += unicode_ut.o obj-$(CONFIG_$(SPL_)LOG) += log/test/cmd_ut.c +0
-0
Quoted 8 lines
test/cmd_ut.c static cmd_tbl_t cmd_ut_sub[] = { · line 53
Quoted 6 lines
test/cmd_ut.c +2
-0@@ -49,6 +49,10 @@ static cmd_tbl_t cmd_ut_sub[] = {#ifdef CONFIG_UT_TIME U_BOOT_CMD_MKENT(time, CONFIG_SYS_MAXARGS, 1, do_ut_time, "", ""),#endif +#if defined(CONFIG_UT_UNICODE ) && \ + !defined(CONFIG_SPL_BUILD ) && !defined(API_BUILD )
CONFIG_IS_ENABLED()
ok
Heinrich.
Quoted 3 lines
Alex
PATCH 5/15 lib: vsprintf: correct printing of Unicode strings
In reply to Heinrich SchuchardtThe width and precision of the printf() function refer to the number of characters not to the number of bytes printed.
--- lib/vsprintf.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-)
lib/vsprintf.c +13 -9
@@ -280,18 +280,22 @@ static char *string16(char *buf, char *end, u16 *s, int field_width, int precision, int flags) {u16 *str = s ? s :L"<NULL>" ; -int utf16_len =u16_strnlen (str, precision); -u8 utf8[utf16_len *MAX_UTF8_PER_UTF16 ]; -int utf8_len, i; - - utf8_len =utf16_to_utf8 (utf8, str, utf16_len) - utf8; +ssize_t i, len =utf16_strnlen (str, precision);if (!(flags &LEFT )) -while (utf8_len < field_width--) +for (; len < field_width; --field_width)ADDCH (buf,' ' ); -for (i =0 ; i < utf8_len; ++i) -ADDCH (buf, utf8[i]); -while (utf8_len < field_width--) +for (i =0 ; i < len; ++i) { +s32 code =utf16_get ((const u16 **)&str); + +if (code <0 ) { + code ='?' ; +if (*str) + ++str; + } +utf8_put (code, &buf); + } +for (; i < field_width; --field_width)ADDCH (buf,' ' );return buf; }
Signature · 1 line
2.18.0
PATCH 5/15 lib: vsprintf: correct printing of Unicode strings
Quoted 29 lines · Heinrich Schuchardt
The width and precision of the
printf()function refer to the number of characters not to the number of bytes printed.Signed-off-by Heinrich Schuchardt <[email protected]>--- lib/vsprintf.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-)lib/vsprintf.c +2
-8@@ -280,18 +280,22 @@ static char *string16(char *buf, char *end, u16 *s, int field_width, int precision, int flags) {u16 *str = s ? s :L"<NULL>" ; -int utf16_len =u16_strnlen (str, precision); -u8 utf8[utf16_len *MAX_UTF8_PER_UTF16 ]; -int utf8_len, i; - - utf8_len =utf16_to_utf8 (utf8, str, utf16_len) - utf8; +ssize_t i, len =utf16_strnlen (str, precision);if (!(flags &LEFT )) -while (utf8_len < field_width--) +for (; len < field_width; --field_width)ADDCH (buf,' ' ); -for (i =0 ; i < utf8_len; ++i) -ADDCH (buf, utf8[i]);
lib/vsprintf.c static char *string16(char *buf, char *end, u16 *s, int field_width, · line 296
Quoted 10 lines
lib/vsprintf.c +9
-1-while (utf8_len < field_width--) +for (i =0 ; i < len; ++i) { +s32 code =utf16_get ((const u16 **)&str); + +if (code <0 ) { + code ='?' ; +if (*str) + ++str; + } +utf8_put (code, &buf);
Can you introduce or reuse a strcpy() helper in charset.c for this? That way the compiler has the chance to inline utf16_get() and utf8_put() and make the function fast.
Alex
PATCH 5/15 lib: vsprintf: correct printing of Unicode strings
Quoted 38 lines · Alexander Graf
Quoted 35 lines · Heinrich Schuchardt
The width and precision of the
printf()function refer to the number of characters not to the number of bytes printed.Signed-off-by Heinrich Schuchardt <[email protected]>--- lib/vsprintf.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-)lib/vsprintf.c +7
-9@@ -280,18 +280,22 @@ static char *string16(char *buf, char *end, u16 *s, int field_width, int precision, int flags) {u16 *str = s ? s :L"<NULL>" ; -int utf16_len =u16_strnlen (str, precision); -u8 utf8[utf16_len *MAX_UTF8_PER_UTF16 ]; -int utf8_len, i; - - utf8_len =utf16_to_utf8 (utf8, str, utf16_len) - utf8; +ssize_t i, len =utf16_strnlen (str, precision);if (!(flags &LEFT )) -while (utf8_len < field_width--) +for (; len < field_width; --field_width)ADDCH (buf,' ' ); -for (i =0 ; i < utf8_len; ++i) -ADDCH (buf, utf8[i]); -while (utf8_len < field_width--) +for (i =0 ; i < len; ++i) { +s32 code =utf16_get ((const u16 **)&str); + +if (code <0 ) { + code ='?' ;
Quoted 8 lines
lib/vsprintf.c static char *string16(char *buf, char *end, u16 *s, int field_width, · line 296
Quoted 4 lines
lib/vsprintf.c +4
-0+if (*str) + ++str; + } +utf8_put (code, &buf);Can you introduce or reuse a
strcpy()helper incharset.cfor this? That way the compiler has the chance to inlineutf16_get()andutf8_put()and make the function fast.
strcpy() works on bytes not on multi-byte utf-8 characters. So it is unclear to me how I should make use of strcpy() here.
Of cause we could define utf8_put() and utf8_get() as inline function. But that would increase code size. Is this what you would prefer? I would guess that the serial interface is always the slowest part of text output anyway.
Regards
Heinrich
Quoted 4 lines
Alex
PATCH 5/15 lib: vsprintf: correct printing of Unicode strings
Quoted 48 lines · Heinrich Schuchardt
Quoted 38 lines · Alexander Graf
Quoted 35 lines · Heinrich Schuchardt
The width and precision of the
printf()function refer to the number of characters not to the number of bytes printed.Signed-off-by Heinrich Schuchardt <[email protected]>--- lib/vsprintf.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-)lib/vsprintf.c +7
-9@@ -280,18 +280,22 @@ static char *string16(char *buf, char *end, u16 *s, int field_width, int precision, int flags) {u16 *str = s ? s :L"<NULL>" ; -int utf16_len =u16_strnlen (str, precision); -u8 utf8[utf16_len *MAX_UTF8_PER_UTF16 ]; -int utf8_len, i; - - utf8_len =utf16_to_utf8 (utf8, str, utf16_len) - utf8; +ssize_t i, len =utf16_strnlen (str, precision);if (!(flags &LEFT )) -while (utf8_len < field_width--) +for (; len < field_width; --field_width)ADDCH (buf,' ' ); -for (i =0 ; i < utf8_len; ++i) -ADDCH (buf, utf8[i]); -while (utf8_len < field_width--) +for (i =0 ; i < len; ++i) { +s32 code =utf16_get ((const u16 **)&str); + +if (code <0 ) { + code ='?' ;Quoted 8 lines
lib/vsprintf.c static char *string16(char *buf, char *end, u16 *s, int field_width, · line 296
Quoted 4 lines
lib/vsprintf.c +4
-0+if (*str) + ++str; + } +utf8_put (code, &buf);Can you introduce or reuse a
strcpy()helper incharset.cfor this? That way the compiler has the chance to inlineutf16_get()andutf8_put()and make the function fast.
Quoted 2 lines
strcpy()works on bytes not on multi-byte utf-8 characters. So it is unclear to me how I should make use ofstrcpy()here.
What I was trying to imply is that what you're doing here is very similar to utf8_utf16_strncpy(). Maybe we can reuse the same function or at least something very similar.
Quoted 4 lines
Of cause we could define
utf8_put()andutf8_get()as inline function. But that would increase code size. Is this what you would prefer? I would guess that the serial interface is always the slowest part of text output anyway.
Real serial output is definitely orders of magnitude slower, I agree. But if we can make the code easier to read along the way I'm all for it ;).
I think what it boils down to is that I'd prefer if we keep utf{8,16}_{get,put}() as local to charset.c as we can and instead put slightly higher level wrappers around them, like you did for pretty much everything else.
Alex
PATCH 6/15 test: test printing Unicode
In reply to Heinrich SchuchardtTest printing of Unicode strings
--- test/unicode_ut.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+)
test/unicode_ut.c +37 -0
@@ -34,6 +34,42 @@ static const char d3[] = {0xe6, 0xbd, 0x9c, 0xe6, 0xb0, 0xb4, 0xe8, 0x89,static const char d4[] = {0xf0 ,0x90 ,0x92 ,0x8d ,0xf0 ,0x90 ,0x92 ,0x96 ,0xf0 ,0x90 ,0x92 ,0x87 ,0x00 }; +static int ut_string16 (void ) +{ +#if defined(CONFIG_EFI_LOADER ) && \ + !defined(CONFIG_SPL_BUILD ) && !defined(API_BUILD ) +char buf[20 ]; + +memset (buf,0xff ,sizeof (buf)); +sprintf (buf,"%8.6ls" , c2); +if (buf[1 ] !=' ' ) +return -1 ; +if (strncmp (&buf[2 ], d2,7 )) +return -1 ; +if (buf[9 ]) +return -1 ; + +memset (buf,0xff ,sizeof (buf)); +sprintf (buf,"%8.6ls" , c4); +if (buf[4 ] !=' ' ) +return -1 ; +if (strncmp (&buf[5 ], d4,12 )) +return -1 ; +if (buf[17 ]) +return -1 ; + +memset (buf,0xff ,sizeof (buf)); +sprintf (buf,"%-8.2ls" , c4); +if (strncmp (buf, d4,8 )) +return -1 ; +if (buf[8 ] !=' ' ) +return -1 ; +if (buf[14 ]) +return -1 ; +#endif +return 0 ; +} +static int ut_utf8_get (void ) {const char *s;
@@ -451,6 +487,7 @@ int do_ut_unicode(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) {int ret =0 ; + ret |=ut_string16 (); ret |=ut_utf8_get (); ret |=ut_utf8_put (); ret |=ut_utf8_utf16_strlen ();
Signature · 1 line
2.18.0
PATCH 6/15 test: test printing Unicode
Quoted 38 lines · Heinrich Schuchardt
Test printing of Unicode strings
Signed-off-by Heinrich Schuchardt <[email protected]>--- test/unicode_ut.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+)test/unicode_ut.c +23
-0@@ -34,6 +34,42 @@ static const char d3[] = {0xe6, 0xbd, 0x9c, 0xe6, 0xb0, 0xb4, 0xe8, 0x89,static const char d4[] = {0xf0 ,0x90 ,0x92 ,0x8d ,0xf0 ,0x90 ,0x92 ,0x96 ,0xf0 ,0x90 ,0x92 ,0x87 ,0x00 }; +static int ut_string16 (void ) +{ +#if defined(CONFIG_EFI_LOADER ) && \ + !defined(CONFIG_SPL_BUILD ) && !defined(API_BUILD ) +char buf[20 ]; + +memset (buf,0xff ,sizeof (buf)); +sprintf (buf,"%8.6ls" , c2); +if (buf[1 ] !=' ' ) +return -1 ; +if (strncmp (&buf[2 ], d2,7 )) +return -1 ; +if (buf[9 ]) +return -1 ; + +memset (buf,0xff ,sizeof (buf)); +sprintf (buf,"%8.6ls" , c4); +if (buf[4 ] !=' ' ) +return -1 ; +if (strncmp (&buf[5 ], d4,12 )) +return -1 ; +if (buf[17 ]) +return -1 ;
test/unicode_ut.c static const char d3[] = {0xe6, 0xbd, 0x9c, 0xe6, 0xb0, 0xb4, 0xe8, 0x89, · line 69
Quoted 10 lines
test/unicode_ut.c +10
-0+ +memset (buf,0xff ,sizeof (buf)); +sprintf (buf,"%-8.2ls" , c4); +if (strncmp (buf, d4,8 )) +return -1 ; +if (buf[8 ] !=' ' ) +return -1 ; +if (buf[14 ]) +return -1 ; +#endif
Does this check the illegal character '?' case as well?
Alex
PATCH 6/15 test: test printing Unicode
Quoted 45 lines · Alexander Graf
Quoted 42 lines · Heinrich Schuchardt
Test printing of Unicode strings
Signed-off-by Heinrich Schuchardt <[email protected]>--- test/unicode_ut.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+)test/unicode_ut.c +27
-0@@ -34,6 +34,42 @@ static const char d3[] = {0xe6, 0xbd, 0x9c, 0xe6, 0xb0, 0xb4, 0xe8, 0x89,static const char d4[] = {0xf0 ,0x90 ,0x92 ,0x8d ,0xf0 ,0x90 ,0x92 ,0x96 ,0xf0 ,0x90 ,0x92 ,0x87 ,0x00 }; +static int ut_string16 (void ) +{ +#if defined(CONFIG_EFI_LOADER ) && \ + !defined(CONFIG_SPL_BUILD ) && !defined(API_BUILD ) +char buf[20 ]; + +memset (buf,0xff ,sizeof (buf)); +sprintf (buf,"%8.6ls" , c2); +if (buf[1 ] !=' ' ) +return -1 ; +if (strncmp (&buf[2 ], d2,7 )) +return -1 ; +if (buf[9 ]) +return -1 ; + +memset (buf,0xff ,sizeof (buf)); +sprintf (buf,"%8.6ls" , c4); +if (buf[4 ] !=' ' ) +return -1 ; +if (strncmp (&buf[5 ], d4,12 )) +return -1 ; +if (buf[17 ]) +return -1 ; + +memset (buf,0xff ,sizeof (buf)); +sprintf (buf,"%-8.2ls" , c4); +if (strncmp (buf, d4,8 ))
Quoted 8 lines
test/unicode_ut.c static const char d3[] = {0xe6, 0xbd, 0x9c, 0xe6, 0xb0, 0xb4, 0xe8, 0x89, · line 69
Quoted 6 lines
test/unicode_ut.c +6
-0+return -1 ; +if (buf[8 ] !=' ' ) +return -1 ; +if (buf[14 ]) +return -1 ; +#endif Does this check the illegal character '?' case as well?
No. I can add this.
Best regards
Heinrich
Quoted 4 lines
Alex
PATCH 7/15 efi_loader: remove limit on variable length
In reply to Heinrich SchuchardtThe EFI spec does not provide a length limit for variables.
--- lib/efi_loader/efi_variable.c | 52 ++++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 22 deletions(-)
lib/efi_loader/efi_variable.c +30 -22
@@ -44,10 +44,7 @@* converted to utf16? */ -#define MAX_VAR_NAME 31 -#define MAX_NATIVE_VAR_NAME \ - (strlen("efi_xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxxxxxx_") + \ - (MAX_VAR_NAME * MAX_UTF8_PER_UTF16)) +#define PREFIX_LEN (strlen("efi_xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxxxxxx_"))static int hex (int ch) {
@@ -101,18 +98,20 @@ static char *mem2hex(char *hexstr, const u8 *mem, int count)return hexstr; } -static efi_status_t efi_to_native (char *native,u16 *variable_name, +static efi_status_t efi_to_native (char **native,const u16 *variable_name,efi_guid_t *vendor) {size_t len; +char *pos; - len =u16_strlen ((u16 *)variable_name); -if (len >=MAX_VAR_NAME ) -return EFI_DEVICE_ERROR ; + len =PREFIX_LEN +utf16_utf8_strlen (variable_name) +1 ; + *native =malloc (len); +if (!*native) +return EFI_OUT_OF_RESOURCES ; - native +=sprintf (native,"efi_%pUl_" , vendor); - native = (char *)utf16_to_utf8 ((u8 *)native, (u16 *)variable_name, len); - *native ='\0' ; + pos = *native; + pos +=sprintf (pos,"efi_%pUl_" , vendor); +utf16_utf8_strcpy (&pos, variable_name);return EFI_SUCCESS ; }
@@ -168,7 +167,7 @@ efi_status_t EFIAPI efi_get_variable(u16 *variable_name, efi_guid_t *vendor, u32 *attributes, efi_uintn_t *data_size, void *data) { -char native_name[MAX_NATIVE_VAR_NAME +1 ]; +char *native_name;efi_status_t ret;unsigned long in_size;const char *val, *s;
@@ -180,13 +179,14 @@ efi_status_t EFIAPI efi_get_variable(u16 *variable_name, efi_guid_t *vendor,if (!variable_name || !vendor || !data_size)return EFI_EXIT (EFI_INVALID_PARAMETER ); - ret =efi_to_native (native_name, variable_name, vendor); + ret =efi_to_native (&native_name, variable_name, vendor);if (ret)return EFI_EXIT (ret);debug ("%s: get '%s'\n" , __func__, native_name); val =env_get (native_name); +free (native_name);if (!val)return EFI_EXIT (EFI_NOT_FOUND );
@@ -256,35 +256,41 @@ efi_status_t EFIAPI efi_set_variable(u16 *variable_name, efi_guid_t *vendor, u32 attributes, efi_uintn_t data_size, void *data) { - char native_name[MAX_NATIVE_VAR_NAME + 1]; + char *native_name = NULL, *val = NULL, *s;efi_status_t ret =EFI_SUCCESS ; -char *val, *s;u32 attr;EFI_ENTRY ("\"%ls\" %pUl %x %zu %p" , variable_name, vendor, attributes, data_size, data); -if (!variable_name || !vendor) -return EFI_EXIT (EFI_INVALID_PARAMETER ); +if (!variable_name || !vendor) { + ret =EFI_INVALID_PARAMETER ; + goto out; + } - ret =efi_to_native (native_name, variable_name, vendor); + ret =efi_to_native (&native_name, variable_name, vendor);if (ret) -return EFI_EXIT (ret); + goto out;#define ACCESS_ATTR (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)if ((data_size ==0 ) || !(attributes &ACCESS_ATTR )) {/* delete the variable: */ env_set (native_name,NULL ); -return EFI_EXIT (EFI_SUCCESS ); + ret =EFI_SUCCESS ; + goto out; } val =env_get (native_name);if (val) {parse_attr (val, &attr); -if (attr &READ_ONLY ) -return EFI_EXIT (EFI_WRITE_PROTECTED ); +if (attr &READ_ONLY ) { +/* We should not free val */ + val =NULL ; + ret =EFI_WRITE_PROTECTED ; + goto out; + } } val =malloc (2 * data_size +strlen ("{ro,run,boot}(blob)" ) +1 );
@@ -320,6 +326,8 @@ efi_status_t EFIAPI efi_set_variable(u16 *variable_name, efi_guid_t *vendor,if (env_set (native_name, val)) ret =EFI_DEVICE_ERROR ; +out: +free (native_name);free (val);return EFI_EXIT (ret);
Signature · 1 line
2.18.0
PATCH 7/15 efi_loader: remove limit on variable length
Quoted 52 lines · Heinrich Schuchardt
The EFI spec does not provide a length limit for variables.
Signed-off-by Heinrich Schuchardt <[email protected]>--- lib/efi_loader/efi_variable.c | 52 ++++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 22 deletions(-)lib/efi_loader/efi_variable.c +10
-11@@ -44,10 +44,7 @@* converted to utf16? */ -#define MAX_VAR_NAME 31 -#define MAX_NATIVE_VAR_NAME \ - (strlen("efi_xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxxxxxx_") + \ - (MAX_VAR_NAME * MAX_UTF8_PER_UTF16)) +#define PREFIX_LEN (strlen("efi_xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxxxxxx_"))static int hex (int ch) {@@ -101,18 +98,20 @@ static char *mem2hex(char *hexstr, const u8 *mem, int count)return hexstr; } -static efi_status_t efi_to_native (char *native,u16 *variable_name, +static efi_status_t efi_to_native (char **native,const u16 *variable_name,efi_guid_t *vendor) {size_t len; +char *pos; - len =u16_strlen ((u16 *)variable_name); -if (len >=MAX_VAR_NAME ) -return EFI_DEVICE_ERROR ; + len =PREFIX_LEN +utf16_utf8_strlen (variable_name) +1 ; + *native =malloc (len); +if (!*native) +return EFI_OUT_OF_RESOURCES ; - native +=sprintf (native,"efi_%pUl_" , vendor); - native = (char *)utf16_to_utf8 ((u8 *)native, (u16 *)variable_name, len); - *native ='\0' ; + pos = *native; + pos +=sprintf (pos,"efi_%pUl_" , vendor); +utf16_utf8_strcpy (&pos, variable_name);return EFI_SUCCESS ; }
lib/efi_loader/efi_variable.c efi_status_t EFIAPI efi_get_variable(u16 *variable_name, efi_guid_t *vendor, · line 170
Quoted 5 lines
lib/efi_loader/efi_variable.c +1
-1@@ -168,7 +167,7 @@ efi_status_t EFIAPI efi_get_variable(u16 *variable_name, efi_guid_t *vendor, u32 *attributes, efi_uintn_t *data_size, void *data) { -char native_name[MAX_NATIVE_VAR_NAME +1 ]; +char *native_name;
I think you want to predefine this to = NULL to make sure that an error path doesn't give you uninitialized values on free().
Alex
PATCH 7/15 efi_loader: remove limit on variable length
Quoted 52 lines · Alexander Graf
Quoted 49 lines · Heinrich Schuchardt
The EFI spec does not provide a length limit for variables.
Signed-off-by Heinrich Schuchardt <[email protected]>--- lib/efi_loader/efi_variable.c | 52 ++++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 22 deletions(-)lib/efi_loader/efi_variable.c +10
-11@@ -44,10 +44,7 @@* converted to utf16? */ -#define MAX_VAR_NAME 31 -#define MAX_NATIVE_VAR_NAME \ - (strlen("efi_xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxxxxxx_") + \ - (MAX_VAR_NAME * MAX_UTF8_PER_UTF16)) +#define PREFIX_LEN (strlen("efi_xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxxxxxx_"))static int hex (int ch) {@@ -101,18 +98,20 @@ static char *mem2hex(char *hexstr, const u8 *mem, int count)return hexstr; } -static efi_status_t efi_to_native (char *native,u16 *variable_name, +static efi_status_t efi_to_native (char **native,const u16 *variable_name,efi_guid_t *vendor) {size_t len; +char *pos; - len =u16_strlen ((u16 *)variable_name); -if (len >=MAX_VAR_NAME ) -return EFI_DEVICE_ERROR ; + len =PREFIX_LEN +utf16_utf8_strlen (variable_name) +1 ; + *native =malloc (len); +if (!*native) +return EFI_OUT_OF_RESOURCES ; - native +=sprintf (native,"efi_%pUl_" , vendor); - native = (char *)utf16_to_utf8 ((u8 *)native, (u16 *)variable_name, len); - *native ='\0' ; + pos = *native; + pos +=sprintf (pos,"efi_%pUl_" , vendor); +utf16_utf8_strcpy (&pos, variable_name);
Quoted 11 lines
lib/efi_loader/efi_variable.c efi_status_t EFIAPI efi_get_variable(u16 *variable_name, efi_guid_t *vendor, · line 170
Quoted 8 lines
lib/efi_loader/efi_variable.c +1
-1return EFI_SUCCESS ; }@@ -168,7 +167,7 @@ efi_status_t EFIAPI efi_get_variable(u16 *variable_name, efi_guid_t *vendor, u32 *attributes, efi_uintn_t *data_size, void *data) { -char native_name[MAX_NATIVE_VAR_NAME +1 ]; +char *native_name;I think you want to predefine this to = NULL to make sure that an error path doesn't give you uninitialized values on
free().
efi_to_native() returns EFI_OUT_OF_RESOURCES if the pointer cannot be assigned and the return value is checked. So how should I reach free(native_name) in this case?
Best regards
Heinrich
Quoted 4 lines
Alex
PATCH 7/15 efi_loader: remove limit on variable length
Quoted 65 lines · Heinrich Schuchardt
Quoted 52 lines · Alexander Graf
Quoted 49 lines · Heinrich Schuchardt
The EFI spec does not provide a length limit for variables.
Signed-off-by Heinrich Schuchardt <[email protected]>--- lib/efi_loader/efi_variable.c | 52 ++++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 22 deletions(-)lib/efi_loader/efi_variable.c +10
-11@@ -44,10 +44,7 @@* converted to utf16? */ -#define MAX_VAR_NAME 31 -#define MAX_NATIVE_VAR_NAME \ - (strlen("efi_xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxxxxxx_") + \ - (MAX_VAR_NAME * MAX_UTF8_PER_UTF16)) +#define PREFIX_LEN (strlen("efi_xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxxxxxx_"))static int hex (int ch) {@@ -101,18 +98,20 @@ static char *mem2hex(char *hexstr, const u8 *mem, int count)return hexstr; } -static efi_status_t efi_to_native (char *native,u16 *variable_name, +static efi_status_t efi_to_native (char **native,const u16 *variable_name,efi_guid_t *vendor) {size_t len; +char *pos; - len =u16_strlen ((u16 *)variable_name); -if (len >=MAX_VAR_NAME ) -return EFI_DEVICE_ERROR ; + len =PREFIX_LEN +utf16_utf8_strlen (variable_name) +1 ; + *native =malloc (len); +if (!*native) +return EFI_OUT_OF_RESOURCES ; - native +=sprintf (native,"efi_%pUl_" , vendor); - native = (char *)utf16_to_utf8 ((u8 *)native, (u16 *)variable_name, len); - *native ='\0' ; + pos = *native; + pos +=sprintf (pos,"efi_%pUl_" , vendor); +utf16_utf8_strcpy (&pos, variable_name);Quoted 11 lines
lib/efi_loader/efi_variable.c efi_status_t EFIAPI efi_get_variable(u16 *variable_name, efi_guid_t *vendor, · line 170
Quoted 8 lines
lib/efi_loader/efi_variable.c +1
-1return EFI_SUCCESS ; }@@ -168,7 +167,7 @@ efi_status_t EFIAPI efi_get_variable(u16 *variable_name, efi_guid_t *vendor, u32 *attributes, efi_uintn_t *data_size, void *data) { -char native_name[MAX_NATIVE_VAR_NAME +1 ]; +char *native_name;I think you want to predefine this to = NULL to make sure that an error path doesn't give you uninitialized values on
free().
Quoted 3 lines
efi_to_native()returnsEFI_OUT_OF_RESOURCESif the pointer cannot be assigned and the return value is checked. So how should I reachfree(native_name)in this case?
True, convinced. I thought I saw a case where you could hit an uninitialized native_name variable, but now I can't see it anymore.
Alex
PATCH 8/15 efi_loader: don't use unlimited stack as buffer
In reply to Heinrich SchuchardtThe length of a string printed to the console by the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL is not limited by the UEFI spec. Hence should not allocate a buffer for it on the stack.
--- lib/efi_loader/efi_console.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-)
lib/efi_loader/efi_console.c +13 -7
@@ -111,16 +111,21 @@ static efi_status_t EFIAPI efi_cout_output_string( {struct simple_text_output_mode *con = &efi_con_mode;struct cout_mode *mode = &efi_cout_modes[con->mode]; - -EFI_ENTRY ("%p, %p" , this, string); - -unsigned int n16 =u16_strlen (string); -char buf[MAX_UTF8_PER_UTF16 * n16 +1 ]; +char *buf, *pos;u16 *p; +efi_status_t ret =EFI_SUCCESS ; - *utf16_to_utf8 ((u8 *)buf, string, n16) ='\0' ; +EFI_ENTRY ("%p, %p" , this, string); + buf =malloc (utf16_utf8_strlen (string) +1 ); +if (!buf) { + ret =EFI_OUT_OF_RESOURCES ; + goto out; + } + pos = buf; +utf16_utf8_strcpy (&pos, string);fputs (stdout, buf); +free (buf);/* * Update the cursor position.
@@ -158,7 +163,8 @@ static efi_status_t EFIAPI efi_cout_output_string( con->cursor_row =min (con->cursor_row, (s32 )mode->rows -1 ); } -return EFI_EXIT (EFI_SUCCESS ); +out: +return EFI_EXIT (ret); } static efi_status_t EFIAPI efi_cout_test_string(
Signature · 1 line
2.18.0
PATCH 8/15 efi_loader: don't use unlimited stack as buffer
Quoted 5 lines · Heinrich Schuchardt
The length of a string printed to the console by the
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOLis not limited by the UEFI spec. Hence should not allocate a buffer for it on the stack.Signed-off-by Heinrich Schuchardt <[email protected]>
Alex
PATCH 9/15 efi_loader: buffer size for load options
In reply to Heinrich SchuchardtThe number of bytes in an utf-8 string is an upper limit for the number of words in the equivalent utf-16 string. In so far the inumbant coding works correctly. For non-ASCII characters the utf-16 string is shorter. With the patch only the necessary buffer size is allocated for the load options.
--- cmd/bootefi.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
cmd/bootefi.c +4 -2
@@ -116,18 +116,20 @@ static void set_load_options(struct efi_loaded_image *loaded_image_info, {size_t size;const char *env =env_get (env_var); +u16 *pos; loaded_image_info->load_options =NULL ; loaded_image_info->load_options_size =0 ;if (!env)return ; - size =strlen (env) +1 ; + size =utf8_utf16_strlen (env) +1 ; loaded_image_info->load_options =calloc (size,sizeof (u16));if (!loaded_image_info->load_options) {printf ("ERROR: Out of memory\n" );return ; } -utf8_to_utf16 (loaded_image_info->load_options, (u8 *)env, size); + pos = loaded_image_info->load_options; +utf8_utf16_strcpy (&pos, env); loaded_image_info->load_options_size = size *2 ; }
Signature · 1 line
2.18.0
PATCH 9/15 efi_loader: buffer size for load options
Quoted 6 lines · Heinrich Schuchardt
The number of bytes in an utf-8 string is an upper limit for the number of words in the equivalent utf-16 string. In so far the inumbant coding works correctly. For non-ASCII characters the utf-16 string is shorter. With the patch only the necessary buffer size is allocated for the load options.
Signed-off-by Heinrich Schuchardt <[email protected]>
Alex
PATCH 10/15 lib: charset: remove obsolete functions
In reply to Heinrich SchuchardtRemove functions:
- utf8_to_utf16()
- utf16_strcpy()
- utf16_strdup()
--- include/charset.h | 23 -------------- lib/charset.c | 79 ----------------------------------------------- 2 files changed, 102 deletions(-)
include/charset.h +0 -23
@@ -161,16 +161,6 @@ size_t u16_strlen(const u16 *in);*/ size_t u16_strnlen (const u16 *in,size_t count); -/** -* utf16_strcpy() - UTF16 equivalent of strcpy() -*/ -uint16_t *utf16_strcpy (uint16_t *dest,const uint16_t *src); - -/** -* utf16_strdup() - UTF16 equivalent of strdup() -*/ -uint16_t *utf16_strdup (const uint16_t *s); -/** * utf16_to_utf8() - Convert an utf16 string to utf8 *
@@ -187,17 +177,4 @@ uint16_t *utf16_strdup(const uint16_t *s);*/ uint8_t *utf16_to_utf8 (uint8_t *dest,const uint16_t *src,size_t size); -/** -* utf8_to_utf16() - Convert an utf8 string to utf16 -* -* Converts up to 'size' characters of the utf16 string 'src' to utf8 -* written to the 'dest' buffer. Stops at 0x00. -* -* @dest the destination buffer to write the utf8 characters -* @src the source utf16 string -* @size maximum number of utf16 characters to convert -* @return the pointer to the first unwritten byte in 'dest' -*/ -uint16_t *utf8_to_utf16 (uint16_t *dest,const uint8_t *src,size_t size); -#endif /* __CHARSET_H_ */
lib/charset.c +0 -79
88 lines not on this page · raw message
Signature · 1 line
2.18.0
PATCH 11/15 efi_loader: capitalization table
In reply to Heinrich SchuchardtThis patch provides a define to initialize a table that maps lower to capital letters for Unicode code point 0x0000 - 0xffff.
--- MAINTAINERS | 1 + include/capitalization.h | 1909 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 1910 insertions(+) create mode 100644 include/capitalization.h
MAINTAINERS +1 -0
@@ -368,6 +368,7 @@ F: doc/DocBook/efi.tmpl F: doc/README.uefi F: doc/README.iscsi F: Documentation/efi.rst +F: include/capitalization.h F: include/efi* F: include/pe.h F: include/asm-generic/pe.h
include/capitalization.h new file +1909 -0
1,909 lines not on this page · raw message
Signature · 1 line
2.18.0
PATCH 11/15 efi_loader: capitalization table
Quoted 30 lines · Heinrich Schuchardt
This patch provides a define to initialize a table that maps lower to capital letters for Unicode code point
0x0000-0xffff.Signed-off-by Heinrich Schuchardt <[email protected]>--- MAINTAINERS | 1 + include/capitalization.h | 1909 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 1910 insertions(+) create mode 100644 include/capitalization.hMAINTAINERS +1
-0@@ -368,6 +368,7 @@ F: doc/DocBook/efi.tmpl F: doc/README.uefi F: doc/README.iscsi F: Documentation/efi.rst +F: include/capitalization.h F: include/efi* F: include/pe.h F: include/asm-generic/pe.hinclude/capitalization.h new file +2
-0@@ -0,0 +1,1909 @@ +/* SPDX-License-Identifier: Unicode-DFS-2016 */ +/*
include/capitalization.h line 12
Quoted 10 lines
include/capitalization.h new file +10
-0+* Correspondence table for small and capital Unicode letters in the range of +* 0x0000 - 0xffff based on http://www.unicode.org/Public/UCA/11.0.0/allkeys.txt +*/ + +struct capitalization_table { +u16 upper; +u16 lower; +}; + +#define UNICODE_CAPITALIZATION_TABLE { \
Ugh, that is a *lot* of data. How much does the binary size grow with the table compiled in?
Is there any slightly more sophisticated pattern in the table maybe that we could just express as code? Would that turn out smaller maybe?
Alex
Quoted 7 lines
include/capitalization.h new file +7
-0+ {0x0531 ,/* ARMENIAN CAPITAL LETTER AYB */ \ + 0x0561, /* ARMENIAN SMALL LETTER AYB */ }, \ + { 0x0532, /* ARMENIAN CAPITAL LETTER BEN */ \ + 0x0562, /* ARMENIAN SMALL LETTER BEN */ }, \ + { 0x053E, /* ARMENIAN CAPITAL LETTER CA */ \ + 0x056E, /* ARMENIAN SMALL LETTER CA */ }, \ + { 0x0549, /* ARMENIAN CAPITAL LETTER CHA */ \
[...]
PATCH 11/15 efi_loader: capitalization table
Quoted 47 lines · Alexander Graf
Quoted 30 lines · Heinrich Schuchardt
This patch provides a define to initialize a table that maps lower to capital letters for Unicode code point
0x0000-0xffff.Signed-off-by Heinrich Schuchardt <[email protected]>--- MAINTAINERS | 1 + include/capitalization.h | 1909 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 1910 insertions(+) create mode 100644 include/capitalization.hMAINTAINERS +1
-0@@ -368,6 +368,7 @@ F: doc/DocBook/efi.tmpl F: doc/README.uefi F: doc/README.iscsi F: Documentation/efi.rst +F: include/capitalization.h F: include/efi* F: include/pe.h F: include/asm-generic/pe.hinclude/capitalization.h new file +2
-0@@ -0,0 +1,1909 @@ +/* SPDX-License-Identifier: Unicode-DFS-2016 */ +/* include/capitalization.h line 12
Quoted 10 lines
include/capitalization.h new file +10
-0+* Correspondence table for small and capital Unicode letters in the range of +* 0x0000 - 0xffff based on http://www.unicode.org/Public/UCA/11.0.0/allkeys.txt +*/ + +struct capitalization_table { +u16 upper; +u16 lower; +}; + +#define UNICODE_CAPITALIZATION_TABLE { \Ugh, that is a *lot* of data. How much does the binary size grow with the table compiled in?
Quoted 2 lines
Is there any slightly more sophisticated pattern in the table maybe that we could just express as code? Would that turn out smaller maybe?
This is 3792 bytes of data. Unicode capitalization is quite random in arranging lower and upper letters.
We could resort to zlib or gzip. But these libraries are not built by default.
Most urgently we will need the capitalization table for generating and checking short FAT filenames, so we could create a configuration switch that would reduce this table to codepage 437 or codepage 1250 letters depending on the chosen native character set.
In EDK2 I only found code for codepage 1250.
Best regards
Heinrich
Quoted 14 lines
Alex
Quoted 7 lines
include/capitalization.h new file +7
-0+ {0x0531 ,/* ARMENIAN CAPITAL LETTER AYB */ \ + 0x0561, /* ARMENIAN SMALL LETTER AYB */ }, \ + { 0x0532, /* ARMENIAN CAPITAL LETTER BEN */ \ + 0x0562, /* ARMENIAN SMALL LETTER BEN */ }, \ + { 0x053E, /* ARMENIAN CAPITAL LETTER CA */ \ + 0x056E, /* ARMENIAN SMALL LETTER CA */ }, \ + { 0x0549, /* ARMENIAN CAPITAL LETTER CHA */ \[...]
PATCH 11/15 efi_loader: capitalization table
Quoted 48 lines · Heinrich Schuchardt
Quoted 47 lines · Alexander Graf
Quoted 30 lines · Heinrich Schuchardt
This patch provides a define to initialize a table that maps lower to capital letters for Unicode code point
0x0000-0xffff.Signed-off-by Heinrich Schuchardt <[email protected]>--- MAINTAINERS | 1 + include/capitalization.h | 1909 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 1910 insertions(+) create mode 100644 include/capitalization.hMAINTAINERS +1
-0@@ -368,6 +368,7 @@ F: doc/DocBook/efi.tmpl F: doc/README.uefi F: doc/README.iscsi F: Documentation/efi.rst +F: include/capitalization.h F: include/efi* F: include/pe.h F: include/asm-generic/pe.hinclude/capitalization.h new file +2
-0@@ -0,0 +1,1909 @@ +/* SPDX-License-Identifier: Unicode-DFS-2016 */ +/* include/capitalization.h line 12
Quoted 10 lines
include/capitalization.h new file +10
-0+* Correspondence table for small and capital Unicode letters in the range of +* 0x0000 - 0xffff based on http://www.unicode.org/Public/UCA/11.0.0/allkeys.txt +*/ + +struct capitalization_table { +u16 upper; +u16 lower; +}; + +#define UNICODE_CAPITALIZATION_TABLE { \Ugh, that is a *lot* of data. How much does the binary size grow with the table compiled in?
Quoted 8 lines
Quoted 2 lines
Is there any slightly more sophisticated pattern in the table maybe that we could just express as code? Would that turn out smaller maybe?
This is 3792 bytes of data. Unicode capitalization is quite random in arranging lower and upper letters.
We could resort to zlib or gzip. But these libraries are not built by default.
Yeah, and that only adds to more overhead.
Quoted 4 lines
Most urgently we will need the capitalization table for generating and checking short FAT filenames, so we could create a configuration switch that would reduce this table to codepage 437 or codepage 1250 letters depending on the chosen native character set.
I think that's a great idea. There probably is a lot of overlap even between the two, so maybe just make it a config option for "non-latin upper/lower case conversion".
Quoted 1 line
In EDK2 I only found code for codepage 1250.
Yeah, I'd be surprised if people really needed more. In fact, how about you just default the config option to =n by default?
Alex
PATCH 11/15 efi_loader: capitalization table
Alexander Graf <[email protected]> �ん�書����:
Quoted 40 lines · Heinrich Schuchardt
Quoted 39 lines · Alexander Graf
Quoted 38 lines · Heinrich Schuchardt
Quoted 35 lines
This patch provides a define to initialize a table that maps lower to capital letters for Unicode code point
0x0000-0xffff.Signed-off-by Heinrich Schuchardt <[email protected]>--- MAINTAINERS | 1 + include/capitalization.h | 1909 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 1910 insertions(+) create mode 100644 include/capitalization.hMAINTAINERS +1
-0@@ -368,6 +368,7 @@ F: doc/DocBook/efi.tmpl F: doc/README.uefi F: doc/README.iscsi F: Documentation/efi.rst +F: include/capitalization.h F: include/efi* F: include/pe.h F: include/asm-generic/pe.hinclude/capitalization.h new file +7
-0@@ -0,0 +1,1909 @@ +/* SPDX-License-Identifier: Unicode-DFS-2016 */ +/* +* Correspondence table for small and capital Unicode letters in the range of +* 0x0000 - 0xffff based on http://www.unicode.org/Public/UCA/11.0.0/allkeys.txt +*/ + +struct capitalization_table {
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
include/capitalization.h line 12
Quoted 5 lines
include/capitalization.h new file +5
-0+u16 upper; +u16 lower; +}; + +#define UNICODE_CAPITALIZATION_TABLE { \Ugh, that is a *lot* of data. How much does the binary size grow with the table compiled in?
That data is also in glibc. I don’t know whether you use glibc though
...
Quoted 28 lines
Quoted 8 lines
Quoted 2 lines
Is there any slightly more sophisticated pattern in the table maybe that we could just express as code? Would that turn out smaller maybe?
This is 3792 bytes of data. Unicode capitalization is quite random in arranging lower and upper letters.
We could resort to zlib or gzip. But these libraries are not built by default.
Yeah, and that only adds to more overhead.
Quoted 4 lines
Most urgently we will need the capitalization table for generating and checking short FAT filenames, so we could create a configuration switch that would reduce this table to codepage 437 or codepage 1250 letters depending on the chosen native character set.
I think that's a great idea. There probably is a lot of overlap even between the two, so maybe just make it a config option for "non-latin upper/lower case conversion".
Quoted 1 line
In EDK2 I only found code for codepage 1250.
Yeah, I'd be surprised if people really needed more. In fact, how about you just default the config option to =n by default?
Alex
Signature · 2 lines
📧 Mike FABIAN <[email protected]> ç�¡çœ ä¸�è¶³ã�¯ã�„ã�„仕事ã�®æ•µã� 。
PATCH 11/15 efi_loader: capitalization table
Quoted 55 lines
Am 27.08.2018 um 10:30 schrieb Mike FABIAN <[email protected]>:
Alexander Graf <[email protected]> さんは書きました:
Quoted 40 lines
Quoted 40 lines · Heinrich Schuchardt
Quoted 39 lines · Alexander Graf
Quoted 38 lines · Heinrich Schuchardt
This patch provides a define to initialize a table that maps lower to capital letters for Unicode code point
0x0000-0xffff.Signed-off-by Heinrich Schuchardt <[email protected]>---
MAINTAINERS| 1 +include/capitalization.h| 1909 ++++++++++++++++++++++++++++++++++++++2 files changed, 1910 insertions(+)create mode 100644
include/capitalization.hMAINTAINERS +0
-0@@ -368,6 +368,7 @@ F: doc/DocBook/efi.tmplF: doc/README.uefi F: doc/README.iscsi F: Documentation/efi.rst +F: include/capitalization.h F: include/efi* F: include/pe.h F: include/asm-generic/pe.hinclude/capitalization.h new file +7
-0@@ -0,0 +1,1909 @@ +/* SPDX-License-Identifier: Unicode-DFS-2016 */ +/* +* Correspondence table for small and capital Unicode letters in the range of +* 0x0000 - 0xffff based on http://www.unicode.org/Public/UCA/11.0.0/allkeys.txt +*/ + +struct capitalization_table {Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
include/capitalization.h line 12
Quoted 5 lines
include/capitalization.h new file +5
-0+u16 upper; +u16 lower; +}; + +#define UNICODE_CAPITALIZATION_TABLE { \Ugh, that is a *lot* of data. How much does the binary size grow with the table compiled in?
Quoted 2 lines
That data is also in glibc. I don’t know whether you use glibc though
...
U-Boot is a standalone OS so to say, we do not use glibc (except for sandbox, but that's a special target).
The main problem is that some times people cram U-Boot into very tight spaces, like small flash chips or even on-chip RAM. So we have to be very cautious on space requirements.
Alex
PATCH 11/15 efi_loader: capitalization table
Hi,
Quoted 55 lines · Alexander Graf
Quoted 55 lines
Am 27.08.2018 um 10:30 schrieb Mike FABIAN <[email protected]>:
Alexander Graf <[email protected]> さんは書きました:
Quoted 48 lines
Quoted 48 lines · Heinrich Schuchardt
Quoted 47 lines · Alexander Graf
Quoted 33 lines · Heinrich Schuchardt
This patch provides a define to initialize a table that maps lower to capital letters for Unicode code point
0x0000-0xffff.Signed-off-by Heinrich Schuchardt <[email protected]>---
MAINTAINERS| 1 +include/capitalization.h| 1909 ++++++++++++++++++++++++++++++++++++++2 files changed, 1910 insertions(+)create mode 100644
include/capitalization.hMAINTAINERS +0
-0@@ -368,6 +368,7 @@ F: doc/DocBook/efi.tmplF: doc/README.uefi F: doc/README.iscsi F: Documentation/efi.rst +F: include/capitalization.h F: include/efi* F: include/pe.h F: include/asm-generic/pe.hinclude/capitalization.h new file +2
-0@@ -0,0 +1,1909 @@ +/* SPDX-License-Identifier: Unicode-DFS-2016 */ +/* include/capitalization.h line 12
Quoted 10 lines
include/capitalization.h new file +10
-0+* Correspondence table for small and capital Unicode letters in the range of +* 0x0000 - 0xffff based on http://www.unicode.org/Public/UCA/11.0.0/allkeys.txt +*/ + +struct capitalization_table { +u16 upper; +u16 lower; +}; + +#define UNICODE_CAPITALIZATION_TABLE { \Ugh, that is a *lot* of data. How much does the binary size grow with the table compiled in?
Quoted 6 lines
Quoted 2 lines
That data is also in glibc. I don’t know whether you use glibc though
...U-Boot is a standalone OS so to say, we do not use glibc (except for sandbox, but that's a special target).
The main problem is that some times people cram U-Boot into very tight spaces, like small flash chips or even on-chip RAM. So we have to be very cautious on space requirements.
Indeed.
Most archs use a private glib so do not build with one that supports this table.
Wouldn't it be better to put this in a C file as a const struct?
If it is big that's OK, we just need to add a CONFIG option for it. If we already have EFI enabled, perhaps it doesn't matter, since it is pretty big.
Regards,
Simon
PATCH 11/15 efi_loader: capitalization table
Quoted 67 lines · Simon Glass
Hi,
Quoted 55 lines · Alexander Graf
Quoted 55 lines
Am 27.08.2018 um 10:30 schrieb Mike FABIAN <[email protected]>:
Alexander Graf <[email protected]> さんは書きました:
Quoted 48 lines
Quoted 48 lines · Heinrich Schuchardt
Quoted 47 lines · Alexander Graf
Quoted 33 lines · Heinrich Schuchardt
This patch provides a define to initialize a table that maps lower to capital letters for Unicode code point
0x0000-0xffff.Signed-off-by Heinrich Schuchardt <[email protected]>---
MAINTAINERS| 1 +include/capitalization.h| 1909 ++++++++++++++++++++++++++++++++++++++2 files changed, 1910 insertions(+)create mode 100644
include/capitalization.hMAINTAINERS +0
-0@@ -368,6 +368,7 @@ F: doc/DocBook/efi.tmplF: doc/README.uefi F: doc/README.iscsi F: Documentation/efi.rst +F: include/capitalization.h F: include/efi* F: include/pe.h F: include/asm-generic/pe.hinclude/capitalization.h new file +2
-0@@ -0,0 +1,1909 @@ +/* SPDX-License-Identifier: Unicode-DFS-2016 */ +/* include/capitalization.h line 12
Quoted 10 lines
include/capitalization.h new file +10
-0+* Correspondence table for small and capital Unicode letters in the range of +* 0x0000 - 0xffff based on http://www.unicode.org/Public/UCA/11.0.0/allkeys.txt +*/ + +struct capitalization_table { +u16 upper; +u16 lower; +}; + +#define UNICODE_CAPITALIZATION_TABLE { \Ugh, that is a *lot* of data. How much does the binary size grow with the table compiled in?
Quoted 6 lines
Quoted 2 lines
That data is also in glibc. I don’t know whether you use glibc though
...U-Boot is a standalone OS so to say, we do not use glibc (except for sandbox, but that's a special target).
The main problem is that some times people cram U-Boot into very tight spaces, like small flash chips or even on-chip RAM. So we have to be very cautious on space requirements.
Indeed.
Quoted 7 lines
Most archs use a private glib so do not build with one that supports this table.
Wouldn't it be better to put this in a C file as a const struct?
If it is big that's OK, we just need to add a CONFIG option for it. If we already have EFI enabled, perhaps it doesn't matter, since it is pretty big.
EFI support when it started was about 10kb. I assume it grew by now, so maybe we're at 15kb by now. Adding another 4kb for the upper/lower translation is *massive* by comparison.
Edk2 only supports upper/lower conversion for English anyway, so we're not worse off if we don't support all the fancy unicode conversions.
Alex
PATCH 12/15 lib: charset: upper/lower case conversion
In reply to Heinrich SchuchardtProvide functions for upper and lower case conversion.
--- include/charset.h | 16 ++++++++++++++++ lib/charset.c | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+)
include/charset.h +16 -0
@@ -142,6 +142,22 @@ int utf16_utf8_strncpy(char **dst, const u16 *src, size_t count);*/ #define utf16_utf8_strcpy (d, s) utf16_utf8_strncpy((d), (s), SIZE_MAX) +/** +* utf_to_lower() - convert a Unicode letter to lower case +* +* @code: letter to convert +* Return: lower case letter or unchanged letter +*/ +s32 utf_to_lower (const s32 code); + +/** +* utf_to_upper() - convert a Unicode letter to upper case +* +* @code: letter to convert +* Return: upper case letter or unchanged letter +*/ +s32 utf_to_upper (const s32 code); +/** * u16_strlen - count non-zero words *
lib/charset.c +41 -0
55 lines not on this page · raw message
Signature · 1 line
2.18.0
PATCH 13/15 test: tests for utf_to_lower() utf_to_upper().
In reply to Heinrich SchuchardtProvide unit tests for utf_to_lower() utf_to_upper().
--- test/unicode_ut.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+)
test/unicode_ut.c +38 -0
@@ -483,6 +483,42 @@ int ut_utf16_utf8_strncpy(void)return 0 ; } +int ut_utf_to_lower (void ) +{ +if (utf_to_lower ('@' ) !='@' ) +return 1 ; +if (utf_to_lower ('A' ) !='a' ) +return 1 ; +if (utf_to_lower ('Z' ) !='z' ) +return 1 ; +if (utf_to_lower ('[' ) !='[' ) +return 1 ; +if (utf_to_lower ('m' ) !='m' ) +return 1 ; +/* Cyrillic letter I*/ +if (utf_to_lower (0x0418 ) !=0x0438 ) +return 0 ; +return 0 ; +} + +int ut_utf_to_upper (void ) +{ +if (utf_to_upper ('M' ) !='M' ) +return 1 ; +if (utf_to_lower ('`' ) !='`' ) +return 1 ; +if (utf_to_upper ('a' ) !='A' ) +return 1 ; +if (utf_to_upper ('z' ) !='Z' ) +return 1 ; +if (utf_to_upper ('{' ) !='{' ) +return 1 ; +/* Cyrillic letter I */ +if (utf_to_upper (0x0438 ) !=0x0418 ) +return 1 ; +return 0 ; +} +int do_ut_unicode (cmd_tbl_t *cmdtp,int flag,int argc,char *const argv[]) {int ret =0 ;
@@ -500,6 +536,8 @@ int do_ut_unicode(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) ret |=ut_utf16_utf8_strnlen (); ret |=ut_utf16_utf8_strcpy (); ret |=ut_utf16_utf8_strncpy (); + ret |=ut_utf_to_lower (); + ret |=ut_utf_to_upper ();printf ("Test %s\n" , ret ?"failed" :"passed" );
Signature · 1 line
2.18.0
PATCH 14/15 efi_loader: EFI_UNICODE_COLLATION_PROTOCOL
In reply to Heinrich SchuchardtThe patch implements the EFI_UNICODE_COLLATION_PROTOCOL.
--- MAINTAINERS | 2 + include/cp1250.h | 40 +++++ include/cp437.h | 40 +++++ include/efi_api.h | 21 +++ include/efi_loader.h | 5 + lib/efi_loader/Makefile | 18 +- lib/efi_loader/efi_boottime.c | 6 + lib/efi_loader/efi_unicode_collation.c | 218 +++++++++++++++++++++++++ 8 files changed, 346 insertions(+), 4 deletions(-) create mode 100644 include/cp1250.h create mode 100644 include/cp437.h create mode 100644 lib/efi_loader/efi_unicode_collation.c
MAINTAINERS +2 -0
@@ -369,6 +369,8 @@ F: doc/README.uefi F: doc/README.iscsi F: Documentation/efi.rst F: include/capitalization.h +F: include/cp1250.h +F: include/cp437.h F: include/efi* F: include/pe.h F: include/asm-generic/pe.h
include/cp1250.h new file +40 -0
@@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ + +/* +* Constant CP1250 contains the Unicode code points for characters 0x80 - 0xff +* of the code page 1250. +*/ +#define CP1250 { \ + 0x20ac, 0x0000, 0x201a, 0x0000, \ + 0x201e, 0x2026, 0x2020, 0x2021, \ + 0x0000, 0x2030, 0x0160, 0x2039, \ + 0x015a, 0x0164, 0x017d, 0x0179, \ + 0x0000, 0x2018, 0x2019, 0x201c, \ + 0x201d, 0x2022, 0x2013, 0x2014, \ + 0x0000, 0x2122, 0x0161, 0x203a, \ + 0x015b, 0x0165, 0x017e, 0x017a, \ + 0x00a0, 0x02c7, 0x02d8, 0x0141, \ + 0x00a4, 0x0104, 0x00a6, 0x00a7, \ + 0x00a8, 0x00a9, 0x015e, 0x00ab, \ + 0x00ac, 0x00ad, 0x00ae, 0x017b, \ + 0x00b0, 0x00b1, 0x02db, 0x0142, \ + 0x00b4, 0x00b5, 0x00b6, 0x00b7, \ + 0x00b8, 0x0105, 0x015f, 0x00bb, \ + 0x013d, 0x02dd, 0x013e, 0x017c, \ + 0x0154, 0x00c1, 0x00c2, 0x0102, \ + 0x00c4, 0x0139, 0x0106, 0x00c7, \ + 0x010c, 0x00c9, 0x0118, 0x00cb, \ + 0x011a, 0x00cd, 0x00ce, 0x010e, \ + 0x0110, 0x0143, 0x0147, 0x00d3, \ + 0x00d4, 0x0150, 0x00d6, 0x00d7, \ + 0x0158, 0x016e, 0x00da, 0x0170, \ + 0x00dc, 0x00dd, 0x0162, 0x00df, \ + 0x0155, 0x00e1, 0x00e2, 0x0103, \ + 0x00e4, 0x013a, 0x0107, 0x00e7, \ + 0x010d, 0x00e9, 0x0119, 0x00eb, \ + 0x011b, 0x00ed, 0x00ee, 0x010f, \ + 0x0111, 0x0144, 0x0148, 0x00f3, \ + 0x00f4, 0x0151, 0x00f6, 0x00f7, \ + 0x0159, 0x016f, 0x00fa, 0x0171, \ + 0x00fc, 0x00fd, 0x0163, 0x02d9, \ +}
include/cp437.h new file +40 -0
@@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ + +/* +* Constant CP437 contains the Unicode code points for characters 0x80 - 0xff +* of the code page 437. +*/ +#define CP437 { \ + 0x00c7, 0x00fc, 0x00e9, 0x00e2, \ + 0x00e4, 0x00e0, 0x00e5, 0x00e7, \ + 0x00ea, 0x00eb, 0x00e8, 0x00ef, \ + 0x00ee, 0x00ec, 0x00c4, 0x00c5, \ + 0x00c9, 0x00e6, 0x00c6, 0x00f4, \ + 0x00f6, 0x00f2, 0x00fb, 0x00f9, \ + 0x00ff, 0x00d6, 0x00dc, 0x00a2, \ + 0x00a3, 0x00a5, 0x20a7, 0x0192, \ + 0x00e1, 0x00ed, 0x00f3, 0x00fa, \ + 0x00f1, 0x00d1, 0x00aa, 0x00ba, \ + 0x00bf, 0x2310, 0x00ac, 0x00bd, \ + 0x00bc, 0x00a1, 0x00ab, 0x00bb, \ + 0x2591, 0x2592, 0x2593, 0x2502, \ + 0x2524, 0x2561, 0x2562, 0x2556, \ + 0x2555, 0x2563, 0x2551, 0x2557, \ + 0x255d, 0x255c, 0x255b, 0x2510, \ + 0x2514, 0x2534, 0x252c, 0x251c, \ + 0x2500, 0x253c, 0x255e, 0x255f, \ + 0x255a, 0x2554, 0x2569, 0x2566, \ + 0x2560, 0x2550, 0x256c, 0x2567, \ + 0x2568, 0x2564, 0x2565, 0x2559, \ + 0x2558, 0x2552, 0x2553, 0x256b, \ + 0x256a, 0x2518, 0x250c, 0x2588, \ + 0x2584, 0x258c, 0x2590, 0x2580, \ + 0x03b1, 0x00df, 0x0393, 0x03c0, \ + 0x03a3, 0x03c3, 0x00b5, 0x03c4, \ + 0x03a6, 0x0398, 0x03a9, 0x03b4, \ + 0x221e, 0x03c6, 0x03b5, 0x2229, \ + 0x2261, 0x00b1, 0x2265, 0x2264, \ + 0x2320, 0x2321, 0x00f7, 0x2248, \ + 0x00b0, 0x2219, 0x00b7, 0x221a, \ + 0x207f, 0x00b2, 0x25a0, 0x00a0, \ +}
include/efi_api.h +21 -0
@@ -31,6 +31,7 @@ enum efi_timer_delay { EFI_TIMER_RELATIVE = 2 }; +#define efi_intn_t ssize_t#define efi_uintn_t size_ttypedef uint16_t *efi_string_t ;
@@ -958,4 +959,24 @@ struct efi_driver_binding_protocol {efi_handle_t driver_binding_handle; }; +#define EFI_UNICODE_COLLATION_PROTOCOL2_GUID \ + EFI_GUID(0xa4c751fc, 0x23ae, 0x4c3e, \ + 0x92, 0xe9, 0x49, 0x64, 0xcf, 0x63, 0xf3, 0x49) +struct efi_unicode_collation_protocol { + efi_intn_t (EFIAPI *stri_coll)( + struct efi_unicode_collation_protocol *this, u16 *s1, u16 *s2); + bool (EFIAPI *metai_match)(struct efi_unicode_collation_protocol *this, +const u16 *string,const u16 *patter); + void (EFIAPI *str_lwr)(struct efi_unicode_collation_protocol + *this,u16 *string); + void (EFIAPI *str_upr)(struct efi_unicode_collation_protocol *this, +u16 *string); + void (EFIAPI *fat_to_str)(struct efi_unicode_collation_protocol *this, +efi_uintn_t fat_size,char *fat,u16 *string); + bool (EFIAPI *str_to_fat)(struct efi_unicode_collation_protocol *this, +const u16 *string,efi_uintn_t fat_size, +char *fat); +char *supported_languages; +}; +#endif
include/efi_loader.h +5 -0
@@ -98,6 +98,9 @@ extern const struct efi_device_path_to_text_protocol efi_device_path_to_text;/* implementation of the EFI_DEVICE_PATH_UTILITIES_PROTOCOL */ extern const struct efi_device_path_utilities_protocol efi_device_path_utilities; +/* Implementation of the EFI_UNICODE_COLLATION_PROTOCOL */ +extern const struct efi_unicode_collation_protocol + efi_unicode_collation_protocol;uint16_t *efi_dp_str (struct efi_device_path *dp);
@@ -127,6 +130,8 @@ extern const efi_guid_t efi_file_info_guid;/* GUID for file system information */ extern const efi_guid_t efi_file_system_info_guid;extern const efi_guid_t efi_guid_device_path_utilities_protocol; +/* GUID of the Unicode collation protocol */ +extern const efi_guid_t efi_guid_unicode_collation_protocol;extern unsigned int __efi_runtime_start, __efi_runtime_stop;extern unsigned int __efi_runtime_rel_start, __efi_runtime_rel_stop;
lib/efi_loader/Makefile +14 -4
@@ -17,10 +17,20 @@ always += helloworld.efi endif obj-$(CONFIG_CMD_BOOTEFI_HELLO) += helloworld_efi.o -obj-y += efi_image_loader.o efi_boottime.o efi_runtime.o efi_console.o -obj-y += efi_memory.o efi_device_path_to_text.o efi_device_path.o -obj-y += efi_device_path_utilities.o efi_file.o efi_variable.o efi_bootmgr.o -obj-y += efi_watchdog.o +obj-y += \ +efi_bootmgr.o \ +efi_boottime.o \ +efi_console.o \ +efi_device_path.o \ +efi_device_path_to_text.o \ +efi_device_path_utilities.o \ +efi_file.o \ +efi_image_loader.o \ +efi_memory.o \ +efi_runtime.o \ +efi_unicode_collation.o \ +efi_variable.o \ +efi_watchdog.o obj-$(CONFIG_LCD) += efi_gop.o obj-$(CONFIG_DM_VIDEO) += efi_gop.o obj-$(CONFIG_PARTITIONS) += efi_disk.o
lib/efi_loader/efi_boottime.c +6 -0
@@ -1525,6 +1525,12 @@ efi_status_t efi_setup_loaded_image(if (ret !=EFI_SUCCESS ) goto failure; + ret =efi_add_protocol (obj->handle, + &efi_guid_unicode_collation_protocol, + (void *)&efi_unicode_collation_protocol); +if (ret !=EFI_SUCCESS ) + goto failure; +return ret; failure:printf ("ERROR: Failure to install protocols for loaded image\n" );
lib/efi_loader/efi_unicode_collation.c new file +218 -0
218 lines not on this page · raw message
Signature · 1 line
2.18.0
PATCH 14/15 efi_loader: EFI_UNICODE_COLLATION_PROTOCOL
Quoted 3 lines · Heinrich Schuchardt
The patch implements the
EFI_UNICODE_COLLATION_PROTOCOL.Signed-off-by Heinrich Schuchardt <[email protected]>
Can you please add documentation to each function?
Alex
PATCH 15/15 efi_selftest: EFI_UNICODE_COLLATION_PROTOCOL
In reply to Heinrich SchuchardtProvide a unit test for the EFI_UNICODE_COLLATION_PROTOCOL.
--- lib/efi_selftest/Makefile | 1 + .../efi_selftest_unicode_collation.c | 257 ++++++++++++++++++ 2 files changed, 258 insertions(+) create mode 100644 lib/efi_selftest/efi_selftest_unicode_collation.c
lib/efi_selftest/Makefile +1 -0
@@ -30,6 +30,7 @@ efi_selftest_snp.o \ efi_selftest_textinput.o \ efi_selftest_textoutput.o \ efi_selftest_tpl.o \ +efi_selftest_unicode_collation.o \ efi_selftest_util.o \ efi_selftest_variables.o \ efi_selftest_watchdog.o
lib/efi_selftest/efi_selftest_unicode_collation.c new file +257 -0
257 lines not on this page · raw message
Signature · 1 line
2.18.0