lib: eliminate size_t casts

Add new functions in `curlx/warnless.h` for controlled type
conversions:

* curlx_uitouz, convert unsigned into to size_t (should always work)
* curlx_uztoso, convert size_t to curl_off_t, capping at CURL_OFF_T_MAX
* curlx_sztouz, convert ssize_t to size_t, return TRUE when ok
* curlx_sotouz_range, convert curl_off_t to size_t interval, capping
  values to interval bounds

Remove some unnecesary casts, convert some internal recv functions
to the "return result, have size_t* arg" pattern.

Closes #19495
This commit is contained in:
Stefan Eissing 2025-11-12 15:58:49 +01:00 committed by Daniel Stenberg
parent 78a610cb83
commit cb2bcb681f
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
13 changed files with 170 additions and 156 deletions

View File

@ -268,7 +268,7 @@ static CURLcode send_CONNECT(struct Curl_cfilter *cf,
DEBUGASSERT(blen >= nwritten);
ts->nsent += nwritten;
Curl_debug(data, CURLINFO_HEADER_OUT, buf, (size_t)nwritten);
Curl_debug(data, CURLINFO_HEADER_OUT, buf, nwritten);
out:
if(result)

View File

@ -847,7 +847,7 @@ static int tunnel_recv_callback(nghttp2_session *session, uint8_t flags,
#endif
}
/* tunnel.recbuf has soft limit, any success MUST add all data */
DEBUGASSERT((size_t)nwritten == len);
DEBUGASSERT(nwritten == len);
return 0;
}

View File

@ -290,3 +290,38 @@ size_t curlx_sitouz(int sinum)
# pragma warning(pop)
#endif
}
size_t curlx_uitouz(unsigned int uinum)
{
return (size_t)uinum;
}
size_t curlx_sotouz_range(curl_off_t sonum, size_t uzmin, size_t uzmax)
{
if(sonum < 0)
return uzmin;
#if SIZEOF_CURL_OFF_T > SIZEOF_SIZE_T
if(sonum > SIZE_MAX)
return uzmax;
#endif
return CURLMIN(CURLMAX((size_t)sonum, uzmin), uzmax);
}
bool curlx_sztouz(ssize_t sznum, size_t *puznum)
{
if(sznum < 0) {
*puznum = 0;
return FALSE;
}
*puznum = (size_t)sznum;
return TRUE;
}
curl_off_t curlx_uztoso(size_t uznum)
{
#if SIZEOF_SIZE_T >= SIZEOF_CURL_OFF_T
if(uznum > (size_t)CURL_OFF_T_MAX)
return CURL_OFF_T_MAX;
#endif
return (curl_off_t)uznum;
}

View File

@ -57,6 +57,18 @@ unsigned short curlx_uitous(unsigned int uinum);
size_t curlx_sitouz(int sinum);
size_t curlx_uitouz(unsigned int uinum);
/* Convert a curl_off_t to fit into size_t interval [uzmin, uzmax].
* values outside this interval give the lower/upper bound. */
size_t curlx_sotouz_range(curl_off_t sonum, size_t uzmin, size_t uzmax);
/* Convert a size_t to curl_off_t, return CURL_OFF_T_MAX if too large. */
curl_off_t curlx_uztoso(size_t uznum);
/* Convert a ssize_t to size_t, return FALSE if negative and set 0 */
bool curlx_sztouz(ssize_t sznum, size_t *puznum);
#ifdef _WIN32
#undef read
#define read(fd, buf, count) (ssize_t)_read(fd, buf, curlx_uztoui(count))

View File

@ -160,9 +160,9 @@ static CURLcode sendf(struct Curl_easy *data, const char *fmt, ...)
if(result)
break;
Curl_debug(data, CURLINFO_DATA_OUT, sptr, (size_t)bytes_written);
Curl_debug(data, CURLINFO_DATA_OUT, sptr, bytes_written);
if((size_t)bytes_written != write_len) {
if(bytes_written != write_len) {
/* if not all was written at once, we must advance the pointer, decrease
the size left and try again! */
write_len -= bytes_written;

View File

@ -2222,9 +2222,11 @@ static CURLcode set_reader(struct Curl_easy *data, Curl_HttpReq httpreq)
result = Curl_creader_set_null(data);
}
else if(data->set.postfields) {
if(postsize > 0)
result = Curl_creader_set_buf(data, data->set.postfields,
(size_t)postsize);
size_t plen = curlx_sotouz_range(postsize, 0, SIZE_MAX);
if(plen == SIZE_MAX)
return CURLE_OUT_OF_MEMORY;
else if(plen)
result = Curl_creader_set_buf(data, data->set.postfields, plen);
else
result = Curl_creader_set_null(data);
}

View File

@ -45,6 +45,7 @@
#include "curlx/strparse.h"
#include "transfer.h"
#include "curlx/dynbuf.h"
#include "curlx/warnless.h"
#include "headers.h"
/* The last 3 #include files should be in this order */
@ -539,10 +540,12 @@ static CURLcode cf_h2_ctx_open(struct Curl_cfilter *cf,
* in the H1 request and we upgrade from there. This stream
* is opened implicitly as #1. */
uint8_t binsettings[H2_BINSETTINGS_LEN];
ssize_t binlen; /* length of the binsettings data */
ssize_t rclen;
size_t binlen; /* length of the binsettings data */
binlen = populate_binsettings(binsettings, data);
if(binlen <= 0) {
rclen = populate_binsettings(binsettings, data);
if(!curlx_sztouz(rclen, &binlen) || !binlen) {
failf(data, "nghttp2 unexpectedly failed on pack_settings_payload");
result = CURLE_FAILED_INIT;
goto out;
@ -554,7 +557,7 @@ static CURLcode cf_h2_ctx_open(struct Curl_cfilter *cf,
DEBUGASSERT(stream);
stream->id = 1;
/* queue SETTINGS frame (again) */
rc = nghttp2_session_upgrade2(ctx->h2, binsettings, (size_t)binlen,
rc = nghttp2_session_upgrade2(ctx->h2, binsettings, binlen,
data->state.httpreq == HTTPREQ_HEAD,
NULL);
if(rc) {
@ -627,16 +630,16 @@ static CURLcode h2_process_pending_input(struct Curl_cfilter *cf,
{
struct cf_h2_ctx *ctx = cf->ctx;
const unsigned char *buf;
size_t blen;
size_t blen, nread;
ssize_t rv;
while(Curl_bufq_peek(&ctx->inbufq, &buf, &blen)) {
rv = nghttp2_session_mem_recv(ctx->h2, (const uint8_t *)buf, blen);
if(rv < 0) {
if(!curlx_sztouz(rv, &nread)) {
failf(data, "nghttp2 recv error %zd: %s", rv, nghttp2_strerror((int)rv));
return CURLE_HTTP2;
}
Curl_bufq_skip(&ctx->inbufq, (size_t)rv);
Curl_bufq_skip(&ctx->inbufq, nread);
if(Curl_bufq_is_empty(&ctx->inbufq)) {
break;
}
@ -1804,16 +1807,17 @@ CURLcode Curl_http2_request_upgrade(struct dynbuf *req,
size_t blen;
struct SingleRequest *k = &data->req;
uint8_t binsettings[H2_BINSETTINGS_LEN];
ssize_t binlen; /* length of the binsettings data */
ssize_t rc;
size_t binlen; /* length of the binsettings data */
binlen = populate_binsettings(binsettings, data);
if(binlen <= 0) {
rc = populate_binsettings(binsettings, data);
if(!curlx_sztouz(rc, &binlen) || !binlen) {
failf(data, "nghttp2 unexpectedly failed on pack_settings_payload");
curlx_dyn_free(req);
return CURLE_FAILED_INIT;
}
result = curlx_base64url_encode((const char *)binsettings, (size_t)binlen,
result = curlx_base64url_encode((const char *)binsettings, binlen,
&base64, &blen);
if(result) {
curlx_dyn_free(req);
@ -2173,15 +2177,16 @@ out:
return result;
}
static ssize_t cf_h2_body_send(struct Curl_cfilter *cf,
struct Curl_easy *data,
struct h2_stream_ctx *stream,
const void *buf, size_t blen, bool eos,
CURLcode *err)
static CURLcode cf_h2_body_send(struct Curl_cfilter *cf,
struct Curl_easy *data,
struct h2_stream_ctx *stream,
const void *buf, size_t blen, bool eos,
size_t *pnwritten)
{
struct cf_h2_ctx *ctx = cf->ctx;
size_t nwritten;
CURLcode result;
*pnwritten = 0;
if(stream->closed) {
if(stream->resp_hds_complete) {
/* Server decided to close the stream after having sent us a final
@ -2193,31 +2198,29 @@ static ssize_t cf_h2_body_send(struct Curl_cfilter *cf,
"on closed stream with response", stream->id);
if(eos)
stream->body_eos = TRUE;
*err = CURLE_OK;
return (ssize_t)blen;
*pnwritten = blen;
return CURLE_OK;
}
/* Server closed before we got a response, this is an error */
infof(data, "stream %u closed", stream->id);
*err = CURLE_SEND_ERROR;
return -1;
return CURLE_SEND_ERROR;
}
*err = Curl_bufq_write(&stream->sendbuf, buf, blen, &nwritten);
if(*err)
return -1;
result = Curl_bufq_write(&stream->sendbuf, buf, blen, pnwritten);
if(result)
return result;
if(eos && (blen == nwritten))
if(eos && (blen == *pnwritten))
stream->body_eos = TRUE;
if(eos || !Curl_bufq_is_empty(&stream->sendbuf)) {
/* resume the potentially suspended stream */
int rv = nghttp2_session_resume_data(ctx->h2, stream->id);
if(nghttp2_is_fatal(rv)) {
*err = CURLE_SEND_ERROR;
return -1;
}
if(nghttp2_is_fatal(rv))
return CURLE_SEND_ERROR;
}
return (ssize_t)nwritten;
return CURLE_OK;
}
static CURLcode h2_submit(struct h2_stream_ctx **pstream,
@ -2234,7 +2237,8 @@ static CURLcode h2_submit(struct h2_stream_ctx **pstream,
nghttp2_data_provider data_prd;
int32_t stream_id;
nghttp2_priority_spec pri_spec;
ssize_t nwritten;
ssize_t rc;
size_t nwritten;
CURLcode result = CURLE_OK;
*pnwritten = 0;
@ -2244,10 +2248,10 @@ static CURLcode h2_submit(struct h2_stream_ctx **pstream,
if(result)
goto out;
nwritten = Curl_h1_req_parse_read(&stream->h1, buf, len, NULL, 0, &result);
if(nwritten < 0)
rc = Curl_h1_req_parse_read(&stream->h1, buf, len, NULL, 0, &result);
if(!curlx_sztouz(rc, &nwritten))
goto out;
*pnwritten = (size_t)nwritten;
*pnwritten = nwritten;
if(!stream->h1.done) {
/* need more data */
goto out;
@ -2321,8 +2325,9 @@ static CURLcode h2_submit(struct h2_stream_ctx **pstream,
bodylen = len - *pnwritten;
if(bodylen || eos) {
ssize_t n = cf_h2_body_send(cf, data, stream, body, bodylen, eos, &result);
if(n >= 0)
size_t n;
result = cf_h2_body_send(cf, data, stream, body, bodylen, eos, &n);
if(!result)
*pnwritten += n;
else if(result == CURLE_AGAIN)
result = CURLE_OK;
@ -2347,7 +2352,6 @@ static CURLcode cf_h2_send(struct Curl_cfilter *cf, struct Curl_easy *data,
struct cf_h2_ctx *ctx = cf->ctx;
struct h2_stream_ctx *stream = H2_STREAM_CTX(ctx, data);
struct cf_call_data save;
ssize_t nwritten;
CURLcode result = CURLE_OK, r2;
CF_DATA_SAVE(save, cf, data);
@ -2364,21 +2368,19 @@ static CURLcode cf_h2_send(struct Curl_cfilter *cf, struct Curl_easy *data,
* being able to flush stream->sendbuf. Make a 0-length write
* to trigger flushing again.
* If this works, we report to have written `len` bytes. */
size_t n;
DEBUGASSERT(eos);
nwritten = cf_h2_body_send(cf, data, stream, buf, 0, eos, &result);
CURL_TRC_CF(data, cf, "[%d] cf_body_send last CHUNK -> %zd, %d, eos=%d",
stream->id, nwritten, result, eos);
if(nwritten < 0) {
result = cf_h2_body_send(cf, data, stream, buf, 0, eos, &n);
CURL_TRC_CF(data, cf, "[%d] cf_body_send last CHUNK -> %d, %zu, eos=%d",
stream->id, result, n, eos);
if(result)
goto out;
}
*pnwritten = len;
}
else {
nwritten = cf_h2_body_send(cf, data, stream, buf, len, eos, &result);
CURL_TRC_CF(data, cf, "[%d] cf_body_send(len=%zu) -> %zd, %d, eos=%d",
stream->id, len, nwritten, result, eos);
if(nwritten >= 0)
*pnwritten = (size_t)nwritten;
result = cf_h2_body_send(cf, data, stream, buf, len, eos, pnwritten);
CURL_TRC_CF(data, cf, "[%d] cf_body_send(len=%zu) -> %d, %zu, eos=%d",
stream->id, len, result, *pnwritten, eos);
}
/* Call the nghttp2 send loop and flush to write ALL buffered data,

View File

@ -3879,10 +3879,10 @@ CURLcode Curl_multi_xfer_buf_borrow(struct Curl_easy *data,
}
if(!data->multi->xfer_buf) {
data->multi->xfer_buf = malloc((size_t)data->set.buffer_size);
data->multi->xfer_buf = malloc(curlx_uitouz(data->set.buffer_size));
if(!data->multi->xfer_buf) {
failf(data, "could not allocate xfer_buf of %zu bytes",
(size_t)data->set.buffer_size);
failf(data, "could not allocate xfer_buf of %u bytes",
data->set.buffer_size);
return CURLE_OUT_OF_MEMORY;
}
data->multi->xfer_buf_len = data->set.buffer_size;
@ -3932,10 +3932,11 @@ CURLcode Curl_multi_xfer_ulbuf_borrow(struct Curl_easy *data,
}
if(!data->multi->xfer_ulbuf) {
data->multi->xfer_ulbuf = malloc((size_t)data->set.upload_buffer_size);
data->multi->xfer_ulbuf =
malloc(curlx_uitouz(data->set.upload_buffer_size));
if(!data->multi->xfer_ulbuf) {
failf(data, "could not allocate xfer_ulbuf of %zu bytes",
(size_t)data->set.upload_buffer_size);
failf(data, "could not allocate xfer_ulbuf of %u bytes",
data->set.upload_buffer_size);
return CURLE_OUT_OF_MEMORY;
}
data->multi->xfer_ulbuf_len = data->set.upload_buffer_size;

View File

@ -209,20 +209,7 @@ static size_t get_max_body_write_len(struct Curl_easy *data, curl_off_t limit)
{
if(limit != -1) {
/* How much more are we allowed to write? */
curl_off_t remain_diff;
remain_diff = limit - data->req.bytecount;
if(remain_diff < 0) {
/* already written too much! */
return 0;
}
#if SIZEOF_CURL_OFF_T > SIZEOF_SIZE_T
else if(remain_diff > SSIZE_MAX) {
return SIZE_MAX;
}
#endif
else {
return (size_t)remain_diff;
}
return curlx_sotouz_range(limit - data->req.bytecount, 0, SIZE_MAX);
}
return SIZE_MAX;
}
@ -678,11 +665,7 @@ static CURLcode cr_in_read(struct Curl_easy *data,
}
/* respect length limitations */
if(ctx->total_len >= 0) {
curl_off_t remain = ctx->total_len - ctx->read_len;
if(remain <= 0)
blen = 0;
else if(remain < (curl_off_t)blen)
blen = (size_t)remain;
blen = curlx_sotouz_range(ctx->total_len - ctx->read_len, 0, blen);
}
nread = 0;
if(ctx->read_cb && blen) {
@ -1363,9 +1346,9 @@ static CURLcode cr_buf_resume_from(struct Curl_easy *data,
/* already started reading? */
if(ctx->index)
return CURLE_READ_ERROR;
if(offset <= 0)
boffset = curlx_sotouz_range(offset, 0, SIZE_MAX);
if(!boffset)
return CURLE_OK;
boffset = (size_t)offset;
if(boffset > ctx->blen)
return CURLE_READ_ERROR;

View File

@ -1689,22 +1689,20 @@ static CURLcode setopt_cptr(struct Curl_easy *data, CURLoption option,
if(!ptr || s->postfieldsize == -1)
result = Curl_setstropt(&s->str[STRING_COPYPOSTFIELDS], ptr);
else {
size_t pflen;
if(s->postfieldsize < 0)
return CURLE_BAD_FUNCTION_ARGUMENT;
#if SIZEOF_CURL_OFF_T > SIZEOF_SIZE_T
/*
* Check that requested length does not overflow the size_t type.
*/
else if(s->postfieldsize > SIZE_MAX)
pflen = curlx_sotouz_range(s->postfieldsize, 0, SIZE_MAX);
if(pflen == SIZE_MAX)
return CURLE_OUT_OF_MEMORY;
#endif
else {
/* Allocate even when size == 0. This satisfies the need of possible
later address compare to detect the COPYPOSTFIELDS mode, and to
mark that postfields is used rather than read function or form
data.
*/
char *p = Curl_memdup0(ptr, (size_t)s->postfieldsize);
char *p = Curl_memdup0(ptr, pflen);
if(!p)
return CURLE_OUT_OF_MEMORY;
else {

View File

@ -82,6 +82,7 @@
#include "hsts.h"
#include "setopt.h"
#include "headers.h"
#include "curlx/warnless.h"
/* The last 2 #include files should be in this order */
#include "curl_memory.h"
@ -189,53 +190,44 @@ CURLcode Curl_xfer_send_shutdown(struct Curl_easy *data, bool *done)
* @param err error code in case of -1 return
* @return number of bytes read or -1 for error
*/
static ssize_t xfer_recv_resp(struct Curl_easy *data,
char *buf, size_t blen,
bool eos_reliable,
CURLcode *err)
static CURLcode xfer_recv_resp(struct Curl_easy *data,
char *buf, size_t blen,
bool eos_reliable,
size_t *pnread)
{
size_t nread;
CURLcode result;
DEBUGASSERT(blen > 0);
*pnread = 0;
/* If we are reading BODY data and the connection does NOT handle EOF
* and we know the size of the BODY data, limit the read amount */
if(!eos_reliable && !data->req.header && data->req.size != -1) {
curl_off_t totalleft = data->req.size - data->req.bytecount;
if(totalleft <= 0)
blen = 0;
else if(totalleft < (curl_off_t)blen)
blen = (size_t)totalleft;
blen = curlx_sotouz_range(data->req.size - data->req.bytecount, 0, blen);
}
else if(xfer_recv_shutdown_started(data)) {
/* we already received everything. Do not try more. */
blen = 0;
}
if(!blen) {
/* want nothing more */
*err = CURLE_OK;
nread = 0;
}
else {
*err = Curl_xfer_recv(data, buf, blen, &nread);
if(blen) {
result = Curl_xfer_recv(data, buf, blen, pnread);
if(result)
return result;
}
if(*err)
return -1;
if(nread == 0) {
if(*pnread == 0) {
if(data->req.shutdown) {
bool done;
*err = xfer_recv_shutdown(data, &done);
if(*err)
return -1;
result = xfer_recv_shutdown(data, &done);
if(result)
return result;
if(!done) {
*err = CURLE_AGAIN;
return -1;
return CURLE_AGAIN;
}
}
DEBUGF(infof(data, "sendrecv_dl: we are done"));
}
return (ssize_t)nread;
return CURLE_OK;
}
/*
@ -264,7 +256,6 @@ static CURLcode sendrecv_dl(struct Curl_easy *data,
read or we get a CURLE_AGAIN */
do {
size_t bytestoread;
ssize_t nread;
if(!is_multiplex) {
/* Multiplexed connection have inherent handling of EOF and we do not
@ -288,9 +279,9 @@ static CURLcode sendrecv_dl(struct Curl_easy *data,
}
rcvd_eagain = FALSE;
nread = xfer_recv_resp(data, buf, bytestoread, is_multiplex, &result);
if(nread < 0) {
if(CURLE_AGAIN != result)
result = xfer_recv_resp(data, buf, bytestoread, is_multiplex, &blen);
if(result) {
if(result != CURLE_AGAIN)
goto out; /* real error */
rcvd_eagain = TRUE;
result = CURLE_OK;
@ -298,7 +289,7 @@ static CURLcode sendrecv_dl(struct Curl_easy *data,
!data->req.resp_trailer) {
DEBUGF(infof(data, "EAGAIN, download done, no trailer announced, "
"not waiting for EOS"));
nread = 0;
blen = 0;
/* continue as if we received the EOS */
}
else
@ -306,7 +297,6 @@ static CURLcode sendrecv_dl(struct Curl_easy *data,
}
/* We only get a 0-length receive at the end of the response */
blen = (size_t)nread;
is_eos = (blen == 0);
if(!blen && (conn->recv[FIRSTSOCKET] == Curl_cf_recv)) {
@ -899,8 +889,8 @@ CURLcode Curl_xfer_recv(struct Curl_easy *data,
DEBUGASSERT(data->conn);
DEBUGASSERT(data->set.buffer_size > 0);
if((size_t)data->set.buffer_size < blen)
blen = (size_t)data->set.buffer_size;
if(curlx_uitouz(data->set.buffer_size) < blen)
blen = curlx_uitouz(data->set.buffer_size);
return Curl_conn_recv(data, data->conn->recv_idx, buf, blen, pnrcvd);
}

View File

@ -1320,32 +1320,25 @@ static CURLcode init_ngh3_conn(struct Curl_cfilter *cf,
return CURLE_OK;
}
static ssize_t recv_closed_stream(struct Curl_cfilter *cf,
static CURLcode recv_closed_stream(struct Curl_cfilter *cf,
struct Curl_easy *data,
struct h3_stream_ctx *stream,
CURLcode *err)
size_t *pnread)
{
ssize_t nread = -1;
(void)cf;
*pnread = 0;
if(stream->reset) {
failf(data, "HTTP/3 stream %" FMT_PRId64 " reset by server", stream->id);
*err = data->req.bytecount ? CURLE_PARTIAL_FILE : CURLE_HTTP3;
goto out;
return data->req.bytecount ? CURLE_PARTIAL_FILE : CURLE_HTTP3;
}
else if(!stream->resp_hds_complete) {
failf(data,
"HTTP/3 stream %" FMT_PRId64 " was closed cleanly, but before "
"getting all response header fields, treated as error",
stream->id);
*err = CURLE_HTTP3;
goto out;
return CURLE_HTTP3;
}
*err = CURLE_OK;
nread = 0;
out:
return nread;
return CURLE_OK;
}
/* incoming data frames on the h3 stream */
@ -1393,9 +1386,7 @@ static CURLcode cf_ngtcp2_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
goto out;
}
else if(stream->closed) {
ssize_t nread = recv_closed_stream(cf, data, stream, &result);
if(nread > 0)
*pnread = (size_t)nread;
result = recv_closed_stream(cf, data, stream, pnread);
goto out;
}
result = CURLE_AGAIN;

View File

@ -41,6 +41,7 @@
#include "select.h"
#include "curlx/nonblock.h"
#include "curlx/strparse.h"
#include "curlx/warnless.h"
/* The last 2 #include files should be in this order */
#include "curl_memory.h"
@ -489,12 +490,13 @@ static CURLcode ws_dec_pass_payload(struct ws_decoder *dec,
size_t inlen;
size_t nwritten;
CURLcode result;
curl_off_t remain = dec->payload_len - dec->payload_offset;
size_t remain = curlx_sotouz_range(dec->payload_len - dec->payload_offset,
0, SIZE_MAX);
(void)data;
while(remain && Curl_bufq_peek(inraw, &inbuf, &inlen)) {
if((curl_off_t)inlen > remain)
inlen = (size_t)remain;
if(inlen > remain)
inlen = remain;
result = write_cb(inbuf, inlen, dec->frame_age, dec->frame_flags,
dec->payload_offset, dec->payload_len,
write_ctx, &nwritten);
@ -502,9 +504,10 @@ static CURLcode ws_dec_pass_payload(struct ws_decoder *dec,
return result;
Curl_bufq_skip(inraw, nwritten);
dec->payload_offset += nwritten;
remain = dec->payload_len - dec->payload_offset;
CURL_TRC_WS(data, "passed %zu bytes payload, %"
FMT_OFF_T " remain", nwritten, remain);
remain = curlx_sotouz_range(dec->payload_len - dec->payload_offset,
0, SIZE_MAX);
CURL_TRC_WS(data, "passed %zu bytes payload, %zu remain",
nwritten, remain);
}
return remain ? CURLE_AGAIN : CURLE_OK;
@ -651,16 +654,13 @@ static curl_off_t ws_payload_remain(curl_off_t payload_total,
curl_off_t payload_offset,
size_t payload_buffered)
{
curl_off_t remain = payload_total - payload_offset;
curl_off_t buffered, remain = payload_total - payload_offset;
if((payload_total < 0) || (payload_offset < 0) || (remain < 0))
return -1;
#if SIZEOF_SIZE_T >= SIZEOF_CURL_OFF_T
if(payload_buffered > (size_t)CURL_OFF_T_MAX)
buffered = curlx_uztoso(payload_buffered);
if(remain < buffered)
return -1;
#endif
if(remain < (curl_off_t)payload_buffered)
return -1;
return remain - (curl_off_t)payload_buffered;
return remain - buffered;
}
static CURLcode ws_cw_dec_next(const unsigned char *buf, size_t buflen,
@ -947,7 +947,7 @@ static CURLcode ws_enc_write_payload(struct ws_encoder *enc,
struct bufq *out, size_t *pnwritten)
{
CURLcode result;
size_t i, len, n;
size_t i, len, n, remain;
*pnwritten = 0;
if(Curl_bufq_is_full(out))
@ -955,8 +955,9 @@ static CURLcode ws_enc_write_payload(struct ws_encoder *enc,
/* not the most performant way to do this */
len = buflen;
if((curl_off_t)len > enc->payload_remain)
len = (size_t)enc->payload_remain;
remain = curlx_sotouz_range(enc->payload_remain, 0, SIZE_MAX);
if(remain < len)
len = remain;
for(i = 0; i < len; ++i) {
unsigned char c = buf[i] ^ enc->mask[enc->xori];
@ -1167,8 +1168,7 @@ static CURLcode cr_ws_read(struct Curl_easy *data,
if(ws->enc.payload_remain) {
CURL_TRC_WS(data, "current frame, %" FMT_OFF_T " remaining",
ws->enc.payload_remain);
if(ws->enc.payload_remain < (curl_off_t)blen)
blen = (size_t)ws->enc.payload_remain;
blen = curlx_sotouz_range(ws->enc.payload_remain, 0, blen);
}
result = Curl_creader_read(data, reader->next, buf, blen, &nread, &eos);