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