git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH] parse-options: fix parsing of "--foobar=" with no value

From
OMOlivier Marin <dkr+ml.git@free.fr>
Date
Jul 22, 2008, 18:44 UTC
Message-ID
<1216752267-12138-1-git-send-email-dkr+ml.git@free.fr>
From: Olivier Marin <dkr@freesurf.fr>

Before this patch, running a git command with a "--foobar=" argument will set the "foobar" option with a random value and continue. We should instead, exit with an error if a value is required, or use the default one if the value is optional.

This patch fix the above issue and add some test cases.
Signed-off-by: Olivier Marin <dkr@freesurf.fr>
---
 parse-options.c          |    8 ++++----
 t/t0040-parse-options.sh |   25 +++++++++++++++++++++++++
 test-parse-options.c     |    3 +++
 3 files changed, 32 insertions(+), 4 deletions(-)
diff --git a/parse-options.c b/parse-options.c
index 71a7acf..67be197 100644
--- a/parse-options.c
+++ b/parse-options.c
@@ -17,7 +17,7 @@ static int opterror(const struct option *opt, const char *reason, int flags)
 static int get_arg(struct parse_opt_ctx_t *p, const struct option *opt,
 		   int flags, const char **arg)
 {
-	if (p->opt) {
+	if (p->opt && *p->opt) {
 		*arg = p->opt;
 		p->opt = NULL;
 	} else if (p->argc == 1 && (opt->flags & PARSE_OPT_LASTARG_DEFAULT)) {
@@ -80,7 +80,7 @@ static int get_value(struct parse_opt_ctx_t *p,
 	case OPTION_STRING:
 		if (unset)
 			*(const char **)opt->value = NULL;
-		else if (opt->flags & PARSE_OPT_OPTARG && !p->opt)
+		else if (opt->flags & PARSE_OPT_OPTARG && (!p->opt || !*p->opt))
 			*(const char **)opt->value = (const char *)opt->defval;
 		else
 			return get_arg(p, opt, flags, (const char **)opt->value);
@@ -91,7 +91,7 @@ static int get_value(struct parse_opt_ctx_t *p,
 			return (*opt->callback)(opt, NULL, 1) ? (-1) : 0;
 		if (opt->flags & PARSE_OPT_NOARG)
 			return (*opt->callback)(opt, NULL, 0) ? (-1) : 0;
-		if (opt->flags & PARSE_OPT_OPTARG && !p->opt)
+		if (opt->flags & PARSE_OPT_OPTARG && (!p->opt || !*p->opt))
 			return (*opt->callback)(opt, NULL, 0) ? (-1) : 0;
 		if (get_arg(p, opt, flags, &arg))
 			return -1;
@@ -102,7 +102,7 @@ static int get_value(struct parse_opt_ctx_t *p,
 			*(int *)opt->value = 0;
 			return 0;
 		}
-		if (opt->flags & PARSE_OPT_OPTARG && !p->opt) {
+		if (opt->flags & PARSE_OPT_OPTARG && (!p->opt || !*p->opt)) {
 			*(int *)opt->value = opt->defval;
 			return 0;
 		}
diff --git a/t/t0040-parse-options.sh b/t/t0040-parse-options.sh
index 03dbe00..7ce2e86 100755
--- a/t/t0040-parse-options.sh
+++ b/t/t0040-parse-options.sh
@@ -26,6 +26,8 @@ String options
     --st <st>             get another string (pervert ordering)
     -o <str>              get another string
     --default-string      set string to default
+    --optional-string[=<string>]
+                          set string to optional if none given
 
 Magic arguments
     --quux                means --quux
@@ -85,6 +87,29 @@ test_expect_success 'missing required value' '
 	test $? = 129
 '
 
+test_expect_success 'missing required value with "--foobar="' '
+	test-parse-options --length=;
+	test $? = 129 &&
+	test-parse-options --len=;
+	test $? = 129
+'
+
+cat > expect << EOF
+boolean: 0
+integer: 0
+string: optional
+abbrev: 7
+verbose: 0
+quiet: no
+dry run: no
+EOF
+
+test_expect_success 'optional value with "--foobar="' '
+	test-parse-options --optional-string= > output 2> output.err &&
+	test ! -s output.err &&
+	test_cmp expect output
+'
+
 cat > expect << EOF
 boolean: 1
 integer: 13
diff --git a/test-parse-options.c b/test-parse-options.c
index 2a79e72..76db37e 100644
--- a/test-parse-options.c
+++ b/test-parse-options.c
@@ -42,6 +42,9 @@ int main(int argc, const char **argv)
 		OPT_STRING('o', NULL, &string, "str", "get another string"),
 		OPT_SET_PTR(0, "default-string", &string,
 			"set string to default", (unsigned long)"default"),
+		{ OPTION_STRING, 0, "optional-string", &string,
+			"string", "set string to optional if none given",
+			PARSE_OPT_OPTARG, NULL, (unsigned long)"optional" },
 		OPT_GROUP("Magic arguments"),
 		OPT_ARGUMENT("quux", "means --quux"),
 		OPT_GROUP("Standard options"),
-- 
1.6.0.rc0.16.gb169.dirty
Next: Sverre Rabbelier
Message 1 of 6 in “parse-options: fix parsing of "--foobar=" with no value”
  1. parse-options: fix parsing of "--foobar=" with no valueOlivier Marin, Jul 22, 2008
  2. Sverre RabbelierJul 22, 2008
  3. Pierre HabouzitJul 22, 2008
  4. Olivier MarinJul 22, 2008
  5. Johannes SchindelinJul 22, 2008
  6. Jeff KingJul 22, 2008

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.