diff options
author | Heinrich Schuchardt <xypron.glpk@gmx.de> | 2019-06-12 19:18:24 +0200 |
---|---|---|
committer | Heinrich Schuchardt <xypron.glpk@gmx.de> | 2019-06-14 19:18:40 +0200 |
commit | 336476a959b9ecac75ba3f6de344829563e213ca (patch) | |
tree | 80b83f2237c9b96d43079dadc28e4b9c77e82b5c /lib/efi_loader/efi_unicode_collation.c | |
parent | 0e22c7cbebefae3a01ea2f10ba1772ba693ee1eb (diff) |
efi_loader: MetaiMatch() must be case insensitive
The MetaiMatch() service of the UnicodeCollationProtocol2 must be case
insensitive.
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Diffstat (limited to 'lib/efi_loader/efi_unicode_collation.c')
-rw-r--r-- | lib/efi_loader/efi_unicode_collation.c | 65 |
1 files changed, 41 insertions, 24 deletions
diff --git a/lib/efi_loader/efi_unicode_collation.c b/lib/efi_loader/efi_unicode_collation.c index f293b42397..4fe2362555 100644 --- a/lib/efi_loader/efi_unicode_collation.c +++ b/lib/efi_loader/efi_unicode_collation.c @@ -74,10 +74,21 @@ out: } /** + * next_lower() - get next codepoint converted to lower case + * + * @string: pointer to u16 string, on return advanced by one codepoint + * Return: first codepoint of string converted to lower case + */ +static s32 next_lower(const u16 **string) +{ + return utf_to_lower(utf16_get(string)); +} + +/** * metai_match() - compare utf-16 string with a pattern string case-insenitively * - * @s: string to compare - * @p: pattern string + * @string: string to compare + * @pattern: pattern string * * The pattern string may use these: * - * matches >= 0 characters @@ -93,61 +104,67 @@ out: * * Return: true if the string is matched. */ -static bool metai_match(const u16 *s, const u16 *p) +static bool metai_match(const u16 *string, const u16 *pattern) { - u16 first; + s32 first, s, p; + + for (; *string && *pattern;) { + const u16 *string_old = string; + + s = next_lower(&string); + p = next_lower(&pattern); - for (; *s && *p; ++s, ++p) { - switch (*p) { + switch (p) { case '*': /* Match 0 or more characters */ - ++p; - for (;; ++s) { - if (metai_match(s, p)) + for (;; s = next_lower(&string)) { + if (metai_match(string_old, pattern)) return true; - if (!*s) + if (!s) return false; + string_old = string; } case '?': /* Match any one character */ break; case '[': /* Match any character in the set */ - ++p; - first = *p; + p = next_lower(&pattern); + first = p; if (first == ']') /* Empty set */ return false; - ++p; - if (*p == '-') { + p = next_lower(&pattern); + if (p == '-') { /* Range */ - ++p; - if (*s < first || *s > *p) + p = next_lower(&pattern); + if (s < first || s > p) return false; - ++p; - if (*p != ']') + p = next_lower(&pattern); + if (p != ']') return false; } else { /* Set */ bool hit = false; - if (*s == first) + if (s == first) hit = true; - for (; *p && *p != ']'; ++p) { - if (*p == *s) + for (; p && p != ']'; + p = next_lower(&pattern)) { + if (p == s) hit = true; } - if (!hit || *p != ']') + if (!hit || p != ']') return false; } break; default: /* Match one character */ - if (*p != *s) + if (p != s) return false; } } - if (!*p && !*s) + if (!*pattern && !*string) return true; return false; } |