diff options
author | robot-contrib <robot-contrib@yandex-team.com> | 2022-12-02 16:18:16 +0300 |
---|---|---|
committer | robot-contrib <robot-contrib@yandex-team.com> | 2022-12-02 16:18:16 +0300 |
commit | 22a73deb46c33ab8539b522286f0fb9b3364f856 (patch) | |
tree | af3cf69e9e6ebc887a5add5491b2fcebbfdff06a /contrib/libs/curl/src/tool_paramhlp.c | |
parent | 2e7d246d83a0077f08e6fed36594fc2087949502 (diff) | |
download | ydb-22a73deb46c33ab8539b522286f0fb9b3364f856.tar.gz |
Update contrib/libs/curl to 7.86.0
Diffstat (limited to 'contrib/libs/curl/src/tool_paramhlp.c')
-rw-r--r-- | contrib/libs/curl/src/tool_paramhlp.c | 197 |
1 files changed, 122 insertions, 75 deletions
diff --git a/contrib/libs/curl/src/tool_paramhlp.c b/contrib/libs/curl/src/tool_paramhlp.c index 9306498e23..05afb8d3a4 100644 --- a/contrib/libs/curl/src/tool_paramhlp.c +++ b/contrib/libs/curl/src/tool_paramhlp.c @@ -34,6 +34,8 @@ #include "tool_getpass.h" #include "tool_msgs.h" #include "tool_paramhlp.h" +#include "tool_libinfo.h" +#include "tool_util.h" #include "tool_version.h" #include "dynbuf.h" @@ -66,6 +68,7 @@ struct getout *new_getout(struct OperationConfig *config) ParameterError file2string(char **bufp, FILE *file) { struct curlx_dynbuf dyn; + DEBUGASSERT(MAX_FILE2STRING < INT_MAX); /* needs to fit in an int later */ curlx_dyn_init(&dyn, MAX_FILE2STRING); if(file) { char buffer[256]; @@ -92,6 +95,8 @@ ParameterError file2memory(char **bufp, size_t *size, FILE *file) if(file) { size_t nread; struct curlx_dynbuf dyn; + /* The size needs to fit in an int later */ + DEBUGASSERT(MAX_FILE2MEMORY < INT_MAX); curlx_dyn_init(&dyn, MAX_FILE2MEMORY); do { char buffer[4096]; @@ -213,7 +218,7 @@ ParameterError str2unummax(long *val, const char *str, long max) * data. */ -static ParameterError str2double(double *val, const char *str, long max) +static ParameterError str2double(double *val, const char *str, double max) { if(str) { char *endptr; @@ -246,7 +251,7 @@ static ParameterError str2double(double *val, const char *str, long max) * data. */ -ParameterError str2udouble(double *valp, const char *str, long max) +ParameterError str2udouble(double *valp, const char *str, double max) { double value; ParameterError result = str2double(&value, str, max); @@ -260,6 +265,53 @@ ParameterError str2udouble(double *valp, const char *str, long max) } /* + * Implement protocol sets in null-terminated array of protocol name pointers. + */ + +/* Return index of prototype token in set, card(set) if not found. + Can be called with proto == NULL to get card(set). */ +static size_t protoset_index(const char * const *protoset, const char *proto) +{ + const char * const *p = protoset; + + DEBUGASSERT(proto == proto_token(proto)); /* Ensure it is tokenized. */ + + for(; *p; p++) + if(proto == *p) + break; + return p - protoset; +} + +/* Include protocol token in set. */ +static void protoset_set(const char **protoset, const char *proto) +{ + if(proto) { + size_t n = protoset_index(protoset, proto); + + if(!protoset[n]) { + DEBUGASSERT(n < proto_count); + protoset[n] = proto; + protoset[n + 1] = NULL; + } + } +} + +/* Exclude protocol token from set. */ +static void protoset_clear(const char **protoset, const char *proto) +{ + if(proto) { + size_t n = protoset_index(protoset, proto); + + if(protoset[n]) { + size_t m = protoset_index(protoset, NULL) - 1; + + protoset[n] = protoset[m]; + protoset[m] = NULL; + } + } +} + +/* * Parse the string and provide an allocated libcurl compatible protocol * string output. Return non-zero on failure, zero on success. * @@ -270,48 +322,20 @@ ParameterError str2udouble(double *valp, const char *str, long max) * data. */ +#define MAX_PROTOSTRING (64*11) /* Enough room for 64 10-chars proto names. */ + ParameterError proto2num(struct OperationConfig *config, - unsigned int val, char **ostr, const char *str) + const char * const *val, char **ostr, const char *str) { char *buffer; const char *sep = ","; char *token; - char obuf[256] = ""; - size_t olen = sizeof(obuf); - char *optr; - struct sprotos const *pp; - - static struct sprotos { - const char *name; - unsigned int bit; - } const protos[] = { - { "all", (unsigned int)CURLPROTO_ALL }, - { "http", CURLPROTO_HTTP }, - { "https", CURLPROTO_HTTPS }, - { "ftp", CURLPROTO_FTP }, - { "ftps", CURLPROTO_FTPS }, - { "scp", CURLPROTO_SCP }, - { "sftp", CURLPROTO_SFTP }, - { "telnet", CURLPROTO_TELNET }, - { "ldap", CURLPROTO_LDAP }, - { "ldaps", CURLPROTO_LDAPS }, - { "mqtt", CURLPROTO_MQTT }, - { "dict", CURLPROTO_DICT }, - { "file", CURLPROTO_FILE }, - { "tftp", CURLPROTO_TFTP }, - { "imap", CURLPROTO_IMAP }, - { "imaps", CURLPROTO_IMAPS }, - { "pop3", CURLPROTO_POP3 }, - { "pop3s", CURLPROTO_POP3S }, - { "smtp", CURLPROTO_SMTP }, - { "smtps", CURLPROTO_SMTPS }, - { "rtsp", CURLPROTO_RTSP }, - { "gopher", CURLPROTO_GOPHER }, - { "gophers", CURLPROTO_GOPHERS }, - { "smb", CURLPROTO_SMB }, - { "smbs", CURLPROTO_SMBS }, - { NULL, 0 } - }; + const char **protoset; + struct curlx_dynbuf obuf; + size_t proto; + CURLcode result; + + curlx_dyn_init(&obuf, MAX_PROTOSTRING); if(!str) return PARAM_OPTION_AMBIGUOUS; @@ -320,6 +344,21 @@ ParameterError proto2num(struct OperationConfig *config, if(!buffer) return PARAM_NO_MEM; + protoset = malloc((proto_count + 1) * sizeof(*protoset)); + if(!protoset) { + free(buffer); + return PARAM_NO_MEM; + } + + /* Preset protocol set with default values. */ + protoset[0] = NULL; + for(; *val; val++) { + const char *p = proto_token(*val); + + if(p) + protoset_set(protoset, p); + } + /* Allow strtok() here since this isn't used threaded */ /* !checksrc! disable BANNEDFUNC 2 */ for(token = strtok(buffer, sep); @@ -340,49 +379,60 @@ ParameterError proto2num(struct OperationConfig *config, action = allow; break; default: /* Includes case of terminating NULL */ - Curl_safefree(buffer); + free(buffer); + free((char *) protoset); return PARAM_BAD_USE; } } - for(pp = protos; pp->name; pp++) { - if(curl_strequal(token, pp->name)) { + if(curl_strequal(token, "all")) { + switch(action) { + case deny: + protoset[0] = NULL; + break; + case allow: + case set: + memcpy((char *) protoset, + built_in_protos, (proto_count + 1) * sizeof(*protoset)); + break; + } + } + else { + const char *p = proto_token(token); + + if(p) switch(action) { case deny: - val &= ~(pp->bit); - break; - case allow: - val |= pp->bit; + protoset_clear(protoset, p); break; case set: - val = pp->bit; + protoset[0] = NULL; + /* FALLTHROUGH */ + case allow: + protoset_set(protoset, p); break; } - break; + else { /* unknown protocol */ + /* If they have specified only this protocol, we say treat it as + if no protocols are allowed */ + if(action == set) + protoset[0] = NULL; + warnf(config->global, "unrecognized protocol '%s'\n", token); } } - - if(!(pp->name)) { /* unknown protocol */ - /* If they have specified only this protocol, we say treat it as - if no protocols are allowed */ - if(action == set) - val = 0; - warnf(config->global, "unrecognized protocol '%s'\n", token); - } - } - Curl_safefree(buffer); - - optr = obuf; - for(pp = &protos[1]; pp->name; pp++) { - if(val & pp->bit) { - size_t n = msnprintf(optr, olen, "%s%s", - olen != sizeof(obuf) ? "," : "", - pp->name); - olen -= n; - optr += n; - } } - *ostr = strdup(obuf); + free(buffer); + + /* We need the protocols in alphabetic order for CI tests requirements. */ + qsort((char *) protoset, protoset_index(protoset, NULL), sizeof(*protoset), + struplocompare4sort); + + result = curlx_dyn_addn(&obuf, "", 0); + for(proto = 0; protoset[proto] && !result; proto++) + result = curlx_dyn_addf(&obuf, "%s,", protoset[proto]); + free((char *) protoset); + curlx_dyn_setlen(&obuf, curlx_dyn_len(&obuf) - 1); + *ostr = curlx_dyn_ptr(&obuf); return *ostr ? PARAM_OK : PARAM_NO_MEM; } @@ -397,14 +447,11 @@ ParameterError proto2num(struct OperationConfig *config, */ ParameterError check_protocol(const char *str) { - const char * const *pp; - const curl_version_info_data *curlinfo = curl_version_info(CURLVERSION_NOW); if(!str) return PARAM_REQUIRES_PARAMETER; - for(pp = curlinfo->protocols; *pp; pp++) { - if(curl_strequal(*pp, str)) - return PARAM_OK; - } + + if(proto_token(str)) + return PARAM_OK; return PARAM_LIBCURL_UNSUPPORTED_PROTOCOL; } |