← Commit list

80b2a5dd37

Daniel Stenberg
Daniel Stenberg
2026-04-08
SUCCESS Duration: 258s

Subject

tool_getparam: reduce opt_string complexity

Binary

No binary (build failed)

Architecture & Compiler Flags

Architecture: x86_64-linux-gnu Compiler: gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0

—

Build Log

(log yok)

Commit Diff GitHub →

src/tool_getparam.c+133 -90
@@ -97,7 +97,7 @@ static const struct LongShort aliases[]= {
{"compressed", ARG_BOOL, ' ', C_COMPRESSED},
{"compressed-ssh", ARG_BOOL, ' ', C_COMPRESSED_SSH},
{"config", ARG_FILE, 'K', C_CONFIG},
- {"connect-timeout", ARG_STRG, ' ', C_CONNECT_TIMEOUT},
+ {"connect-timeout", ARG_SECS, ' ', C_CONNECT_TIMEOUT},
{"connect-to", ARG_STRG, ' ', C_CONNECT_TO},
{"continue-at", ARG_STRG, 'C', C_CONTINUE_AT},
{"cookie", ARG_STRG, 'b', C_COOKIE},
@@ -134,7 +134,7 @@ static const struct LongShort aliases[]= {
{"epsv", ARG_BOOL, ' ', C_EPSV},
{"etag-compare", ARG_FILE, ' ', C_ETAG_COMPARE},
{"etag-save", ARG_FILE, ' ', C_ETAG_SAVE},
- {"expect100-timeout", ARG_STRG, ' ', C_EXPECT100_TIMEOUT},
+ {"expect100-timeout", ARG_SECS, ' ', C_EXPECT100_TIMEOUT},
{"fail", ARG_BOOL, 'f', C_FAIL},
{"fail-early", ARG_BOOL, ' ', C_FAIL_EARLY},
{"fail-with-body", ARG_BOOL, ' ', C_FAIL_WITH_BODY},
@@ -158,7 +158,7 @@ static const struct LongShort aliases[]= {
{"ftp-ssl-reqd", ARG_BOOL|ARG_TLS, ' ', C_FTP_SSL_REQD},
{"get", ARG_BOOL, 'G', C_GET},
{"globoff", ARG_BOOL, 'g', C_GLOBOFF},
- {"happy-eyeballs-timeout-ms", ARG_STRG, ' ', C_HAPPY_EYEBALLS_TIMEOUT_MS},
+ {"happy-eyeballs-timeout-ms", ARG_UNUM, ' ', C_HAPPY_EYEBALLS_TIMEOUT_MS},
{"haproxy-clientip", ARG_STRG, ' ', C_HAPROXY_CLIENTIP},
{"haproxy-protocol", ARG_BOOL, ' ', C_HAPROXY_PROTOCOL},
{"head", ARG_BOOL, 'I', C_HEAD},
@@ -187,8 +187,8 @@ static const struct LongShort aliases[]= {
{"json", ARG_STRG, ' ', C_JSON},
{"junk-session-cookies", ARG_BOOL, 'j', C_JUNK_SESSION_COOKIES},
{"keepalive", ARG_BOOL|ARG_NO, ' ', C_KEEPALIVE},
- {"keepalive-cnt", ARG_STRG, ' ', C_KEEPALIVE_CNT},
- {"keepalive-time", ARG_STRG, ' ', C_KEEPALIVE_TIME},
+ {"keepalive-cnt", ARG_UNUM, ' ', C_KEEPALIVE_CNT},
+ {"keepalive-time", ARG_UNUM, ' ', C_KEEPALIVE_TIME},
{"key", ARG_FILE, ' ', C_KEY},
{"key-type", ARG_STRG|ARG_TLS, ' ', C_KEY_TYPE},
{"knownhosts", ARG_FILE, ' ', C_KNOWNHOSTS},
@@ -208,7 +208,7 @@ static const struct LongShort aliases[]= {
{"manual", ARG_BOOL, 'M', C_MANUAL},
{"max-filesize", ARG_STRG, ' ', C_MAX_FILESIZE},
{"max-redirs", ARG_STRG, ' ', C_MAX_REDIRS},
- {"max-time", ARG_STRG, 'm', C_MAX_TIME},
+ {"max-time", ARG_SECS, 'm', C_MAX_TIME},
{"metalink", ARG_BOOL|ARG_DEPR, ' ', C_METALINK},
{"mptcp", ARG_BOOL, ' ', C_MPTCP},
{"negotiate", ARG_BOOL, ' ', C_NEGOTIATE},
@@ -226,8 +226,8 @@ static const struct LongShort aliases[]= {
{"output-dir", ARG_STRG, ' ', C_OUTPUT_DIR},
{"parallel", ARG_BOOL, 'Z', C_PARALLEL},
{"parallel-immediate", ARG_BOOL, ' ', C_PARALLEL_IMMEDIATE},
- {"parallel-max", ARG_STRG, ' ', C_PARALLEL_MAX},
- {"parallel-max-host", ARG_STRG, ' ', C_PARALLEL_HOST},
+ {"parallel-max", ARG_UNUM, ' ', C_PARALLEL_MAX},
+ {"parallel-max-host", ARG_UNUM, ' ', C_PARALLEL_HOST},
{"pass", ARG_STRG|ARG_CLEAR, ' ', C_PASS},
{"path-as-is", ARG_BOOL, ' ', C_PATH_AS_IS},
{"pinnedpubkey", ARG_STRG|ARG_TLS, ' ', C_PINNEDPUBKEY},
@@ -288,11 +288,11 @@ static const struct LongShort aliases[]= {
{"request", ARG_STRG, 'X', C_REQUEST},
{"request-target", ARG_STRG, ' ', C_REQUEST_TARGET},
{"resolve", ARG_STRG, ' ', C_RESOLVE},
- {"retry", ARG_STRG, ' ', C_RETRY},
+ {"retry", ARG_UNUM, ' ', C_RETRY},
{"retry-all-errors", ARG_BOOL, ' ', C_RETRY_ALL_ERRORS},
{"retry-connrefused", ARG_BOOL, ' ', C_RETRY_CONNREFUSED},
- {"retry-delay", ARG_STRG, ' ', C_RETRY_DELAY},
- {"retry-max-time", ARG_STRG, ' ', C_RETRY_MAX_TIME},
+ {"retry-delay", ARG_SECS, ' ', C_RETRY_DELAY},
+ {"retry-max-time", ARG_SECS, ' ', C_RETRY_MAX_TIME},
{"sasl-authzid", ARG_STRG, ' ', C_SASL_AUTHZID},
{"sasl-ir", ARG_BOOL, ' ', C_SASL_IR},
{"service-name", ARG_STRG, ' ', C_SERVICE_NAME},
@@ -311,8 +311,8 @@ static const struct LongShort aliases[]= {
{"socks5-gssapi-nec", ARG_BOOL, ' ', C_SOCKS5_GSSAPI_NEC},
{"socks5-gssapi-service", ARG_STRG, ' ', C_SOCKS5_GSSAPI_SERVICE},
{"socks5-hostname", ARG_STRG, ' ', C_SOCKS5_HOSTNAME},
- {"speed-limit", ARG_STRG, 'Y', C_SPEED_LIMIT},
- {"speed-time", ARG_STRG, 'y', C_SPEED_TIME},
+ {"speed-limit", ARG_UNUM, 'Y', C_SPEED_LIMIT},
+ {"speed-time", ARG_UNUM, 'y', C_SPEED_TIME},
{"ssl", ARG_BOOL|ARG_TLS, ' ', C_SSL},
{"ssl-allow-beast", ARG_BOOL|ARG_TLS, ' ', C_SSL_ALLOW_BEAST},
{"ssl-auto-client-cert", ARG_BOOL|ARG_TLS, ' ',
@@ -334,7 +334,7 @@ static const struct LongShort aliases[]= {
{"test-duphandle", ARG_BOOL, ' ', C_TEST_DUPHANDLE},
{"test-event", ARG_BOOL, ' ', C_TEST_EVENT},
#endif
- {"tftp-blksize", ARG_STRG, ' ', C_TFTP_BLKSIZE},
+ {"tftp-blksize", ARG_UNUM, ' ', C_TFTP_BLKSIZE},
{"tftp-no-options", ARG_BOOL, ' ', C_TFTP_NO_OPTIONS},
{"time-cond", ARG_STRG, 'z', C_TIME_COND},
{"tls-earlydata", ARG_BOOL|ARG_TLS, ' ', C_TLS_EARLYDATA},
@@ -365,7 +365,7 @@ static const struct LongShort aliases[]= {
{"variable", ARG_STRG, ' ', C_VARIABLE},
{"verbose", ARG_BOOL, 'v', C_VERBOSE},
{"version", ARG_BOOL, 'V', C_VERSION},
- {"vlan-priority", ARG_STRG, ' ', C_VLAN_PRIORITY},
+ {"vlan-priority", ARG_UNUM, ' ', C_VLAN_PRIORITY},
#ifdef USE_WATT32
{"wdebug", ARG_BOOL, ' ', C_WDEBUG},
#endif
@@ -2348,6 +2348,106 @@ static ParameterError opt_file(struct OperationConfig *config,
return err;
}
+/* options that accept unsigned numbers */
+static ParameterError opt_unum(struct OperationConfig *config,
+ const struct LongShort *a,
+ const char *nextarg)
+{
+ ParameterError err = PARAM_OK;
+ long val;
+ err = str2unum(&val, nextarg);
+ if(err)
+ return err;
+ switch(a->cmd) {
+ case C_VLAN_PRIORITY: /* --vlan-priority */
+ if(val > 7)
+ return PARAM_NUMBER_TOO_LARGE;
+ config->vlan_priority = val;
+ break;
+ case C_RETRY: /* --retry */
+ config->req_retry = val;
+ break;
+ case C_KEEPALIVE_TIME: /* --keepalive-time */
+ config->alivetime = val;
+ break;
+ case C_KEEPALIVE_CNT: /* --keepalive-cnt */
+ config->alivecnt = val;
+ break;
+ case C_TFTP_BLKSIZE: /* --tftp-blksize */
+ config->tftp_blksize = val;
+ break;
+ case C_HAPPY_EYEBALLS_TIMEOUT_MS: /* --happy-eyeballs-timeout-ms */
+ config->happy_eyeballs_timeout_ms = val;
+ /* 0 is a valid value for this timeout */
+ break;
+ case C_SPEED_TIME: /* --speed-time */
+ /* low speed time */
+ config->low_speed_time = val;
+ if(!config->low_speed_limit)
+ config->low_speed_limit = 1;
+ break;
+ case C_SPEED_LIMIT: /* --speed-limit */
+ /* low speed limit */
+ config->low_speed_limit = val;
+ if(!config->low_speed_time)
+ config->low_speed_time = 30;
+ break;
+ case C_PARALLEL_HOST: /* --parallel-max-host */
+ if(val > MAX_PARALLEL_HOST)
+ global->parallel_host = MAX_PARALLEL_HOST;
+ else if(val < 1)
+ global->parallel_host = PARALLEL_HOST_DEFAULT;
+ else
+ global->parallel_host = (unsigned short)val;
+ break;
+ case C_PARALLEL_MAX: /* --parallel-max */
+ if(val > MAX_PARALLEL)
+ global->parallel_max = MAX_PARALLEL;
+ else if(val < 1)
+ global->parallel_max = PARALLEL_DEFAULT;
+ else
+ global->parallel_max = (unsigned short)val;
+ break;
+ default:
+ DEBUGASSERT(0);
+ return PARAM_OPTION_UNKNOWN;
+ }
+ return err;
+}
+
+/* handle options that accept seconds */
+static ParameterError opt_secs(struct OperationConfig *config,
+ const struct LongShort *a,
+ const char *nextarg)
+{
+ long val;
+ ParameterError err = secs2ms(&val, nextarg);
+ if(err)
+ return err;
+ switch(a->cmd) {
+ case C_CONNECT_TIMEOUT: /* --connect-timeout */
+ config->connecttimeout_ms = val;
+ break;
+ case C_RETRY_DELAY: /* --retry-delay */
+ config->retry_delay_ms = val;
+ break;
+ case C_RETRY_MAX_TIME: /* --retry-max-time */
+ config->retry_maxtime_ms = val;
+ break;
+ case C_EXPECT100_TIMEOUT: /* --expect100-timeout */
+ config->expect100timeout_ms = val;
+ break;
+ case C_MAX_TIME: /* --max-time */
+ /* specified max time */
+ config->timeout_ms = val;
+ break;
+ default:
+ DEBUGASSERT(0);
+ return PARAM_OPTION_UNKNOWN;
+ }
+ return err;
+}
+
/* opt_string handles string options */
static ParameterError opt_string(struct OperationConfig *config,
const struct LongShort *a,
@@ -2355,7 +2455,6 @@ static ParameterError opt_string(struct OperationConfig *config,
{
ParameterError err = PARAM_OK;
curl_off_t value;
- long val;
static const char *redir_protos[] = {
"http",
"https",
@@ -2383,9 +2482,6 @@ static ParameterError opt_string(struct OperationConfig *config,
config->authtype |= CURLAUTH_BEARER;
return getstr(&config->oauth_bearer, nextarg, DENY_BLANK);
- case C_CONNECT_TIMEOUT: /* --connect-timeout */
- return secs2ms(&config->connecttimeout_ms, nextarg);
-
case C_DOH_URL: /* --doh-url */
err = getstr(&config->doh_url, nextarg, ALLOW_BLANK);
if(!err && config->doh_url && !config->doh_url[0])
@@ -2486,18 +2582,6 @@ static ParameterError opt_string(struct OperationConfig *config,
err = str2unummax(&config->ip_tos, nextarg, 0xFF);
break;
}
- case C_VLAN_PRIORITY: /* --vlan-priority */
- err = str2unummax(&config->vlan_priority, nextarg, 7);
- break;
- case C_RETRY: /* --retry */
- err = str2unum(&config->req_retry, nextarg);
- break;
- case C_RETRY_DELAY: /* --retry-delay */
- err = secs2ms(&config->retry_delay_ms, nextarg);
- break;
- case C_RETRY_MAX_TIME: /* --retry-max-time */
- err = secs2ms(&config->retry_maxtime_ms, nextarg);
- break;
case C_FTP_ACCOUNT: /* --ftp-account */
err = getstr(&config->ftp_account, nextarg, DENY_BLANK);
break;
@@ -2518,12 +2602,6 @@ static ParameterError opt_string(struct OperationConfig *config,
err = getstr(&global->libcurl, nextarg, DENY_BLANK);
#endif
break;
- case C_KEEPALIVE_TIME: /* --keepalive-time */
- err = str2unum(&config->alivetime, nextarg);
- break;
- case C_KEEPALIVE_CNT: /* --keepalive-cnt */
- err = str2unum(&config->alivecnt, nextarg);
- break;
case C_NOPROXY: /* --noproxy */
/* This specifies the noproxy list */
err = getstr(&config->noproxy, nextarg, ALLOW_BLANK);
@@ -2533,9 +2611,6 @@ static ParameterError opt_string(struct OperationConfig *config,
err = getstr(&config->proxy, nextarg, DENY_BLANK);
config->proxyver = CURLPROXY_HTTP_1_0;
break;
- case C_TFTP_BLKSIZE: /* --tftp-blksize */
- err = str2unum(&config->tftp_blksize, nextarg);
- break;
case C_MAIL_FROM: /* --mail-from */
err = getstr(&config->mail_from, nextarg, DENY_BLANK);
break;
@@ -2575,9 +2650,6 @@ static ParameterError opt_string(struct OperationConfig *config,
if(!err)
err = check_protocol(config->proto_default);
break;
- case C_EXPECT100_TIMEOUT: /* --expect100-timeout */
- err = secs2ms(&config->expect100timeout_ms, nextarg);
- break;
case C_CONNECT_TO: /* --connect-to */
err = add2list(&config->connect_to, nextarg);
break;
@@ -2588,10 +2660,6 @@ static ParameterError opt_string(struct OperationConfig *config,
err = PARAM_BAD_USE;
}
break;
- case C_HAPPY_EYEBALLS_TIMEOUT_MS: /* --happy-eyeballs-timeout-ms */
- err = str2unum(&config->happy_eyeballs_timeout_ms, nextarg);
- /* 0 is a valid value for this timeout */
- break;
case C_TRACE_CONFIG: /* --trace-config */
global->trace_set = TRUE;
if(set_trace_config(nextarg))
@@ -2789,10 +2857,6 @@ static ParameterError opt_string(struct OperationConfig *config,
case C_PROXY_HEADER: /* --proxy-header */
err = parse_header(config, (cmdline_t)a->cmd, nextarg);
break;
- case C_MAX_TIME: /* --max-time */
- /* specified max time */
- err = secs2ms(&config->timeout_ms, nextarg);
- break;
case C_OUTPUT_DIR: /* --output-dir */
err = getstr(&config->output_dir, nextarg, DENY_BLANK);
break;
@@ -2842,40 +2906,6 @@ static ParameterError opt_string(struct OperationConfig *config,
/* set custom request */
err = getstr(&config->customrequest, nextarg, DENY_BLANK);
break;
- case C_SPEED_TIME: /* --speed-time */
- /* low speed time */
- err = str2unum(&config->low_speed_time, nextarg);
- if(!err && !config->low_speed_limit)
- config->low_speed_limit = 1;
- break;
- case C_SPEED_LIMIT: /* --speed-limit */
- /* low speed limit */
- err = str2unum(&config->low_speed_limit, nextarg);
- if(!err && !config->low_speed_time)
- config->low_speed_time = 30;
- break;
- case C_PARALLEL_HOST: /* --parallel-max-host */
- err = str2unum(&val, nextarg);
- if(err)
- break;
- if(val > MAX_PARALLEL_HOST)
- global->parallel_host = MAX_PARALLEL_HOST;
- else if(val < 1)
- global->parallel_host = PARALLEL_HOST_DEFAULT;
- else
- global->parallel_host = (unsigned short)val;
- break;
- case C_PARALLEL_MAX: /* --parallel-max */
- err = str2unum(&val, nextarg);
- if(err)
- break;
- if(val > MAX_PARALLEL)
- global->parallel_max = MAX_PARALLEL;
- else if(val < 1)
- global->parallel_max = PARALLEL_DEFAULT;
- else
- global->parallel_max = (unsigned short)val;
- break;
case C_TIME_COND: /* --time-cond */
err = parse_time_cond(config, nextarg);
break;
@@ -2966,9 +2996,8 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
struct dynbuf nbuf;
bool replaced;
- if((ARGTYPE(a->desc) != ARG_STRG) &&
- (ARGTYPE(a->desc) != ARG_FILE)) {
- /* --expand on an option that is not a string or a filename */
+ if(ARGTYPE(a->desc) < ARG_STRG) {
+ /* --expand on an option that does not take an argument */
err = PARAM_EXPAND_ERROR;
goto error;
}
@@ -3030,10 +3059,24 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
warnf("The argument '%s' starts with a Unicode character. "
"Maybe ASCII was intended?", nextarg);
}
- if(ARGTYPE(a->desc) == ARG_FILE)
+ switch(ARGTYPE(a->desc)) {
+ case ARG_FILE:
err = opt_file(config, a, nextarg, max_recursive);
- else /* if(ARGTYPE(a->desc) == ARG_STRG) */
+ break;
+ case ARG_STRG:
err = opt_string(config, a, nextarg);
+ break;
+ case ARG_SECS:
+ err = opt_secs(config, a, nextarg);
+ break;
+ case ARG_UNUM:
+ err = opt_unum(config, a, nextarg);
+ break;
+ default:
+ DEBUGASSERT(0);
+ err = PARAM_OPTION_UNKNOWN;
+ break;
+ }
if(a->desc & ARG_CLEAR)
cleanarg(CURL_UNCONST(nextarg));
}
src/tool_getparam.h+3 -1
@@ -317,8 +317,10 @@ typedef enum {
#define ARG_BOOL 1 /* accepts a --no-[name] prefix */
#define ARG_STRG 2 /* requires an argument */
#define ARG_FILE 3 /* requires an argument, usually a filename */
+#define ARG_SECS 4 /* requires a time in seconds */
+#define ARG_UNUM 5 /* requires a non-negative number */
-#define ARG_TYPEMASK 0x03
+#define ARG_TYPEMASK 0x07
#define ARGTYPE(x) ((x) & ARG_TYPEMASK)
#define ARG_DEPR 0x10 /* deprecated option */