]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
lib: eliminate size_t casts
authorStefan Eissing <stefan@eissing.org>
Wed, 12 Nov 2025 14:58:49 +0000 (15:58 +0100)
committerDaniel Stenberg <daniel@haxx.se>
Thu, 13 Nov 2025 12:32:19 +0000 (13:32 +0100)
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

13 files changed:
lib/cf-h1-proxy.c
lib/cf-h2-proxy.c
lib/curlx/warnless.c
lib/curlx/warnless.h
lib/dict.c
lib/http.c
lib/http2.c
lib/multi.c
lib/sendf.c
lib/setopt.c
lib/transfer.c
lib/vquic/curl_ngtcp2.c
lib/ws.c

index be01891bf0784c22bb54bb0eb2ec8c8a2b1477fd..ac0dc596f2b70494d32cb887b00328ef562289f1 100644 (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)
index 148caca71b1a409278915e67cada6346afcea7ce..d38bd4695254db25a3f2385b95af7f08adb6fdbf 100644 (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;
 }
 
index bb636a93270fa0e68d5fed159919cabff7cbe3ef..a0aa5eda13b1ec868bc8cd3353b7ea92c9cd3d2b 100644 (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;
+}
index 0a0c60807340b876ee1d9ec8ff2a55cc70472907..a128f71488a155e6d648cff163ff2f62959e2014 100644 (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))
index 3296a45466ad074c6b107ee8ea55118f8a2c3e68..5c7ba7f6229f03fcf63b559fa2c7597ca29c3a39 100644 (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;
index 0555291d0bba31a08b6c372c170dfd30bda24a58..f3444d46a91f34ac63c132d06898166f70b0f038 100644 (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);
     }
index de1113c1e45f95ea07320329804fa03a7c3c661d..5c8b0cab3886f014a0618d1e8d8a0f651f9e37ba 100644 (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,
index 1e24ce8c466271808fac49991c2f60d50588e45f..a47336457b80d086456185064e5cadd9509fd818 100644 (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;
index 980fae23e64606984b7195341bd095ac53f916fe..655444a2950406b0f80efffe9c7dd18591147acb 100644 (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;
 
index 9f43b1b60da0ca86d7195f77f5805d283a3bf637..338e94d1bbf4208ffdda6272e2507f6b5aadd5ef 100644 (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 {
index 6ae21e1a403049665e67a85da3074a7216fdf7a3..4c17cbb50da0d47aa9e3f796f57e2c25fc43bdbe 100644 (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);
 }
 
index 1f70e0b480ab8667dbf0b38927839ddda90f1642..475060ebdd345de9e73fb2f5734c53491279ec70 100644 (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;
index ddf49c9d2d83f6a465c529ca8b299b7b07d26744..96a0d61378f0e694c4eedaecb845013e84a0871b 100644 (file)
--- a/lib/ws.c
+++ b/lib/ws.c
@@ -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);