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

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