From 7e1ae24c3cdfe9ca003ba8b44fe09875b2c84df1 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sat, 3 Apr 2021 21:02:22 -0600 Subject: [PATCH] getopt_common(): Correct handling of unsupported long options. If an unrecognized long option is encountered, we must skip over that argv[] entry or getopt_long() will seriously misbehave. Affects getopt_long() and getopt_long_only() Problem found and fix verified with an updated version of the OS test. --- libs/libc/unistd/lib_getopt_common.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/libs/libc/unistd/lib_getopt_common.c b/libs/libc/unistd/lib_getopt_common.c index c1a5d6b909c..e04a8d38c4e 100644 --- a/libs/libc/unistd/lib_getopt_common.c +++ b/libs/libc/unistd/lib_getopt_common.c @@ -384,7 +384,16 @@ int getopt_common(int argc, FAR char * const argv[], /* And parse the long option */ - return getopt_long_option(go, argv, longopts, longindex); + ret = getopt_long_option(go, argv, longopts, longindex); + if (ret == '?') + { + /* Skip over the unrecognized long option */ + + go->go_optind++; + go->go_optptr = NULL; + } + + return ret; } /* The -option form is only valid in getop_long_only() mode and @@ -401,8 +410,18 @@ int getopt_common(int argc, FAR char * const argv[], */ ret = getopt_long_option(go, argv, longopts, longindex); - if (ret != '?' || *(go->go_optptr + 1) != '\0') + if (ret != '?') { + /* Success or ERROR */ + + return ret; + } + else if (*(go->go_optptr + 1) != '\0') + { + /* Skip over the unrecognized long option */ + + go->go_optind++; + go->go_optptr = NULL; return ret; } }