]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
ngtcp2: fix coverity warning about result handling
authorStefan Eissing <stefan@eissing.org>
Mon, 30 Jun 2025 07:07:54 +0000 (09:07 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Mon, 7 Jul 2025 06:58:46 +0000 (08:58 +0200)
Closes #17783

lib/cf-h2-proxy.c
lib/easy.c
lib/http.c
lib/multi.c
lib/url.c
lib/url.h
lib/vquic/curl_ngtcp2.c
lib/vquic/curl_osslq.c
lib/vquic/curl_quiche.c

index 59322aa9ace7b7c3e4f648a7366ec3427bf59dbc..c55467c70589e15bcd8383059d2c1b9b23fccefa 100644 (file)
@@ -28,6 +28,7 @@
 
 #include <nghttp2/nghttp2.h>
 #include "urldata.h"
+#include "url.h"
 #include "cfilters.h"
 #include "connect.h"
 #include "curl_trc.h"
@@ -1315,7 +1316,7 @@ static CURLcode cf_h2_proxy_recv(struct Curl_cfilter *cf,
 {
   struct cf_h2_proxy_ctx *ctx = cf->ctx;
   struct cf_call_data save;
-  CURLcode result, r2;
+  CURLcode result;
 
   *pnread = 0;
   CF_DATA_SAVE(save, cf, data);
@@ -1339,9 +1340,7 @@ static CURLcode cf_h2_proxy_recv(struct Curl_cfilter *cf,
     nghttp2_session_consume(ctx->h2, ctx->tunnel.stream_id, *pnread);
   }
 
-  r2 = proxy_h2_progress_egress(cf, data);
-  if(r2 && (r2 != CURLE_AGAIN))
-    result = r2;
+  result = Curl_1st_fatal(result, proxy_h2_progress_egress(cf, data));
 
 out:
   if(!Curl_bufq_is_empty(&ctx->tunnel.recvbuf) &&
@@ -1364,7 +1363,7 @@ static CURLcode cf_h2_proxy_send(struct Curl_cfilter *cf,
   struct cf_h2_proxy_ctx *ctx = cf->ctx;
   struct cf_call_data save;
   int rv;
-  CURLcode result, r2;
+  CURLcode result;
 
   (void)eos;
   *pnwritten = 0;
@@ -1394,19 +1393,8 @@ static CURLcode cf_h2_proxy_send(struct Curl_cfilter *cf,
     }
   }
 
-  r2 = proxy_h2_progress_ingress(cf, data);
-  if(r2 && (r2 != CURLE_AGAIN)) {
-    result = r2;
-    goto out;
-  }
-
-  /* Call the nghttp2 send loop and flush to write ALL buffered data,
-   * headers and/or request body completely out to the network */
-  r2 = proxy_h2_progress_egress(cf, data);
-  if(r2 && (r2 != CURLE_AGAIN)) {
-    result = r2;
-    goto out;
-  }
+  result = Curl_1st_fatal(result, proxy_h2_progress_ingress(cf, data));
+  result = Curl_1st_fatal(result, proxy_h2_progress_egress(cf, data));
 
   if(!result && proxy_h2_should_close_session(ctx)) {
     /* nghttp2 thinks this session is done. If the stream has not been
index d540888d3aac4938cbd86f51bdf31053dde4e3c2..99cbd970ea42fc4eb3f63ebc119e263c07f4618c 100644 (file)
@@ -1129,7 +1129,7 @@ void curl_easy_reset(CURL *d)
  */
 CURLcode curl_easy_pause(CURL *d, int action)
 {
-  CURLcode result = CURLE_OK, r2;
+  CURLcode result = CURLE_OK;
   bool recursive = FALSE;
   bool changed = FALSE;
   struct Curl_easy *data = d;
@@ -1150,16 +1150,12 @@ CURLcode curl_easy_pause(CURL *d, int action)
 
   if(send_paused != send_paused_new) {
     changed = TRUE;
-    r2 = Curl_xfer_pause_send(data, send_paused_new);
-    if(r2)
-      result = r2;
+    result = Curl_1st_err(result, Curl_xfer_pause_send(data, send_paused_new));
   }
 
   if(recv_paused != recv_paused_new) {
     changed = TRUE;
-    r2 = Curl_xfer_pause_recv(data, recv_paused_new);
-    if(r2)
-      result = r2;
+    result = Curl_1st_err(result, Curl_xfer_pause_recv(data, recv_paused_new));
   }
 
   /* If not completely pausing both directions now, run again in any case. */
index 2dfb631fd3094f7866c8c872ddc6735b6733c214..32e54c2683ae344bcb5efc9bafd98ef1d1248877 100644 (file)
@@ -3962,9 +3962,8 @@ static CURLcode http_on_response(struct Curl_easy *data,
 out:
   if(last_hd) {
     /* if not written yet, write it now */
-    CURLcode r2 = http_write_header(data, last_hd, last_hd_len);
-    if(!result)
-      result = r2;
+    result = Curl_1st_err(
+      result, http_write_header(data, last_hd, last_hd_len));
   }
   return result;
 }
index 86afc600163001b60dabe96f0959d30e5688f968..fe2cca4039efe0b8774a3691a57421ab2200ee7e 100644 (file)
@@ -621,7 +621,7 @@ static CURLcode multi_done(struct Curl_easy *data,
                                                 after an error was detected */
                            bool premature)
 {
-  CURLcode result, r2;
+  CURLcode result;
   struct connectdata *conn = data->conn;
   struct multi_done_ctx mdctx;
 
@@ -670,9 +670,7 @@ static CURLcode multi_done(struct Curl_easy *data,
   }
 
   /* Make sure that transfer client writes are really done now. */
-  r2 = Curl_xfer_write_done(data, premature);
-  if(r2 && !result)
-    result = r2;
+  result = Curl_1st_err(result, Curl_xfer_write_done(data, premature));
 
   /* Inform connection filters that this transfer is done */
   Curl_conn_ev_data_done(data, premature);
index 977b6a604922fbc63911e95a36569d4f94efeeeb..1f73c1e3ac3a85ee9daf41b97d3399cb4999403c 100644 (file)
--- a/lib/url.c
+++ b/lib/url.c
@@ -4101,3 +4101,17 @@ void *Curl_conn_meta_get(struct connectdata *conn, const char *key)
 {
   return Curl_hash_pick(&conn->meta_hash, CURL_UNCONST(key), strlen(key) + 1);
 }
+
+CURLcode Curl_1st_err(CURLcode r1, CURLcode r2)
+{
+  return r1 ? r1 : r2;
+}
+
+CURLcode Curl_1st_fatal(CURLcode r1, CURLcode r2)
+{
+  if(r1 && (r1 != CURLE_AGAIN))
+    return r1;
+  if(r2 && (r2 != CURLE_AGAIN))
+    return r2;
+  return r1;
+}
index 7aba98dbb93686824e90e395701b3e68d7c2431a..bd4060c8846dc1f615d3d933047ca6addf1c443c 100644 (file)
--- a/lib/url.h
+++ b/lib/url.h
@@ -101,6 +101,19 @@ CURLcode Curl_conn_upkeep(struct Curl_easy *data,
                           struct connectdata *conn,
                           struct curltime *now);
 
+/**
+ * Always eval all arguments, return the first result != CURLE_OK.
+ * A non-short-circuit evaluation.
+ */
+CURLcode Curl_1st_err(CURLcode r1, CURLcode r2);
+
+/**
+ * Always eval all arguments, return the first
+ * result != (CURLE_OK|CURLE_AGAIN) or `r1`.
+ * A non-short-circuit evaluation.
+ */
+CURLcode Curl_1st_fatal(CURLcode r1, CURLcode r2);
+
 #if defined(USE_HTTP2) || defined(USE_HTTP3)
 void Curl_data_priority_clear_state(struct Curl_easy *data);
 #else
index 5d40fd5ccfd551c01c8d2125ba55b520ce69ccdf..c534e905f6eeb7987d7e89f7b37dddca5676cd90 100644 (file)
@@ -47,6 +47,7 @@
 #endif
 
 #include "../urldata.h"
+#include "../url.h"
 #include "../uint-hash.h"
 #include "../sendf.h"
 #include "../strdup.h"
@@ -1325,15 +1326,11 @@ static CURLcode cf_ngtcp2_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
   result = CURLE_AGAIN;
 
 out:
-  if(cf_progress_egress(cf, data, &pktx)) {
-    result = CURLE_SEND_ERROR;
-  }
-  else {
-    CURLcode r2 = check_and_set_expiry(cf, data, &pktx);
-    if(r2)
-      result = r2;
-  }
+  result = Curl_1st_err(result, cf_progress_egress(cf, data, &pktx));
+  result = Curl_1st_err(result, check_and_set_expiry(cf, data, &pktx));
+
   CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] cf_recv(blen=%zu) -> %dm, %zu",
+
               stream ? stream->id : -1, blen, result, *pnread);
   CF_DATA_RESTORE(cf, save);
   return result;
@@ -1581,7 +1578,7 @@ static CURLcode cf_ngtcp2_send(struct Curl_cfilter *cf, struct Curl_easy *data,
   struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data);
   struct cf_call_data save;
   struct pkt_io_ctx pktx;
-  CURLcode result = CURLE_OK, r2;
+  CURLcode result = CURLE_OK;
 
   CF_DATA_SAVE(save, cf, data);
   DEBUGASSERT(cf->connected);
@@ -1595,10 +1592,9 @@ static CURLcode cf_ngtcp2_send(struct Curl_cfilter *cf, struct Curl_easy *data,
     return ctx->tls_vrfy_result;
 
   (void)eos; /* use for stream EOF and block handling */
-  r2 = cf_progress_ingress(cf, data, &pktx);
-  if(r2) {
-    result = r2;
-  }
+  result = cf_progress_ingress(cf, data, &pktx);
+  if(result)
+    goto out;
 
   if(!stream || stream->id < 0) {
     if(ctx->shutdown_started) {
@@ -1655,14 +1651,11 @@ static CURLcode cf_ngtcp2_send(struct Curl_cfilter *cf, struct Curl_easy *data,
   if(*pnwritten > 0 && !ctx->tls_handshake_complete && ctx->use_earlydata)
     ctx->earlydata_skip += *pnwritten;
 
-  r2 = cf_progress_egress(cf, data, &pktx);
-  if(r2)
-    result = r2;
+  DEBUGASSERT(!result);
+  result = cf_progress_egress(cf, data, &pktx);
 
 out:
-  r2 = check_and_set_expiry(cf, data, &pktx);
-  if(r2)
-    result = r2;
+  result = Curl_1st_err(result, check_and_set_expiry(cf, data, &pktx));
 
   CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] cf_send(len=%zu) -> %d, %zu",
               stream ? stream->id : -1, len, result, *pnwritten);
index d435d7f512481b00a661781fefc1cafd7df0792b..8e6f8c11a6d25b0b2717eb1371a2f3c6bf278efa 100644 (file)
@@ -1995,7 +1995,7 @@ static CURLcode cf_osslq_send(struct Curl_cfilter *cf, struct Curl_easy *data,
   struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data);
   struct cf_call_data save;
   ssize_t nwritten;
-  CURLcode result = CURLE_OK, r2;
+  CURLcode result = CURLE_OK;
 
   (void)eos; /* use to end stream */
   CF_DATA_SAVE(save, cf, data);
@@ -2049,14 +2049,11 @@ static CURLcode cf_osslq_send(struct Curl_cfilter *cf, struct Curl_easy *data,
     (void)nghttp3_conn_resume_stream(ctx->h3.conn, stream->s.id);
   }
 
-  r2 = cf_progress_egress(cf, data);
-  if(r2)
-    result = r2;
+  result = Curl_1st_err(result, cf_progress_egress(cf, data));
 
 out:
-  r2 = check_and_set_expiry(cf, data);
-  if(r2)
-    result = r2;
+  result = Curl_1st_err(result, check_and_set_expiry(cf, data));
+
   CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] cf_send(len=%zu) -> %d, %zu",
               stream ? stream->s.id : -1, len, result, *pnwritten);
   CF_DATA_RESTORE(cf, save);
@@ -2093,7 +2090,7 @@ static CURLcode cf_osslq_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
   struct cf_osslq_ctx *ctx = cf->ctx;
   struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data);
   struct cf_call_data save;
-  CURLcode result = CURLE_OK, r2;
+  CURLcode result = CURLE_OK;
 
   (void)ctx;
   CF_DATA_SAVE(save, cf, data);
@@ -2117,11 +2114,9 @@ static CURLcode cf_osslq_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
     }
   }
 
-  r2 = cf_progress_ingress(cf, data);
-  if(r2) {
-    result = r2;
+  result = Curl_1st_err(result, cf_progress_ingress(cf, data));
+  if(result)
     goto out;
-  }
 
   /* recvbuf had nothing before, maybe after progressing ingress? */
   if(!*pnread && !Curl_bufq_is_empty(&stream->recvbuf)) {
@@ -2145,14 +2140,9 @@ static CURLcode cf_osslq_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
   }
 
 out:
-  if(cf_progress_egress(cf, data)) {
-    result = CURLE_SEND_ERROR;
-  }
-  else {
-    r2 = check_and_set_expiry(cf, data);
-    if(r2)
-      result = r2;
-  }
+  result = Curl_1st_err(result, cf_progress_egress(cf, data));
+  result = Curl_1st_err(result, check_and_set_expiry(cf, data));
+
   CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] cf_recv(len=%zu) -> %d, %zu",
               stream ? stream->s.id : -1, len, result, *pnread);
   CF_DATA_RESTORE(cf, save);
index 6d79842fba0ed8d2d26c2a5fd3fa3cfb6cbf60c0..912f312a1f4922b939f713c8c40bff2e2a62d04c 100644 (file)
@@ -848,7 +848,7 @@ static CURLcode cf_quiche_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
 {
   struct cf_quiche_ctx *ctx = cf->ctx;
   struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data);
-  CURLcode result = CURLE_OK, r2;
+  CURLcode result = CURLE_OK;
 
   *pnread = 0;
   vquic_ctx_update_time(&ctx->q);
@@ -896,11 +896,7 @@ static CURLcode cf_quiche_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
   }
 
 out:
-  r2 = cf_flush_egress(cf, data);
-  if(r2) {
-    CURL_TRC_CF(data, cf, "cf_recv, flush egress failed");
-    result = r2;
-  }
+  result = Curl_1st_err(result, cf_flush_egress(cf, data));
   if(*pnread > 0)
     ctx->data_recvd += *pnread;
   CURL_TRC_CF(data, cf, "[%"FMT_PRIu64"] cf_recv(total=%"
@@ -1085,7 +1081,7 @@ static CURLcode cf_quiche_send(struct Curl_cfilter *cf, struct Curl_easy *data,
 {
   struct cf_quiche_ctx *ctx = cf->ctx;
   struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data);
-  CURLcode result, r2;
+  CURLcode result;
 
   *pnwritten = 0;
   vquic_ctx_update_time(&ctx->q);
@@ -1126,9 +1122,7 @@ static CURLcode cf_quiche_send(struct Curl_cfilter *cf, struct Curl_easy *data,
   }
 
 out:
-  r2 = cf_flush_egress(cf, data);
-  if(r2)
-    result = r2;
+  result = Curl_1st_err(result, cf_flush_egress(cf, data));
 
   CURL_TRC_CF(data, cf, "[%" FMT_PRIu64 "] cf_send(len=%zu) -> %d, %zu",
               stream ? stream->id : (curl_uint64_t)~0, len,