]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
efi_loader: MetaiMatch() must be case insensitive
authorHeinrich Schuchardt <xypron.glpk@gmx.de>
Wed, 12 Jun 2019 17:18:24 +0000 (19:18 +0200)
committerHeinrich Schuchardt <xypron.glpk@gmx.de>
Fri, 14 Jun 2019 17:18:40 +0000 (19:18 +0200)
The MetaiMatch() service of the UnicodeCollationProtocol2 must be case
insensitive.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
lib/efi_loader/efi_unicode_collation.c

index f293b423975f58f4c67f42c625e56be3ba9d36bd..4fe23625558b5ad1e7ae1a596fe124b561de40ab 100644 (file)
@@ -73,11 +73,22 @@ out:
        return ret;
 }
 
+/**
+ * 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;
 }