Hi Rasmus,

On Wed, 11 Mar 2026 at 06:09, Rasmus Villemoes <[email protected]> wrote:
>
> POSIX states that
>
>   0 arguments:
>       Exit false (1).
>   1 argument:
>       Exit true (0) if $1 is not null; otherwise, exit false.
>
> and at least bash and busybox sh behave that way.
>
> The current 'argc < 3' does the right thing for a non-existing or
> empty argv[1], but not for a non-empty argv[1]. Fix that and add
> corresponding test cases.
>
> Signed-off-by: Rasmus Villemoes <[email protected]>
> ---
>  cmd/test.c     | 11 +++++++++--
>  test/hush/if.c | 30 ++++++++++++++++++++++++++++++
>  2 files changed, 39 insertions(+), 2 deletions(-)
>
> diff --git a/cmd/test.c b/cmd/test.c
> index f0645ef98f1..0d0f090386c 100644
> --- a/cmd/test.c
> +++ b/cmd/test.c
> @@ -71,10 +71,17 @@ static int do_test(struct cmd_tbl *cmdtp, int flag, int 
> argc,
>                 argc--;
>         }
>
> -       /* args? */
> -       if (argc < 3)
> +       /*
> +        * Per POSIX, 'test' with 0 arguments should return 1, while
> +        * 'test <arg>' should be equivalent to 'test -n <arg>',
> +        * i.e. true if and only if <arg> is not empty.
> +        */
> +       if (argc < 2)
>                 return 1;
>
> +       if (argc == 2)
> +               return !strcmp(argv[1], "");
> +
>  #ifdef DEBUG
>         {
>                 debug("test(%d):", argc);
> diff --git a/test/hush/if.c b/test/hush/if.c
> index 148e9a53e90..e82a95aaf27 100644
> --- a/test/hush/if.c
> +++ b/test/hush/if.c
> @@ -32,6 +32,15 @@ static int hush_test_if_base(struct unit_test_state *uts)
>         sprintf(if_formatted, if_format, "false");
>         ut_asserteq(1, run_command(if_formatted, 0));

Can you use run_commandf() here?

>
> +       sprintf(if_formatted, if_format, "test");
> +       ut_asserteq(1, run_command(if_formatted, 0));
> +
> +       sprintf(if_formatted, if_format, "test ''");
> +       ut_asserteq(1, run_command(if_formatted, 0));
> +
> +       sprintf(if_formatted, if_format, "test 'abc'");
> +       ut_assertok(run_command(if_formatted, 0));
> +
>         return 0;
>  }
>  HUSH_TEST(hush_test_if_base, 0);
> @@ -343,6 +352,27 @@ static int hush_test_lbracket_alias(struct 
> unit_test_state *uts)
>         ut_asserteq(1, run_command(if_formatted, 0));
>         ut_assert_nextline(missing_rbracket_error);
>
> +       sprintf(if_formatted, if_format, "[ ]");
> +       ut_asserteq(1, run_command(if_formatted, 0));
> +
> +       sprintf(if_formatted, if_format, "[");
> +       ut_asserteq(1, run_command(if_formatted, 0));
> +       ut_assert_nextline(missing_rbracket_error);
> +
> +       sprintf(if_formatted, if_format, "[ '' ]");
> +       ut_asserteq(1, run_command(if_formatted, 0));
> +
> +       sprintf(if_formatted, if_format, "[ ''");
> +       ut_asserteq(1, run_command(if_formatted, 0));
> +       ut_assert_nextline(missing_rbracket_error);
> +
> +       sprintf(if_formatted, if_format, "[ 'abc' ]");
> +       ut_assertok(run_command(if_formatted, 0));
> +
> +       sprintf(if_formatted, if_format, "[ 'abc'");
> +       ut_asserteq(1, run_command(if_formatted, 0));
> +       ut_assert_nextline(missing_rbracket_error);
> +
>         return 0;
>  }
>  HUSH_TEST(hush_test_lbracket_alias, UTF_CONSOLE);
> --
> 2.53.0
>

Regards,
Simon

Reply via email to