Unverified Commit 099f37e9 authored by Daniel Stenberg's avatar Daniel Stenberg
Browse files

curl: warn the user if a given file name looks like an option

... simply because this is usually a sign of the user having omitted the
file name and the next option is instead "eaten" by the parser as a file
name.

Add test1268 to verify

Closes #2885
parent ac86eabd
Loading
Loading
Loading
Loading
+31 −23
Original line number Diff line number Diff line
@@ -65,7 +65,8 @@ struct LongShort {
  enum {
    ARG_NONE,   /* stand-alone but not a boolean */
    ARG_BOOL,   /* accepts a --no-[name] prefix */
    ARG_STRING  /* requires an argument */
    ARG_STRING, /* requires an argument */
    ARG_FILENAME /* requires an argument, usually a file name */
  } desc;
};

@@ -75,7 +76,7 @@ static const struct LongShort aliases[]= {
  {"*@", "url",                      ARG_STRING},
  {"*4", "dns-ipv4-addr",            ARG_STRING},
  {"*6", "dns-ipv6-addr",            ARG_STRING},
  {"*a", "random-file",              ARG_STRING},
  {"*a", "random-file",              ARG_FILENAME},
  {"*b", "egd-file",                 ARG_STRING},
  {"*B", "oauth2-bearer",            ARG_STRING},
  {"*c", "connect-timeout",          ARG_STRING},
@@ -87,9 +88,9 @@ static const struct LongShort aliases[]= {
         /* 'epsv' made like this to make --no-epsv and --epsv to work
             although --disable-epsv is the documented option */
  {"*F", "dns-servers",              ARG_STRING},
  {"*g", "trace",                    ARG_STRING},
  {"*g", "trace",                    ARG_FILENAME},
  {"*G", "npn",                      ARG_BOOL},
  {"*h", "trace-ascii",              ARG_STRING},
  {"*h", "trace-ascii",              ARG_FILENAME},
  {"*H", "alpn",                     ARG_BOOL},
  {"*i", "limit-rate",               ARG_STRING},
  {"*j", "compressed",               ARG_BOOL},
@@ -108,7 +109,7 @@ static const struct LongShort aliases[]= {
  {"*s", "max-redirs",               ARG_STRING},
  {"*t", "proxy-ntlm",               ARG_BOOL},
  {"*u", "crlf",                     ARG_BOOL},
  {"*v", "stderr",                   ARG_STRING},
  {"*v", "stderr",                   ARG_FILENAME},
  {"*w", "interface",                ARG_STRING},
  {"*x", "krb",                      ARG_STRING},
  {"*x", "krb4",                     ARG_STRING},
@@ -177,7 +178,7 @@ static const struct LongShort aliases[]= {
  {"$J", "metalink",                 ARG_BOOL},
  {"$K", "sasl-ir",                  ARG_BOOL},
  {"$L", "test-event",               ARG_BOOL},
  {"$M", "unix-socket",              ARG_STRING},
  {"$M", "unix-socket",              ARG_FILENAME},
  {"$N", "path-as-is",               ARG_BOOL},
  {"$O", "socks5-gssapi-service",    ARG_STRING},
         /* 'socks5-gssapi-service' merged with'proxy-service-name' and
@@ -188,7 +189,7 @@ static const struct LongShort aliases[]= {
  {"$R", "expect100-timeout",        ARG_STRING},
  {"$S", "tftp-no-options",          ARG_BOOL},
  {"$U", "connect-to",               ARG_STRING},
  {"$W", "abstract-unix-socket",     ARG_STRING},
  {"$W", "abstract-unix-socket",     ARG_FILENAME},
  {"$X", "tls-max",                  ARG_STRING},
  {"$Y", "suppress-connect-headers", ARG_BOOL},
  {"$Z", "compressed-ssh",           ARG_BOOL},
@@ -219,19 +220,19 @@ static const struct LongShort aliases[]= {
  {"da", "data-ascii",               ARG_STRING},
  {"db", "data-binary",              ARG_STRING},
  {"de", "data-urlencode",           ARG_STRING},
  {"D",  "dump-header",              ARG_STRING},
  {"D",  "dump-header",              ARG_FILENAME},
  {"e",  "referer",                  ARG_STRING},
  {"E",  "cert",                     ARG_STRING},
  {"Ea", "cacert",                   ARG_STRING},
  {"E",  "cert",                     ARG_FILENAME},
  {"Ea", "cacert",                   ARG_FILENAME},
  {"Eb", "cert-type",                ARG_STRING},
  {"Ec", "key",                      ARG_STRING},
  {"Ec", "key",                      ARG_FILENAME},
  {"Ed", "key-type",                 ARG_STRING},
  {"Ee", "pass",                     ARG_STRING},
  {"Ef", "engine",                   ARG_STRING},
  {"Eg", "capath",                   ARG_STRING},
  {"Eg", "capath",                   ARG_FILENAME},
  {"Eh", "pubkey",                   ARG_STRING},
  {"Ei", "hostpubmd5",               ARG_STRING},
  {"Ej", "crlfile",                  ARG_STRING},
  {"Ej", "crlfile",                  ARG_FILENAME},
  {"Ek", "tlsuser",                  ARG_STRING},
  {"El", "tlspassword",              ARG_STRING},
  {"Em", "tlsauthtype",              ARG_STRING},
@@ -246,17 +247,17 @@ static const struct LongShort aliases[]= {
  {"Eu", "proxy-tlsuser",            ARG_STRING},
  {"Ev", "proxy-tlspassword",        ARG_STRING},
  {"Ew", "proxy-tlsauthtype",        ARG_STRING},
  {"Ex", "proxy-cert",               ARG_STRING},
  {"Ex", "proxy-cert",               ARG_FILENAME},
  {"Ey", "proxy-cert-type",          ARG_STRING},
  {"Ez", "proxy-key",                ARG_STRING},
  {"Ez", "proxy-key",                ARG_FILENAME},
  {"E0", "proxy-key-type",           ARG_STRING},
  {"E1", "proxy-pass",               ARG_STRING},
  {"E2", "proxy-ciphers",            ARG_STRING},
  {"E3", "proxy-crlfile",            ARG_STRING},
  {"E3", "proxy-crlfile",            ARG_FILENAME},
  {"E4", "proxy-ssl-allow-beast",    ARG_BOOL},
  {"E5", "login-options",            ARG_STRING},
  {"E6", "proxy-cacert",             ARG_STRING},
  {"E7", "proxy-capath",             ARG_STRING},
  {"E6", "proxy-cacert",             ARG_FILENAME},
  {"E7", "proxy-capath",             ARG_FILENAME},
  {"E8", "proxy-insecure",           ARG_BOOL},
  {"E9", "proxy-tlsv1",              ARG_NONE},
  {"EA", "socks5-basic",             ARG_BOOL},
@@ -277,7 +278,7 @@ static const struct LongShort aliases[]= {
  {"j",  "junk-session-cookies",     ARG_BOOL},
  {"J",  "remote-header-name",       ARG_BOOL},
  {"k",  "insecure",                 ARG_BOOL},
  {"K",  "config",                   ARG_STRING},
  {"K",  "config",                   ARG_FILENAME},
  {"l",  "list-only",                ARG_BOOL},
  {"L",  "location",                 ARG_BOOL},
  {"Lt", "location-trusted",         ARG_BOOL},
@@ -285,10 +286,10 @@ static const struct LongShort aliases[]= {
  {"M",  "manual",                   ARG_BOOL},
  {"n",  "netrc",                    ARG_BOOL},
  {"no", "netrc-optional",           ARG_BOOL},
  {"ne", "netrc-file",               ARG_STRING},
  {"ne", "netrc-file",               ARG_FILENAME},
  {"N",  "buffer",                   ARG_BOOL},
         /* 'buffer' listed as --no-buffer in the help */
  {"o",  "output",                   ARG_STRING},
  {"o",  "output",                   ARG_FILENAME},
  {"O",  "remote-name",              ARG_NONE},
  {"Oa", "remote-name-all",          ARG_BOOL},
  {"p",  "proxytunnel",              ARG_BOOL},
@@ -300,7 +301,7 @@ static const struct LongShort aliases[]= {
  {"s",  "silent",                   ARG_BOOL},
  {"S",  "show-error",               ARG_BOOL},
  {"t",  "telnet-option",            ARG_STRING},
  {"T",  "upload-file",              ARG_STRING},
  {"T",  "upload-file",              ARG_FILENAME},
  {"u",  "user",                     ARG_STRING},
  {"U",  "proxy-user",               ARG_STRING},
  {"v",  "verbose",                  ARG_BOOL},
@@ -570,7 +571,7 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
      }
    }

    if(aliases[hit].desc == ARG_STRING) {
    if(aliases[hit].desc >= ARG_STRING) {
      /* this option requires an extra parameter */
      if(!longopt && parse[1]) {
        nextarg = (char *)&parse[1]; /* this is the actual extra parameter */
@@ -580,6 +581,13 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
        return PARAM_REQUIRES_PARAMETER;
      else
        *usedarg = TRUE; /* mark it as used */

      if((aliases[hit].desc == ARG_FILENAME) &&
         (nextarg[0] == '-') && nextarg[1]) {
        /* if the file name looks like a command line option */
        warnf(global, "The file name argument '%s' looks like a flag.\n",
              nextarg);
      }
    }
    else if((aliases[hit].desc == ARG_NONE) && !toggle)
      return PARAM_NO_PREFIX;
+1 −0
Original line number Diff line number Diff line
@@ -140,6 +140,7 @@ test1236 test1237 test1238 test1239 test1240 test1241 test1242 test1243 \
test1244 test1245 test1246 test1247 test1248 test1249 test1250 test1251 \
test1252 test1253 test1254 test1255 test1256 test1257 test1258 test1259 \
test1260 test1261 test1262 test1263 test1264 test1265 test1266 test1267 \
test1268 \
\
test1280 test1281 test1282 test1283 test1284 test1285 test1286 test1287 \
test1288 test1289 test1290 test1291 test1292 \

tests/data/test1268

0 → 100644
+38 −0
Original line number Diff line number Diff line
<testcase>
<info>
<keywords>
warning
</keywords>
</info>

#
# Server-side
<reply>
</reply>

#
# Client-side
<client>
<server>
none
</server>
 <name>
file name argument looks like a flag
 </name>
 <command>
--stderr log/moo1268 --unix-socket -k hej://moo
</command>
</client>

<verify>
<file name="log/moo1268">
Warning: The file name argument '-k' looks like a flag.
curl: (1) Protocol "hej" not supported or disabled in libcurl
</file>

# we expect an error since we provide a weird URL
<errorcode>
1
</errorcode>
</verify>
</testcase>