Blame SOURCES/0118-libmultipath-cleanup-add_feature.patch

1595c1
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
1595c1
From: Benjamin Marzinski <bmarzins@redhat.com>
1595c1
Date: Fri, 7 Oct 2022 12:35:38 -0500
1595c1
Subject: [PATCH] libmultipath: cleanup add_feature
1595c1
1595c1
add_feature() didn't correctly handle feature strings that used
1595c1
whitespace other than spaces, which the kernel allows. It also didn't
1595c1
allow adding features with multiple tokens. When it looked to see if the
1595c1
feature string to be added already existed, it didn't check if the match
1595c1
was part of a larger token. Finally, it did unnecessary work.  By using
1595c1
asprintf() to create the string, the function can be signifcantly
1595c1
simplified.
1595c1
1595c1
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
1595c1
Reviewed-by: Martin Wilck <mwilck@suse.com>
1595c1
---
1595c1
 libmultipath/structs.c | 49 +++++++++++++++++++++---------------------
1595c1
 1 file changed, 24 insertions(+), 25 deletions(-)
1595c1
1595c1
diff --git a/libmultipath/structs.c b/libmultipath/structs.c
1595c1
index 471087e2..84f9c959 100644
1595c1
--- a/libmultipath/structs.c
1595c1
+++ b/libmultipath/structs.c
1595c1
@@ -572,23 +572,33 @@ int add_feature(char **f, const char *n)
1595c1
 {
1595c1
 	int c = 0, d, l;
1595c1
 	char *e, *t;
1595c1
+	const char *p;
1595c1
 
1595c1
 	if (!f)
1595c1
 		return 1;
1595c1
 
1595c1
 	/* Nothing to do */
1595c1
-	if (!n || *n == '0')
1595c1
+	if (!n || *n == '\0')
1595c1
 		return 0;
1595c1
 
1595c1
-	if (strchr(n, ' ') != NULL) {
1595c1
-		condlog(0, "internal error: feature \"%s\" contains spaces", n);
1595c1
+	l = strlen(n);
1595c1
+	if (isspace(*n) || isspace(*(n + l - 1))) {
1595c1
+		condlog(0, "internal error: feature \"%s\" has leading or trailing spaces", n);
1595c1
 		return 1;
1595c1
 	}
1595c1
 
1595c1
+	p = n;
1595c1
+	d = 1;
1595c1
+	while (*p != '\0') {
1595c1
+		if (isspace(*p) && !isspace(*(p + 1)) && *(p + 1) != '\0')
1595c1
+			d++;
1595c1
+		p++;
1595c1
+	}
1595c1
+
1595c1
 	/* default feature is null */
1595c1
 	if(!*f)
1595c1
 	{
1595c1
-		l = asprintf(&t, "1 %s", n);
1595c1
+		l = asprintf(&t, "%0d %s", d, n);
1595c1
 		if(l == -1)
1595c1
 			return 1;
1595c1
 
1595c1
@@ -597,35 +607,24 @@ int add_feature(char **f, const char *n)
1595c1
 	}
1595c1
 
1595c1
 	/* Check if feature is already present */
1595c1
-	if (strstr(*f, n))
1595c1
-		return 0;
1595c1
+	e = *f;
1595c1
+	while ((e = strstr(e, n)) != NULL) {
1595c1
+		if (isspace(*(e - 1)) &&
1595c1
+		    (isspace(*(e + l)) || *(e + l) == '\0'))
1595c1
+			return 0;
1595c1
+		e += l;
1595c1
+	}
1595c1
 
1595c1
 	/* Get feature count */
1595c1
 	c = strtoul(*f, &e, 10);
1595c1
-	if (*f == e || (*e != ' ' && *e != '\0')) {
1595c1
+	if (*f == e || (!isspace(*e) && *e != '\0')) {
1595c1
 		condlog(0, "parse error in feature string \"%s\"", *f);
1595c1
 		return 1;
1595c1
 	}
1595c1
-
1595c1
-	/* Add 1 digit and 1 space */
1595c1
-	l = strlen(e) + strlen(n) + 2;
1595c1
-
1595c1
-	c++;
1595c1
-	/* Check if we need more digits for feature count */
1595c1
-	for (d = c; d >= 10; d /= 10)
1595c1
-		l++;
1595c1
-
1595c1
-	t = MALLOC(l + 1);
1595c1
-	if (!t)
1595c1
+	c += d;
1595c1
+	if (asprintf(&t, "%0d%s %s", c, e, n) < 0)
1595c1
 		return 1;
1595c1
 
1595c1
-	/* e: old feature string with leading space, or "" */
1595c1
-	if (*e == ' ')
1595c1
-		while (*(e + 1) == ' ')
1595c1
-			e++;
1595c1
-
1595c1
-	snprintf(t, l + 1, "%0d%s %s", c, e, n);
1595c1
-
1595c1
 	FREE(*f);
1595c1
 	*f = t;
1595c1