urldata: convert 'long' fields to fixed variable types

Makes sure they work identically cross-platform, as long varies in size
between Windows vs non-Windows. Makes Curl_easy 16 bytes smaller on 64
bit Linux.

This reduces support for the RTSP cseq counters to 32 bit (down from 63
bit previously on 64 bit non-Windows), but it is probably safe.
Implementations probably rarely support anything above 32 bits anyway
and this is how curl has worked on Windows since always.

There is now only one 'long' left in urldata.h (in the ssl_config_data
struct). That field, certverifyresult, is used to store the response
code from TLS backend code and in the OpenSSL case that function returns
an actual 'long'.

Closes #20227
This commit is contained in:
Daniel Stenberg
2026-01-08 23:57:58 +01:00
parent 3402036e1a
commit d881b91133
5 changed files with 42 additions and 35 deletions

View File

@@ -281,7 +281,12 @@ static CURLcode getinfo_long(struct Curl_easy *data, CURLINFO info,
*param_longp = data->state.os_errno;
break;
case CURLINFO_NUM_CONNECTS:
*param_longp = data->info.numconnects;
#if SIZEOF_LONG < SIZEOF_CURL_OFF_T
if(data->info.numconnects > LONG_MAX)
*param_longp = LONG_MAX;
else
#endif
*param_longp = (long)data->info.numconnects;
break;
case CURLINFO_LASTSOCKET:
sockfd = Curl_getconnectinfo(data, NULL);

View File

@@ -152,11 +152,9 @@ UNITTEST CURLcode pgrs_speedcheck(struct Curl_easy *data,
if(howlong >= data->set.low_speed_time * 1000) {
/* too long */
failf(data,
"Operation too slow. "
"Less than %ld bytes/sec transferred the last %ld seconds",
data->set.low_speed_limit,
data->set.low_speed_time);
failf(data, "Operation too slow. Less than %" FMT_OFF_T
" bytes/sec transferred the last %u seconds",
data->set.low_speed_limit, data->set.low_speed_time);
return CURLE_OPERATION_TIMEDOUT;
}
}

View File

@@ -66,8 +66,8 @@ struct rtsp_conn {
/* RTSP transfer data */
struct RTSP {
long CSeq_sent; /* CSeq of this request */
long CSeq_recv; /* CSeq received */
uint32_t CSeq_sent; /* CSeq of this request */
uint32_t CSeq_recv; /* CSeq received */
};
#define RTP_PKT_LENGTH(p) ((((unsigned int)((unsigned char)((p)[2]))) << 8) | \
@@ -245,16 +245,16 @@ static CURLcode rtsp_done(struct Curl_easy *data,
if(!status && !httpStatus) {
/* Check the sequence numbers */
long CSeq_sent = rtsp->CSeq_sent;
long CSeq_recv = rtsp->CSeq_recv;
uint32_t CSeq_sent = rtsp->CSeq_sent;
uint32_t CSeq_recv = rtsp->CSeq_recv;
if((data->set.rtspreq != RTSPREQ_RECEIVE) && (CSeq_sent != CSeq_recv)) {
failf(data,
"The CSeq of this request %ld did not match the response %ld",
"The CSeq of this request %u did not match the response %u",
CSeq_sent, CSeq_recv);
return CURLE_RTSP_CSEQ_ERROR;
}
if(data->set.rtspreq == RTSPREQ_RECEIVE && (rtspc->rtp_channel == -1)) {
infof(data, "Got an RTP Receive with a CSeq of %ld", CSeq_recv);
infof(data, "Got an RTP Receive with a CSeq of %u", CSeq_recv);
}
if(data->set.rtspreq == RTSPREQ_RECEIVE &&
data->req.eos_written) {
@@ -346,11 +346,11 @@ static CURLcode rtsp_do(struct Curl_easy *data, bool *done)
{
struct connectdata *conn = data->conn;
CURLcode result = CURLE_OK;
Curl_RtspReq rtspreq = data->set.rtspreq;
const Curl_RtspReq rtspreq = data->set.rtspreq;
struct RTSP *rtsp = Curl_meta_get(data, CURL_META_RTSP_EASY);
struct dynbuf req_buffer;
unsigned char httpversion = 11; /* RTSP is close to HTTP/1.1, sort of... */
const unsigned char httpversion = 11; /* RTSP is close to HTTP/1.1, sort
of... */
const char *p_request = NULL;
const char *p_session_id = NULL;
const char *p_accept = NULL;
@@ -573,7 +573,7 @@ static CURLcode rtsp_do(struct Curl_easy *data, bool *done)
result =
curlx_dyn_addf(&req_buffer,
"%s %s RTSP/1.0\r\n" /* Request Stream-URI RTSP/1.0 */
"CSeq: %ld\r\n", /* CSeq */
"CSeq: %u\r\n", /* CSeq */
p_request, p_stream_uri, rtsp->CSeq_sent);
if(result)
goto out;
@@ -995,12 +995,11 @@ CURLcode Curl_rtsp_parseheader(struct Curl_easy *data, const char *header)
if(!rtsp)
return CURLE_FAILED_INIT;
curlx_str_passblanks(&p);
if(curlx_str_number(&p, &CSeq, LONG_MAX)) {
if(curlx_str_number(&p, &CSeq, UINT_MAX)) {
failf(data, "Unable to read the CSeq header: [%s]", header);
return CURLE_RTSP_CSEQ_ERROR;
}
rtsp->CSeq_recv = (long)CSeq; /* mark the request */
data->state.rtsp_CSeq_recv = (long)CSeq; /* update the handle */
data->state.rtsp_CSeq_recv = rtsp->CSeq_recv = (uint32_t)CSeq;
}
else if(checkprefix("Session:", header)) {
const char *start, *end;

View File

@@ -1050,9 +1050,10 @@ static CURLcode setopt_long(struct Curl_easy *data, CURLoption option,
s->low_speed_limit = arg;
break;
case CURLOPT_LOW_SPEED_TIME:
if(arg < 0)
return CURLE_BAD_FUNCTION_ARGUMENT;
s->low_speed_time = arg;
result = value_range(&arg, 0, 0, USHRT_MAX);
if(result)
return result;
s->low_speed_time = (uint16_t)arg;
break;
case CURLOPT_PORT:
if((arg < 0) || (arg > 65535))
@@ -1190,11 +1191,17 @@ static CURLcode setopt_long(struct Curl_easy *data, CURLoption option,
case CURLOPT_RTSP_REQUEST:
return setopt_RTSP_REQUEST(data, arg);
case CURLOPT_RTSP_CLIENT_CSEQ:
data->state.rtsp_next_client_CSeq = arg;
result = value_range(&arg, 0, 0, INT_MAX);
if(result)
return result;
data->state.rtsp_next_client_CSeq = (uint32_t)arg;
break;
case CURLOPT_RTSP_SERVER_CSEQ:
data->state.rtsp_next_server_CSeq = arg;
result = value_range(&arg, 0, 0, INT_MAX);
if(result)
return result;
data->state.rtsp_next_server_CSeq = (uint32_t)arg;
break;
#endif /* !CURL_DISABLE_RTSP */
@@ -1231,9 +1238,7 @@ static CURLcode setopt_long(struct Curl_easy *data, CURLoption option,
return setopt_set_timeout_ms(&s->happy_eyeballs_timeout, arg);
case CURLOPT_UPKEEP_INTERVAL_MS:
if(arg < 0)
return CURLE_BAD_FUNCTION_ARGUMENT;
s->upkeep_interval_ms = arg;
return setopt_set_timeout_ms(&s->upkeep_interval_ms, arg);
break;
case CURLOPT_MAXAGE_CONN:
return setopt_set_timeout_sec(&s->conn_max_idle_ms, arg);

View File

@@ -753,11 +753,11 @@ struct PureInfo {
time_t filetime; /* If requested, this is might get set. Set to -1 if the
time was unretrievable. */
curl_off_t request_size; /* the amount of bytes sent in the request(s) */
curl_off_t numconnects; /* how many new connections libcurl created */
uint32_t proxyauthavail; /* what proxy auth types were announced */
uint32_t httpauthavail; /* what host auth types were announced */
uint32_t proxyauthpicked; /* selected proxy auth type */
uint32_t httpauthpicked; /* selected host auth type */
long numconnects; /* how many new connection did libcurl created */
char *contenttype; /* the content type of the object */
char *wouldredirect; /* URL this would have been redirected to if asked to */
curl_off_t retry_after; /* info from Retry-After: header */
@@ -998,10 +998,9 @@ struct UrlState {
#ifndef CURL_DISABLE_RTSP
/* This RTSP state information survives requests and connections */
long rtsp_next_client_CSeq; /* the session's next client CSeq */
long rtsp_next_server_CSeq; /* the session's next server CSeq */
long rtsp_CSeq_recv; /* most recent CSeq received */
uint32_t rtsp_next_client_CSeq; /* the session's next client CSeq */
uint32_t rtsp_next_server_CSeq; /* the session's next server CSeq */
uint32_t rtsp_CSeq_recv; /* most recent CSeq received */
uint8_t rtp_channel_mask[32]; /* for the correctness checking of the
interleaved data */
#endif
@@ -1334,8 +1333,7 @@ struct UserDefined {
timediff_t conn_max_age_ms; /* max time since creation to allow a
connection that is to be reused */
curl_off_t filesize; /* size of file to upload, -1 means unknown */
long low_speed_limit; /* bytes/second */
long low_speed_time; /* number of seconds */
curl_off_t low_speed_limit; /* bytes/second */
curl_off_t max_send_speed; /* high speed limit in bytes/second for upload */
curl_off_t max_recv_speed; /* high speed limit in bytes/second for
download */
@@ -1433,7 +1431,8 @@ struct UserDefined {
curl_resolver_start_callback resolver_start; /* optional callback called
before resolver start */
void *resolver_start_client; /* pointer to pass to resolver start callback */
long upkeep_interval_ms; /* Time between calls for connection upkeep. */
timediff_t upkeep_interval_ms; /* Time between calls for connection
upkeep. */
CURLU *uh; /* URL handle for the current parsed URL */
#ifndef CURL_DISABLE_HTTP
void *trailer_data; /* pointer to pass to trailer data callback */
@@ -1450,6 +1449,7 @@ struct UserDefined {
set to -1 for infinity */
uint16_t expect_100_timeout; /* in milliseconds */
uint16_t use_port; /* which port to use (when not using default) */
uint16_t low_speed_time; /* number of seconds */
#ifndef CURL_DISABLE_BINDLOCAL
uint16_t localport; /* local port number to bind to */
uint16_t localportrange; /* number of additional port numbers to test