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) */