[PATCH 3/3] lib/bitmap.c: bitmap_parselist can accept string with whitespaces on head or tail

2015-07-01 Thread Pan Xinhui


In __bitmap_parselist we can accept whitespaces on head or tail
during every parsing procedure.
If input has valid ranges, there is no reason to reject the user.

For example, bitmap_parselist(" 1-3, 5, ", , nmaskbits).
After separating the string, we get " 1-3", " 5", and " ".
It's possible and reasonable to accept such string as long as
the parsing result is correct.

Signed-off-by: Pan Xinhui 
Cc: Yury Norov 
---
 lib/bitmap.c | 32 ++--
 1 file changed, 18 insertions(+), 14 deletions(-)

diff --git a/lib/bitmap.c b/lib/bitmap.c
index f549176..8148143 100644
--- a/lib/bitmap.c
+++ b/lib/bitmap.c
@@ -506,7 +506,7 @@ static int __bitmap_parselist(const char *buf, unsigned int 
buflen,
int nmaskbits)
 {
unsigned a, b;
-   int c, old_c, totaldigits;
+   int c, old_c, totaldigits, ndigits;
const char __user __force *ubuf = (const char __user __force *)buf;
int at_start, in_range;
 
@@ -516,6 +516,7 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,

at_start = 1;
in_range = 0;
a = b = 0;
+   ndigits = totaldigits;
 
 		/* Get the next cpu# or a range of cpu#'s */

while (buflen) {
@@ -529,17 +530,20 @@ static int __bitmap_parselist(const char *buf, unsigned 
int buflen,
if (isspace(c))
continue;
 
-			/*

-* If the last character was a space and the current
-* character isn't '\0', we've got embedded whitespace.
-* This is a no-no, so throw an error.
-*/
-   if (totaldigits && c && isspace(old_c))
-   return -EINVAL;
-
/* A '\0' or a ',' signal the end of a cpu# or range */
if (c == '\0' || c == ',')
break;
+   /*
+   * whitespaces between digits are not allowed,
+   * but it's ok if whitespaces are on head or tail.
+   * when old_c is whilespace,
+   * if totaldigits == ndigits, whitespace is on head.
+   * if whitespace is on tail, it should not run here.
+   * as c was ',' or '\0',
+   * the last code line has broken the current loop.
+   */
+   if ((totaldigits != ndigits) && isspace(old_c))
+   return -EINVAL;
 
 			if (c == '-') {

if (at_start || in_range)
@@ -559,6 +563,8 @@ static int __bitmap_parselist(const char *buf, unsigned int 
buflen,
at_start = 0;
totaldigits++;
}
+   if (ndigits == totaldigits)
+   continue;
/* if no digit is after '-', it's wrong*/
if (at_start && in_range)
return -EINVAL;
@@ -566,11 +572,9 @@ static int __bitmap_parselist(const char *buf, unsigned 
int buflen,
return -EINVAL;
if (b >= nmaskbits)
return -ERANGE;
-   if (!at_start) {
-   while (a <= b) {
-   set_bit(a, maskp);
-   a++;
-   }
+   while (a <= b) {
+   set_bit(a, maskp);
+   a++;
}
} while (buflen && c == ',');
return 0;
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 3/3] lib/bitmap.c: bitmap_parselist can accept string with whitespaces on head or tail

2015-07-01 Thread Pan Xinhui


In __bitmap_parselist we can accept whitespaces on head or tail
during every parsing procedure.
If input has valid ranges, there is no reason to reject the user.

For example, bitmap_parselist( 1-3, 5, , mask, nmaskbits).
After separating the string, we get  1-3,  5, and  .
It's possible and reasonable to accept such string as long as
the parsing result is correct.

Signed-off-by: Pan Xinhui xinhuix@intel.com
Cc: Yury Norov yury.no...@gmail.com
---
 lib/bitmap.c | 32 ++--
 1 file changed, 18 insertions(+), 14 deletions(-)

diff --git a/lib/bitmap.c b/lib/bitmap.c
index f549176..8148143 100644
--- a/lib/bitmap.c
+++ b/lib/bitmap.c
@@ -506,7 +506,7 @@ static int __bitmap_parselist(const char *buf, unsigned int 
buflen,
int nmaskbits)
 {
unsigned a, b;
-   int c, old_c, totaldigits;
+   int c, old_c, totaldigits, ndigits;
const char __user __force *ubuf = (const char __user __force *)buf;
int at_start, in_range;
 
@@ -516,6 +516,7 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,

at_start = 1;
in_range = 0;
a = b = 0;
+   ndigits = totaldigits;
 
 		/* Get the next cpu# or a range of cpu#'s */

while (buflen) {
@@ -529,17 +530,20 @@ static int __bitmap_parselist(const char *buf, unsigned 
int buflen,
if (isspace(c))
continue;
 
-			/*

-* If the last character was a space and the current
-* character isn't '\0', we've got embedded whitespace.
-* This is a no-no, so throw an error.
-*/
-   if (totaldigits  c  isspace(old_c))
-   return -EINVAL;
-
/* A '\0' or a ',' signal the end of a cpu# or range */
if (c == '\0' || c == ',')
break;
+   /*
+   * whitespaces between digits are not allowed,
+   * but it's ok if whitespaces are on head or tail.
+   * when old_c is whilespace,
+   * if totaldigits == ndigits, whitespace is on head.
+   * if whitespace is on tail, it should not run here.
+   * as c was ',' or '\0',
+   * the last code line has broken the current loop.
+   */
+   if ((totaldigits != ndigits)  isspace(old_c))
+   return -EINVAL;
 
 			if (c == '-') {

if (at_start || in_range)
@@ -559,6 +563,8 @@ static int __bitmap_parselist(const char *buf, unsigned int 
buflen,
at_start = 0;
totaldigits++;
}
+   if (ndigits == totaldigits)
+   continue;
/* if no digit is after '-', it's wrong*/
if (at_start  in_range)
return -EINVAL;
@@ -566,11 +572,9 @@ static int __bitmap_parselist(const char *buf, unsigned 
int buflen,
return -EINVAL;
if (b = nmaskbits)
return -ERANGE;
-   if (!at_start) {
-   while (a = b) {
-   set_bit(a, maskp);
-   a++;
-   }
+   while (a = b) {
+   set_bit(a, maskp);
+   a++;
}
} while (buflen  c == ',');
return 0;
--
1.9.1
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/