[U-Boot] [PATCH 1/1] efi_loader: MetaiMatch() must be cases insensitive

Heinrich Schuchardt xypron.glpk at gmx.de
Wed Jun 12 18:14:46 UTC 2019


The MetaiMatch() service of the UnicodeCollationProtocol2 must be case
insensitive.

Signed-off-by: Heinrich Schuchardt <xypron.glpk at gmx.de>
---
 lib/efi_loader/efi_unicode_collation.c | 65 ++++++++++++++++----------
 1 file 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..c5e5b55d07 100644
--- a/lib/efi_loader/efi_unicode_collation.c
+++ b/lib/efi_loader/efi_unicode_collation.c
@@ -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;
 }
--
2.20.1



More information about the U-Boot mailing list