setopt: add helper functions to setopt_long()

- Consistently keep options within ranges
- Reduce the maximum maxredirs value to fit a signed short
- Removed comments as the place to document the options is not here

Closes #18174
This commit is contained in:
Daniel Stenberg 2025-08-05 08:47:31 +02:00
parent b5d2e6e63f
commit b059f7deaf
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2
4 changed files with 51 additions and 216 deletions

View file

@ -217,7 +217,7 @@ dnscache_entry_is_stale(void *datap, void *hc)
* Returns the 'age' of the oldest still kept entry - in milliseconds. * Returns the 'age' of the oldest still kept entry - in milliseconds.
*/ */
static timediff_t static timediff_t
dnscache_prune(struct Curl_hash *hostcache, int cache_timeout_ms, dnscache_prune(struct Curl_hash *hostcache, timediff_t cache_timeout_ms,
struct curltime now) struct curltime now)
{ {
struct dnscache_prune_data user; struct dnscache_prune_data user;
@ -265,7 +265,7 @@ void Curl_dnscache_prune(struct Curl_easy *data)
struct Curl_dnscache *dnscache = dnscache_get(data); struct Curl_dnscache *dnscache = dnscache_get(data);
struct curltime now; struct curltime now;
/* the timeout may be set -1 (forever) */ /* the timeout may be set -1 (forever) */
int timeout_ms = data->set.dns_cache_timeout_ms; timediff_t timeout_ms = data->set.dns_cache_timeout_ms;
if(!dnscache || (timeout_ms == -1)) if(!dnscache || (timeout_ms == -1))
/* NULL hostcache means we cannot do it */ /* NULL hostcache means we cannot do it */

View file

@ -1323,7 +1323,7 @@ CURLcode Curl_http_follow(struct Curl_easy *data, const char *newurl,
data->info.wouldredirect = follow_url; data->info.wouldredirect = follow_url;
if(reachedmax) { if(reachedmax) {
failf(data, "Maximum (%ld) redirects followed", data->set.maxredirs); failf(data, "Maximum (%d) redirects followed", data->set.maxredirs);
return CURLE_TOO_MANY_REDIRECTS; return CURLE_TOO_MANY_REDIRECTS;
} }
return CURLE_OK; return CURLE_OK;

View file

@ -60,7 +60,6 @@
#include "curl_memory.h" #include "curl_memory.h"
#include "memdebug.h" #include "memdebug.h"
static CURLcode setopt_set_timeout_sec(timediff_t *ptimeout_ms, long secs) static CURLcode setopt_set_timeout_sec(timediff_t *ptimeout_ms, long secs)
{ {
if(secs < 0) if(secs < 0)
@ -854,6 +853,17 @@ static CURLcode setopt_bool(struct Curl_easy *data, CURLoption option,
return CURLE_OK; return CURLE_OK;
} }
static CURLcode value_range(long *value, long below_error, long min, long max)
{
if(*value < below_error)
return CURLE_BAD_FUNCTION_ARGUMENT;
else if(*value < min)
*value = min;
else if(*value > max)
*value = max;
return CURLE_OK;
}
static CURLcode setopt_long(struct Curl_easy *data, CURLoption option, static CURLcode setopt_long(struct Curl_easy *data, CURLoption option,
long arg) long arg)
{ {
@ -866,21 +876,13 @@ static CURLcode setopt_long(struct Curl_easy *data, CURLoption option,
switch(option) { switch(option) {
case CURLOPT_DNS_CACHE_TIMEOUT: case CURLOPT_DNS_CACHE_TIMEOUT:
if(arg < -1) return setopt_set_timeout_sec(&s->dns_cache_timeout_ms, arg);
return CURLE_BAD_FUNCTION_ARGUMENT;
else if(arg > INT_MAX/1000)
arg = INT_MAX/1000;
if(arg > 0)
arg *= 1000;
s->dns_cache_timeout_ms = (int)arg;
break;
case CURLOPT_CA_CACHE_TIMEOUT: case CURLOPT_CA_CACHE_TIMEOUT:
if(Curl_ssl_supports(data, SSLSUPP_CA_CACHE)) { if(Curl_ssl_supports(data, SSLSUPP_CA_CACHE)) {
if(arg < -1) result = value_range(&arg, -1, -1, INT_MAX);
return CURLE_BAD_FUNCTION_ARGUMENT; if(result)
else if(arg > INT_MAX) return result;
arg = INT_MAX;
s->general_ssl.ca_cache_timeout = (int)arg; s->general_ssl.ca_cache_timeout = (int)arg;
} }
@ -888,64 +890,38 @@ static CURLcode setopt_long(struct Curl_easy *data, CURLoption option,
return CURLE_NOT_BUILT_IN; return CURLE_NOT_BUILT_IN;
break; break;
case CURLOPT_MAXCONNECTS: case CURLOPT_MAXCONNECTS:
/* result = value_range(&arg, 1, 1, UINT_MAX);
* Set the absolute number of maximum simultaneous alive connection that if(result)
* libcurl is allowed to have. return result;
*/ s->maxconnects = (unsigned int)arg;
if(uarg > UINT_MAX)
return CURLE_BAD_FUNCTION_ARGUMENT;
s->maxconnects = (unsigned int)uarg;
break; break;
case CURLOPT_SERVER_RESPONSE_TIMEOUT: case CURLOPT_SERVER_RESPONSE_TIMEOUT:
/*
* Option that specifies how quickly a server response must be obtained
* before it is considered failure. For pingpong protocols.
*/
return setopt_set_timeout_sec(&s->server_response_timeout, arg); return setopt_set_timeout_sec(&s->server_response_timeout, arg);
case CURLOPT_SERVER_RESPONSE_TIMEOUT_MS: case CURLOPT_SERVER_RESPONSE_TIMEOUT_MS:
/*
* Option that specifies how quickly a server response must be obtained
* before it is considered failure. For pingpong protocols.
*/
return setopt_set_timeout_ms(&s->server_response_timeout, arg); return setopt_set_timeout_ms(&s->server_response_timeout, arg);
#ifndef CURL_DISABLE_TFTP #ifndef CURL_DISABLE_TFTP
case CURLOPT_TFTP_BLKSIZE: case CURLOPT_TFTP_BLKSIZE:
/* result = value_range(&arg, 0, TFTP_BLKSIZE_MIN, TFTP_BLKSIZE_MAX);
* TFTP option that specifies the block size to use for data transmission. if(result)
*/ return result;
if(arg < TFTP_BLKSIZE_MIN)
arg = 512;
else if(arg > TFTP_BLKSIZE_MAX)
arg = TFTP_BLKSIZE_MAX;
s->tftp_blksize = (unsigned short)arg; s->tftp_blksize = (unsigned short)arg;
break; break;
#endif #endif
#ifndef CURL_DISABLE_NETRC #ifndef CURL_DISABLE_NETRC
case CURLOPT_NETRC: case CURLOPT_NETRC:
/*
* Parse the $HOME/.netrc file
*/
if((arg < CURL_NETRC_IGNORED) || (arg >= CURL_NETRC_LAST)) if((arg < CURL_NETRC_IGNORED) || (arg >= CURL_NETRC_LAST))
return CURLE_BAD_FUNCTION_ARGUMENT; return CURLE_BAD_FUNCTION_ARGUMENT;
s->use_netrc = (unsigned char)arg; s->use_netrc = (unsigned char)arg;
break; break;
#endif #endif
case CURLOPT_TIMECONDITION: case CURLOPT_TIMECONDITION:
/*
* Set HTTP time condition. This must be one of the defines in the
* curl/curl.h header file.
*/
if((arg < CURL_TIMECOND_NONE) || (arg >= CURL_TIMECOND_LAST)) if((arg < CURL_TIMECOND_NONE) || (arg >= CURL_TIMECOND_LAST))
return CURLE_BAD_FUNCTION_ARGUMENT; return CURLE_BAD_FUNCTION_ARGUMENT;
s->timecondition = (unsigned char)arg; s->timecondition = (unsigned char)arg;
break; break;
case CURLOPT_TIMEVALUE: case CURLOPT_TIMEVALUE:
/*
* This is the value to compare with the remote document with the
* method set with CURLOPT_TIMECONDITION
*/
s->timevalue = (time_t)arg; s->timevalue = (time_t)arg;
break; break;
case CURLOPT_SSLVERSION: case CURLOPT_SSLVERSION:
@ -955,10 +931,6 @@ static CURLcode setopt_long(struct Curl_easy *data, CURLoption option,
return Curl_setopt_SSLVERSION(data, option, arg); return Curl_setopt_SSLVERSION(data, option, arg);
case CURLOPT_POSTFIELDSIZE: case CURLOPT_POSTFIELDSIZE:
/*
* The size of the POSTFIELD data to prevent libcurl to do strlen() to
* figure it out. Enables binary posts.
*/
if(arg < -1) if(arg < -1)
return CURLE_BAD_FUNCTION_ARGUMENT; return CURLE_BAD_FUNCTION_ARGUMENT;
@ -973,34 +945,19 @@ static CURLcode setopt_long(struct Curl_easy *data, CURLoption option,
break; break;
#ifndef CURL_DISABLE_HTTP #ifndef CURL_DISABLE_HTTP
case CURLOPT_FOLLOWLOCATION: case CURLOPT_FOLLOWLOCATION:
/*
* Follow Location: header hints on an HTTP-server.
*/
if(uarg > 3) if(uarg > 3)
return CURLE_BAD_FUNCTION_ARGUMENT; return CURLE_BAD_FUNCTION_ARGUMENT;
s->http_follow_mode = (unsigned char)uarg; s->http_follow_mode = (unsigned char)uarg;
break; break;
case CURLOPT_MAXREDIRS: case CURLOPT_MAXREDIRS:
/* result = value_range(&arg, -1, 0, 0x7fff);
* The maximum amount of hops you allow curl to follow Location: if(result)
* headers. This should mostly be used to detect never-ending loops. return result;
*/ s->maxredirs = (short)arg;
if(arg < -1)
return CURLE_BAD_FUNCTION_ARGUMENT;
s->maxredirs = arg;
break; break;
case CURLOPT_POSTREDIR: case CURLOPT_POSTREDIR:
/*
* Set the behavior of POST when redirecting
* CURL_REDIR_GET_ALL - POST is changed to GET after 301 and 302
* CURL_REDIR_POST_301 - POST is kept as POST after 301
* CURL_REDIR_POST_302 - POST is kept as POST after 302
* CURL_REDIR_POST_303 - POST is kept as POST after 303
* CURL_REDIR_POST_ALL - POST is kept as POST after 301, 302 and 303
* other - POST is kept as POST after 301 and 302
*/
if(arg < CURL_REDIR_GET_ALL) if(arg < CURL_REDIR_GET_ALL)
/* no return error on too high numbers since the bitmask could be /* no return error on too high numbers since the bitmask could be
extended in a future */ extended in a future */
@ -1009,9 +966,6 @@ static CURLcode setopt_long(struct Curl_easy *data, CURLoption option,
break; break;
case CURLOPT_HEADEROPT: case CURLOPT_HEADEROPT:
/*
* Set header option.
*/
s->sep_headers = !!(arg & CURLHEADER_SEPARATE); s->sep_headers = !!(arg & CURLHEADER_SEPARATE);
break; break;
case CURLOPT_HTTPAUTH: case CURLOPT_HTTPAUTH:
@ -1021,14 +975,9 @@ static CURLcode setopt_long(struct Curl_easy *data, CURLoption option,
return setopt_HTTP_VERSION(data, arg); return setopt_HTTP_VERSION(data, arg);
case CURLOPT_EXPECT_100_TIMEOUT_MS: case CURLOPT_EXPECT_100_TIMEOUT_MS:
/* result = value_range(&arg, 0, 0, 0xffff);
* Time to wait for a response to an HTTP request containing an if(result)
* Expect: 100-continue header before sending the data anyway. return result;
*/
if(arg < 0)
return CURLE_BAD_FUNCTION_ARGUMENT;
if(arg > 0xffff)
arg = 0xffff;
s->expect_100_timeout = (unsigned short)arg; s->expect_100_timeout = (unsigned short)arg;
break; break;
@ -1041,9 +990,6 @@ static CURLcode setopt_long(struct Curl_easy *data, CURLoption option,
#endif #endif
#ifndef CURL_DISABLE_PROXY #ifndef CURL_DISABLE_PROXY
case CURLOPT_PROXYPORT: case CURLOPT_PROXYPORT:
/*
* Explicitly set HTTP proxy port number.
*/
if((arg < 0) || (arg > 65535)) if((arg < 0) || (arg > 65535))
return CURLE_BAD_FUNCTION_ARGUMENT; return CURLE_BAD_FUNCTION_ARGUMENT;
s->proxyport = (unsigned short)arg; s->proxyport = (unsigned short)arg;
@ -1053,9 +999,6 @@ static CURLcode setopt_long(struct Curl_easy *data, CURLoption option,
return httpauth(data, TRUE, uarg); return httpauth(data, TRUE, uarg);
case CURLOPT_PROXYTYPE: case CURLOPT_PROXYTYPE:
/*
* Set proxy type.
*/
if((arg < CURLPROXY_HTTP) || (arg > CURLPROXY_SOCKS5_HOSTNAME)) if((arg < CURLPROXY_HTTP) || (arg > CURLPROXY_SOCKS5_HOSTNAME))
return CURLE_BAD_FUNCTION_ARGUMENT; return CURLE_BAD_FUNCTION_ARGUMENT;
s->proxytype = (unsigned char)arg; s->proxytype = (unsigned char)arg;
@ -1070,9 +1013,6 @@ static CURLcode setopt_long(struct Curl_easy *data, CURLoption option,
#ifndef CURL_DISABLE_FTP #ifndef CURL_DISABLE_FTP
case CURLOPT_FTP_FILEMETHOD: case CURLOPT_FTP_FILEMETHOD:
/*
* How do access files over FTP.
*/
if((arg < CURLFTPMETHOD_DEFAULT) || (arg >= CURLFTPMETHOD_LAST)) if((arg < CURLFTPMETHOD_DEFAULT) || (arg >= CURLFTPMETHOD_LAST))
return CURLE_BAD_FUNCTION_ARGUMENT; return CURLE_BAD_FUNCTION_ARGUMENT;
s->ftp_filemethod = (unsigned char)arg; s->ftp_filemethod = (unsigned char)arg;
@ -1084,89 +1024,53 @@ static CURLcode setopt_long(struct Curl_easy *data, CURLoption option,
break; break;
case CURLOPT_FTPSSLAUTH: case CURLOPT_FTPSSLAUTH:
/*
* Set a specific auth for FTP-SSL transfers.
*/
if((arg < CURLFTPAUTH_DEFAULT) || (arg >= CURLFTPAUTH_LAST)) if((arg < CURLFTPAUTH_DEFAULT) || (arg >= CURLFTPAUTH_LAST))
return CURLE_BAD_FUNCTION_ARGUMENT; return CURLE_BAD_FUNCTION_ARGUMENT;
s->ftpsslauth = (unsigned char)arg; s->ftpsslauth = (unsigned char)arg;
break; break;
case CURLOPT_ACCEPTTIMEOUT_MS: case CURLOPT_ACCEPTTIMEOUT_MS:
/*
* The maximum time for curl to wait for FTP server connect
*/
return setopt_set_timeout_ms(&s->accepttimeout, arg); return setopt_set_timeout_ms(&s->accepttimeout, arg);
#endif /* ! CURL_DISABLE_FTP */ #endif /* ! CURL_DISABLE_FTP */
#if !defined(CURL_DISABLE_FTP) || defined(USE_SSH) #if !defined(CURL_DISABLE_FTP) || defined(USE_SSH)
case CURLOPT_FTP_CREATE_MISSING_DIRS: case CURLOPT_FTP_CREATE_MISSING_DIRS:
/*
* An FTP/SFTP option that modifies an upload to create missing
* directories on the server.
*/
/* reserve other values for future use */
if((arg < CURLFTP_CREATE_DIR_NONE) || (arg > CURLFTP_CREATE_DIR_RETRY)) if((arg < CURLFTP_CREATE_DIR_NONE) || (arg > CURLFTP_CREATE_DIR_RETRY))
return CURLE_BAD_FUNCTION_ARGUMENT; return CURLE_BAD_FUNCTION_ARGUMENT;
s->ftp_create_missing_dirs = (unsigned char)arg; s->ftp_create_missing_dirs = (unsigned char)arg;
break; break;
#endif /* ! CURL_DISABLE_FTP || USE_SSH */ #endif /* ! CURL_DISABLE_FTP || USE_SSH */
case CURLOPT_INFILESIZE: case CURLOPT_INFILESIZE:
/*
* If known, this should inform curl about the file size of the
* to-be-uploaded file.
*/
if(arg < -1) if(arg < -1)
return CURLE_BAD_FUNCTION_ARGUMENT; return CURLE_BAD_FUNCTION_ARGUMENT;
s->filesize = arg; s->filesize = arg;
break; break;
case CURLOPT_LOW_SPEED_LIMIT: case CURLOPT_LOW_SPEED_LIMIT:
/*
* The low speed limit that if transfers are below this for
* CURLOPT_LOW_SPEED_TIME, the transfer is aborted.
*/
if(arg < 0) if(arg < 0)
return CURLE_BAD_FUNCTION_ARGUMENT; return CURLE_BAD_FUNCTION_ARGUMENT;
s->low_speed_limit = arg; s->low_speed_limit = arg;
break; break;
case CURLOPT_LOW_SPEED_TIME: case CURLOPT_LOW_SPEED_TIME:
/*
* The low speed time that if transfers are below the set
* CURLOPT_LOW_SPEED_LIMIT during this time, the transfer is aborted.
*/
if(arg < 0) if(arg < 0)
return CURLE_BAD_FUNCTION_ARGUMENT; return CURLE_BAD_FUNCTION_ARGUMENT;
s->low_speed_time = arg; s->low_speed_time = arg;
break; break;
case CURLOPT_PORT: case CURLOPT_PORT:
/*
* The port number to use when getting the URL. 0 disables it.
*/
if((arg < 0) || (arg > 65535)) if((arg < 0) || (arg > 65535))
return CURLE_BAD_FUNCTION_ARGUMENT; return CURLE_BAD_FUNCTION_ARGUMENT;
s->use_port = (unsigned short)arg; s->use_port = (unsigned short)arg;
break; break;
case CURLOPT_TIMEOUT: case CURLOPT_TIMEOUT:
/*
* The maximum time you allow curl to use for a single transfer
* operation.
*/
return setopt_set_timeout_sec(&s->timeout, arg); return setopt_set_timeout_sec(&s->timeout, arg);
case CURLOPT_TIMEOUT_MS: case CURLOPT_TIMEOUT_MS:
return setopt_set_timeout_ms(&s->timeout, arg); return setopt_set_timeout_ms(&s->timeout, arg);
case CURLOPT_CONNECTTIMEOUT: case CURLOPT_CONNECTTIMEOUT:
/*
* The maximum time you allow curl to use to connect.
*/
return setopt_set_timeout_sec(&s->connecttimeout, arg); return setopt_set_timeout_sec(&s->connecttimeout, arg);
case CURLOPT_CONNECTTIMEOUT_MS: case CURLOPT_CONNECTTIMEOUT_MS:
return setopt_set_timeout_ms(&s->connecttimeout, arg); return setopt_set_timeout_ms(&s->connecttimeout, arg);
case CURLOPT_RESUME_FROM: case CURLOPT_RESUME_FROM:
/*
* Resume transfer at the given file position
*/
if(arg < -1) if(arg < -1)
return CURLE_BAD_FUNCTION_ARGUMENT; return CURLE_BAD_FUNCTION_ARGUMENT;
s->set_resume_from = arg; s->set_resume_from = arg;
@ -1174,17 +1078,11 @@ static CURLcode setopt_long(struct Curl_easy *data, CURLoption option,
#ifndef CURL_DISABLE_BINDLOCAL #ifndef CURL_DISABLE_BINDLOCAL
case CURLOPT_LOCALPORT: case CURLOPT_LOCALPORT:
/*
* Set what local port to bind the socket to when performing an operation.
*/
if((arg < 0) || (arg > 65535)) if((arg < 0) || (arg > 65535))
return CURLE_BAD_FUNCTION_ARGUMENT; return CURLE_BAD_FUNCTION_ARGUMENT;
s->localport = curlx_sltous(arg); s->localport = curlx_sltous(arg);
break; break;
case CURLOPT_LOCALPORTRANGE: case CURLOPT_LOCALPORTRANGE:
/*
* Set number of local ports to try, starting with CURLOPT_LOCALPORT.
*/
if((arg < 0) || (arg > 65535)) if((arg < 0) || (arg > 65535))
return CURLE_BAD_FUNCTION_ARGUMENT; return CURLE_BAD_FUNCTION_ARGUMENT;
s->localportrange = curlx_sltous(arg); s->localportrange = curlx_sltous(arg);
@ -1193,51 +1091,28 @@ static CURLcode setopt_long(struct Curl_easy *data, CURLoption option,
#ifdef HAVE_GSSAPI #ifdef HAVE_GSSAPI
case CURLOPT_GSSAPI_DELEGATION: case CURLOPT_GSSAPI_DELEGATION:
/*
* GSS-API credential delegation bitmask
*/
s->gssapi_delegation = (unsigned char)uarg& s->gssapi_delegation = (unsigned char)uarg&
(CURLGSSAPI_DELEGATION_POLICY_FLAG|CURLGSSAPI_DELEGATION_FLAG); (CURLGSSAPI_DELEGATION_POLICY_FLAG|CURLGSSAPI_DELEGATION_FLAG);
break; break;
#endif #endif
case CURLOPT_SSL_FALSESTART: case CURLOPT_SSL_FALSESTART:
/*
* No TLS backends support false start anymore.
*/
return CURLE_NOT_BUILT_IN; return CURLE_NOT_BUILT_IN;
case CURLOPT_BUFFERSIZE: case CURLOPT_BUFFERSIZE:
/* result = value_range(&arg, 0, READBUFFER_MIN, READBUFFER_MAX);
* The application kindly asks for a differently sized receive buffer. if(result)
* If it seems reasonable, we will use it. return result;
*/
if(arg > READBUFFER_MAX)
arg = READBUFFER_MAX;
else if(arg < 1)
arg = READBUFFER_SIZE;
else if(arg < READBUFFER_MIN)
arg = READBUFFER_MIN;
s->buffer_size = (unsigned int)arg; s->buffer_size = (unsigned int)arg;
break; break;
case CURLOPT_UPLOAD_BUFFERSIZE: case CURLOPT_UPLOAD_BUFFERSIZE:
/* result = value_range(&arg, 0, UPLOADBUFFER_MIN, UPLOADBUFFER_MAX);
* The application kindly asks for a differently sized upload buffer. if(result)
* Cap it to sensible. return result;
*/
if(arg > UPLOADBUFFER_MAX)
arg = UPLOADBUFFER_MAX;
else if(arg < UPLOADBUFFER_MIN)
arg = UPLOADBUFFER_MIN;
s->upload_buffer_size = (unsigned int)arg; s->upload_buffer_size = (unsigned int)arg;
break; break;
case CURLOPT_MAXFILESIZE: case CURLOPT_MAXFILESIZE:
/*
* Set the maximum size of a file to download.
*/
if(arg < 0) if(arg < 0)
return CURLE_BAD_FUNCTION_ARGUMENT; return CURLE_BAD_FUNCTION_ARGUMENT;
s->max_filesize = arg; s->max_filesize = arg;
@ -1245,9 +1120,6 @@ static CURLcode setopt_long(struct Curl_easy *data, CURLoption option,
#ifdef USE_SSL #ifdef USE_SSL
case CURLOPT_USE_SSL: case CURLOPT_USE_SSL:
/*
* Make transfers attempt to use SSL/TLS.
*/
if((arg < CURLUSESSL_NONE) || (arg >= CURLUSESSL_LAST)) if((arg < CURLUSESSL_NONE) || (arg >= CURLUSESSL_LAST))
return CURLE_BAD_FUNCTION_ARGUMENT; return CURLE_BAD_FUNCTION_ARGUMENT;
s->use_ssl = (unsigned char)arg; s->use_ssl = (unsigned char)arg;
@ -1270,12 +1142,7 @@ static CURLcode setopt_long(struct Curl_easy *data, CURLoption option,
break; break;
case CURLOPT_CONNECT_ONLY: case CURLOPT_CONNECT_ONLY:
/* if(arg < 0 || arg > 2)
* No data transfer.
* (1) - only do connection
* (2) - do first get request but get no content
*/
if(arg > 2)
return CURLE_BAD_FUNCTION_ARGUMENT; return CURLE_BAD_FUNCTION_ARGUMENT;
s->connect_only = !!arg; s->connect_only = !!arg;
s->connect_only_ws = (arg == 2); s->connect_only_ws = (arg == 2);
@ -1283,7 +1150,6 @@ static CURLcode setopt_long(struct Curl_easy *data, CURLoption option,
#ifdef USE_SSH #ifdef USE_SSH
/* we only include SSH options if explicitly built to support SSH */
case CURLOPT_SSH_AUTH_TYPES: case CURLOPT_SSH_AUTH_TYPES:
s->ssh_auth_types = (int)arg; s->ssh_auth_types = (int)arg;
break; break;
@ -1291,9 +1157,6 @@ static CURLcode setopt_long(struct Curl_easy *data, CURLoption option,
#if !defined(CURL_DISABLE_FTP) || defined(USE_SSH) #if !defined(CURL_DISABLE_FTP) || defined(USE_SSH)
case CURLOPT_NEW_FILE_PERMS: case CURLOPT_NEW_FILE_PERMS:
/*
* Uses these permissions instead of 0644
*/
if((arg < 0) || (arg > 0777)) if((arg < 0) || (arg > 0777))
return CURLE_BAD_FUNCTION_ARGUMENT; return CURLE_BAD_FUNCTION_ARGUMENT;
s->new_file_perms = (unsigned int)arg; s->new_file_perms = (unsigned int)arg;
@ -1301,9 +1164,6 @@ static CURLcode setopt_long(struct Curl_easy *data, CURLoption option,
#endif #endif
#ifdef USE_SSH #ifdef USE_SSH
case CURLOPT_NEW_DIRECTORY_PERMS: case CURLOPT_NEW_DIRECTORY_PERMS:
/*
* Uses these permissions instead of 0755
*/
if((arg < 0) || (arg > 0777)) if((arg < 0) || (arg > 0777))
return CURLE_BAD_FUNCTION_ARGUMENT; return CURLE_BAD_FUNCTION_ARGUMENT;
s->new_directory_perms = (unsigned int)arg; s->new_directory_perms = (unsigned int)arg;
@ -1311,11 +1171,6 @@ static CURLcode setopt_long(struct Curl_easy *data, CURLoption option,
#endif #endif
#ifdef USE_IPV6 #ifdef USE_IPV6
case CURLOPT_ADDRESS_SCOPE: case CURLOPT_ADDRESS_SCOPE:
/*
* Use this scope id when using IPv6
* We always get longs when passed plain numericals so we should check
* that the value fits into an unsigned 32-bit integer.
*/
#if SIZEOF_LONG > 4 #if SIZEOF_LONG > 4
if(uarg > UINT_MAX) if(uarg > UINT_MAX)
return CURLE_BAD_FUNCTION_ARGUMENT; return CURLE_BAD_FUNCTION_ARGUMENT;
@ -1324,17 +1179,10 @@ static CURLcode setopt_long(struct Curl_easy *data, CURLoption option,
break; break;
#endif #endif
case CURLOPT_PROTOCOLS: case CURLOPT_PROTOCOLS:
/* set the bitmask for the protocols that are allowed to be used for the
transfer, which thus helps the app which takes URLs from users or other
external inputs and want to restrict what protocol(s) to deal with.
Defaults to CURLPROTO_ALL. */
s->allowed_protocols = (curl_prot_t)arg; s->allowed_protocols = (curl_prot_t)arg;
break; break;
case CURLOPT_REDIR_PROTOCOLS: case CURLOPT_REDIR_PROTOCOLS:
/* set the bitmask for the protocols that libcurl is allowed to follow to,
as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol
needs to be set in both bitmasks to be allowed to get redirected to. */
s->redir_protocols = (curl_prot_t)arg; s->redir_protocols = (curl_prot_t)arg;
break; break;
@ -1342,40 +1190,31 @@ static CURLcode setopt_long(struct Curl_easy *data, CURLoption option,
case CURLOPT_RTSP_REQUEST: case CURLOPT_RTSP_REQUEST:
return setopt_RTSP_REQUEST(data, arg); return setopt_RTSP_REQUEST(data, arg);
case CURLOPT_RTSP_CLIENT_CSEQ: case CURLOPT_RTSP_CLIENT_CSEQ:
/*
* Set the CSEQ number to issue for the next RTSP request. Useful if the
* application is resuming a previously broken connection. The CSEQ
* will increment from this new number henceforth.
*/
data->state.rtsp_next_client_CSeq = arg; data->state.rtsp_next_client_CSeq = arg;
break; break;
case CURLOPT_RTSP_SERVER_CSEQ: case CURLOPT_RTSP_SERVER_CSEQ:
/* Same as the above, but for server-initiated requests */
data->state.rtsp_next_server_CSeq = arg; data->state.rtsp_next_server_CSeq = arg;
break; break;
#endif /* ! CURL_DISABLE_RTSP */ #endif /* ! CURL_DISABLE_RTSP */
case CURLOPT_TCP_KEEPIDLE: case CURLOPT_TCP_KEEPIDLE:
if(arg < 0) result = value_range(&arg, 0, 0, INT_MAX);
return CURLE_BAD_FUNCTION_ARGUMENT; if(result)
else if(arg > INT_MAX) return result;
arg = INT_MAX;
s->tcp_keepidle = (int)arg; s->tcp_keepidle = (int)arg;
break; break;
case CURLOPT_TCP_KEEPINTVL: case CURLOPT_TCP_KEEPINTVL:
if(arg < 0) result = value_range(&arg, 0, 0, INT_MAX);
return CURLE_BAD_FUNCTION_ARGUMENT; if(result)
else if(arg > INT_MAX) return result;
arg = INT_MAX;
s->tcp_keepintvl = (int)arg; s->tcp_keepintvl = (int)arg;
break; break;
case CURLOPT_TCP_KEEPCNT: case CURLOPT_TCP_KEEPCNT:
if(arg < 0) result = value_range(&arg, 0, 0, INT_MAX);
return CURLE_BAD_FUNCTION_ARGUMENT; if(result)
else if(arg > INT_MAX) return result;
arg = INT_MAX;
s->tcp_keepcnt = (int)arg; s->tcp_keepcnt = (int)arg;
break; break;
case CURLOPT_SSL_ENABLE_NPN: case CURLOPT_SSL_ENABLE_NPN:
@ -1438,16 +1277,12 @@ static CURLcode setopt_long(struct Curl_easy *data, CURLoption option,
/* deprecated */ /* deprecated */
break; break;
case CURLOPT_SSLENGINE_DEFAULT: case CURLOPT_SSLENGINE_DEFAULT:
/*
* flag to set engine as default.
*/
Curl_safefree(s->str[STRING_SSL_ENGINE]); Curl_safefree(s->str[STRING_SSL_ENGINE]);
return Curl_ssl_set_engine_default(data); return Curl_ssl_set_engine_default(data);
case CURLOPT_UPLOAD_FLAGS: case CURLOPT_UPLOAD_FLAGS:
s->upload_flags = (unsigned char)arg; s->upload_flags = (unsigned char)arg;
break; break;
default: default:
/* unknown option */
return CURLE_UNKNOWN_OPTION; return CURLE_UNKNOWN_OPTION;
} }
return CURLE_OK; return CURLE_OK;

View file

@ -1348,8 +1348,6 @@ struct UserDefined {
void *writeheader; /* write the header to this if non-NULL */ void *writeheader; /* write the header to this if non-NULL */
unsigned long httpauth; /* kind of HTTP authentication to use (bitmask) */ unsigned long httpauth; /* kind of HTTP authentication to use (bitmask) */
unsigned long proxyauth; /* kind of proxy authentication to use (bitmask) */ unsigned long proxyauth; /* kind of proxy authentication to use (bitmask) */
long maxredirs; /* maximum no. of http(s) redirects to follow, set to -1
for infinity */
void *postfields; /* if POST, set the fields' values here */ void *postfields; /* if POST, set the fields' values here */
curl_seek_callback seek_func; /* function that seeks the input */ curl_seek_callback seek_func; /* function that seeks the input */
curl_off_t postfieldsize; /* if POST, this might have a size to use instead curl_off_t postfieldsize; /* if POST, this might have a size to use instead
@ -1419,7 +1417,7 @@ struct UserDefined {
unsigned char socks5auth;/* kind of SOCKS5 authentication to use (bitmask) */ unsigned char socks5auth;/* kind of SOCKS5 authentication to use (bitmask) */
#endif #endif
struct ssl_general_config general_ssl; /* general user defined SSL stuff */ struct ssl_general_config general_ssl; /* general user defined SSL stuff */
int dns_cache_timeout_ms; /* DNS cache timeout (milliseconds) */ timediff_t dns_cache_timeout_ms; /* DNS cache timeout (milliseconds) */
unsigned int buffer_size; /* size of receive buffer to use */ unsigned int buffer_size; /* size of receive buffer to use */
unsigned int upload_buffer_size; /* size of upload buffer to use, unsigned int upload_buffer_size; /* size of upload buffer to use,
keep it >= CURL_MAX_WRITE_SIZE */ keep it >= CURL_MAX_WRITE_SIZE */
@ -1501,6 +1499,8 @@ struct UserDefined {
#ifdef USE_ECH #ifdef USE_ECH
int tls_ech; /* TLS ECH configuration */ int tls_ech; /* TLS ECH configuration */
#endif #endif
short maxredirs; /* maximum no. of http(s) redirects to follow,
set to -1 for infinity */
unsigned short expect_100_timeout; /* in milliseconds */ unsigned short expect_100_timeout; /* in milliseconds */
unsigned short use_port; /* which port to use (when not using default) */ unsigned short use_port; /* which port to use (when not using default) */
#ifndef CURL_DISABLE_BINDLOCAL #ifndef CURL_DISABLE_BINDLOCAL