diff mbox series

[v3,3/6] lib/cmdline: Allow get_options() to take 0 to validate the input

Message ID 20210122123853.75162-3-andriy.shevchenko@linux.intel.com
State New
Headers show
Series [v3,1/6] lib/cmdline_kunit: add a new test case for get_options() | expand

Commit Message

Andy Shevchenko Jan. 22, 2021, 12:38 p.m. UTC
Allow get_options() to take 0 as a number of integers parameter to validate
the input.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
v3: dropped string macros, added "the" in the comment (Bart)
 lib/cmdline.c       | 14 +++++++++++---
 lib/cmdline_kunit.c | 11 ++++++++++-
 2 files changed, 21 insertions(+), 4 deletions(-)

Comments

Geert Uytterhoeven Jan. 22, 2021, 1:13 p.m. UTC | #1
Hi Andy,

On Fri, Jan 22, 2021 at 1:39 PM Andy Shevchenko
<andriy.shevchenko@linux.intel.com> wrote:
> Allow get_options() to take 0 as a number of integers parameter to validate
> the input.
>
> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

Thanks for your patch!

> --- a/lib/cmdline.c
> +++ b/lib/cmdline.c

> @@ -103,15 +106,20 @@ EXPORT_SYMBOL(get_option);
>
>  char *get_options(const char *str, int nints, int *ints)
>  {
> +       bool validate = (nints == 0);
>         int res, i = 1;
>
> -       while (i < nints) {
> -               res = get_option((char **)&str, ints + i);
> +       while (i < nints || validate) {
> +               int *pint = validate ? ints : ints + i;

I think you can use NULL for validation, as per the documentation for
get_option().

> +
> +               res = get_option((char **)&str, pint);
>                 if (res == 0)
>                         break;
>                 if (res == 3) {
> +                       int n = validate ? 0 : nints - i;
>                         int range_nums;
> -                       range_nums = get_range((char **)&str, ints + i, nints - i);
> +
> +                       range_nums = get_range((char **)&str, pint, n);
>                         if (range_nums < 0)
>                                 break;
>                         /*

Regardless:
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>

Gr{oetje,eeting}s,

                        Geert
Andy Shevchenko Jan. 22, 2021, 1:49 p.m. UTC | #2
On Fri, Jan 22, 2021 at 02:13:10PM +0100, Geert Uytterhoeven wrote:
> On Fri, Jan 22, 2021 at 1:39 PM Andy Shevchenko
> <andriy.shevchenko@linux.intel.com> wrote:

...

> > +       while (i < nints || validate) {
> > +               int *pint = validate ? ints : ints + i;
> 
> I think you can use NULL for validation, as per the documentation for
> get_option().

That's what takes me a long time to realize how this machinery works and no,
unfortunately we may not use NULL, we have to keep the parsed number
for the further operations.

Thanks for review!
diff mbox series

Patch

diff --git a/lib/cmdline.c b/lib/cmdline.c
index 2a9ae2143e42..16b9eaa39538 100644
--- a/lib/cmdline.c
+++ b/lib/cmdline.c
@@ -91,6 +91,9 @@  EXPORT_SYMBOL(get_option);
  *	full, or when no more numbers can be retrieved from the
  *	string.
  *
+ *	When @nints is 0, the function just validates the given @str and
+ *	returns the amount of parseable integers as described below.
+ *
  *	Returns:
  *
  *	The first element is filled by the amount of the collected numbers
@@ -103,15 +106,20 @@  EXPORT_SYMBOL(get_option);
 
 char *get_options(const char *str, int nints, int *ints)
 {
+	bool validate = (nints == 0);
 	int res, i = 1;
 
-	while (i < nints) {
-		res = get_option((char **)&str, ints + i);
+	while (i < nints || validate) {
+		int *pint = validate ? ints : ints + i;
+
+		res = get_option((char **)&str, pint);
 		if (res == 0)
 			break;
 		if (res == 3) {
+			int n = validate ? 0 : nints - i;
 			int range_nums;
-			range_nums = get_range((char **)&str, ints + i, nints - i);
+
+			range_nums = get_range((char **)&str, pint, n);
 			if (range_nums < 0)
 				break;
 			/*
diff --git a/lib/cmdline_kunit.c b/lib/cmdline_kunit.c
index 91737f17ce51..3622c62bcf08 100644
--- a/lib/cmdline_kunit.c
+++ b/lib/cmdline_kunit.c
@@ -109,13 +109,22 @@  static void cmdline_do_one_range_test(struct kunit *test, const char *in,
 {
 	unsigned int i;
 	int r[16];
+	int *p;
 
 	memset(r, 0, sizeof(r));
 	get_options(in, ARRAY_SIZE(r), r);
-	KUNIT_EXPECT_EQ_MSG(test, r[0], e[0], "in test %u expected %d numbers, got %d",
+	KUNIT_EXPECT_EQ_MSG(test, r[0], e[0], "in test %u (parsed) expected %d numbers, got %d",
 			    n, e[0], r[0]);
 	for (i = 1; i < ARRAY_SIZE(r); i++)
 		KUNIT_EXPECT_EQ_MSG(test, r[i], e[i], "in test %u at %d", n, i);
+
+	memset(r, 0, sizeof(r));
+	get_options(in, 0, r);
+	KUNIT_EXPECT_EQ_MSG(test, r[0], e[0], "in test %u (validated) expected %d numbers, got %d",
+			    n, e[0], r[0]);
+
+	p = memchr_inv(&r[1], 0, sizeof(r) - sizeof(r[0]));
+	KUNIT_EXPECT_PTR_EQ_MSG(test, p, (int *)0, "in test %u out of bound at %d", n, p - r);
 }
 
 static void cmdline_test_range(struct kunit *test)