Here's something that was recently fixed for the popt that is included
with rsync: rejecting an arg to an option that doesn't take an arg.

Attached is a patch.  A new error code, POPT_ERROR_UNWANTEDARG, was
created to make the error message nice.  This handles both -l=value
and --long-arg=value where neither one is supposed to take a value.

..wayne..
--- popt.c
+++ popt.c
@@ -860,20 +860,21 @@ int poptGetNextOpt(poptContext con)
 
 	    origOptString++;
 	    if (*origOptString != '\0')
-		con->os->nextCharArg = origOptString + (*origOptString == '=');
+		con->os->nextCharArg = origOptString;
 	}
 	/*...@=branchstate@*/
 
 	if (opt == NULL) return POPT_ERROR_BADOPT;	/* XXX can't happen */
-	if (opt->arg && (opt->argInfo & POPT_ARG_MASK) == POPT_ARG_NONE) {
-	    if (poptSaveInt((int *)opt->arg, opt->argInfo, 1L))
-		return POPT_ERROR_BADOPERATION;
-	} else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_VAL) {
+	if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_NONE
+	 || (opt->argInfo & POPT_ARG_MASK) == POPT_ARG_VAL) {
+	    if (longArg || (con->os->nextCharArg && con->os->nextCharArg[0] == '='))
+		return POPT_ERROR_UNWANTEDARG;
 	    if (opt->arg) {
-		if (poptSaveInt((int *)opt->arg, opt->argInfo, (long)opt->val))
+		long val = (opt->argInfo & POPT_ARG_MASK) == POPT_ARG_VAL ? opt->val : 1;
+		if (poptSaveInt((int *)opt->arg, opt->argInfo, val))
 		    return POPT_ERROR_BADOPERATION;
 	    }
-	} else if ((opt->argInfo & POPT_ARG_MASK) != POPT_ARG_NONE) {
+	} else {
 	    con->os->nextArg = _free(con->os->nextArg);
 	    /*...@-usedef@*/	/* FIX: W2DO? */
 	    if (longArg) {
@@ -881,7 +882,7 @@ int poptGetNextOpt(poptContext con)
 		longArg = expandNextArg(con, longArg);
 		con->os->nextArg = longArg;
 	    } else if (con->os->nextCharArg) {
-		longArg = expandNextArg(con, con->os->nextCharArg);
+		longArg = expandNextArg(con, con->os->nextCharArg + (con->os->nextCharArg[0] == '='));
 		con->os->nextArg = longArg;
 		con->os->nextCharArg = NULL;
 	    } else {
@@ -1202,6 +1203,8 @@ const char * poptStrerror(const int error)
     switch (error) {
       case POPT_ERROR_NOARG:
 	return POPT_("missing argument");
+      case POPT_ERROR_UNWANTEDARG:
+	return POPT_("option does not take an argument");
       case POPT_ERROR_BADOPT:
 	return POPT_("unknown option");
       case POPT_ERROR_BADOPERATION:
diff --git a/popt/popt.h b/popt/popt.h
index 4f85d9e..8d85f73 100644
--- a/popt/popt.h
+++ b/popt/popt.h
@@ -82,6 +82,7 @@
 /*...@{*/
 #define POPT_ERROR_NOARG	-10	/*!< missing argument */
 #define POPT_ERROR_BADOPT	-11	/*!< unknown option */
+#define POPT_ERROR_UNWANTEDARG	-12	/*!< option does not take an argument */
 #define POPT_ERROR_OPTSTOODEEP	-13	/*!< aliases nested too deeply */
 #define POPT_ERROR_BADQUOTE	-15	/*!< error in paramter quoting */
 #define POPT_ERROR_ERRNO	-16	/*!< errno set, use strerror(errno) */

Reply via email to