Reject passing an arg to an option that doesn't take one (bug 6915).
[rsync.git] / popt / popt.c
index a2c24e78423f72f642a67f550a7dff53169b968e..ec6f3bd8be7420575eb713eeaf83b63ec7e26793 100644 (file)
@@ -809,16 +809,20 @@ int poptGetNextOpt(poptContext con)
                    *oe++ = '\0';
                    /* XXX longArg is mapped back to persistent storage. */
                    longArg = origOptString + (oe - localOptString);
-               }
+               } else
+                   oe = NULL;
 
                opt = findOption(con->options, optString, '\0', &cb, &cbData,
                                 singleDash);
                if (!opt && !singleDash)
                    return POPT_ERROR_BADOPT;
+               if (!opt && oe)
+                   oe[-1] = '='; /* restore overwritten '=' */
            }
 
            if (!opt) {
                con->os->nextCharArg = origOptString + 1;
+               longArg = NULL;
            } else {
                if (con->os == con->optionStack &&
                   opt->argInfo & POPT_ARGFLAG_STRIP)
@@ -861,15 +865,16 @@ int poptGetNextOpt(poptContext con)
        /*@=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) {
@@ -877,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 {
@@ -1198,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: