From: Stefan Eissing Date: Sun, 4 Jun 2023 10:43:14 +0000 (+0200) Subject: bufq: make write/pass methods more robust X-Git-Tag: curl-8_2_0~152 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=73022b52c124fe64ea5740eb6004fda250b10c63;p=thirdparty%2Fcurl.git bufq: make write/pass methods more robust - related to #11242 where curl enters busy loop when sending http2 data to the server Closes #11247 --- diff --git a/lib/bufq.c b/lib/bufq.c index 30598cf586..e2107f94bf 100644 --- a/lib/bufq.c +++ b/lib/bufq.c @@ -418,7 +418,8 @@ ssize_t Curl_bufq_write(struct bufq *q, break; } n = chunk_append(tail, buf, len); - DEBUGASSERT(n); + if(!n) + break; nwritten += n; buf += n; len -= n; @@ -528,6 +529,14 @@ ssize_t Curl_bufq_pass(struct bufq *q, Curl_bufq_writer *writer, } break; } + if(!chunk_written) { + if(!nwritten) { + /* treat as blocked */ + *err = CURLE_AGAIN; + nwritten = -1; + } + break; + } Curl_bufq_skip(q, (size_t)chunk_written); nwritten += chunk_written; } @@ -551,7 +560,8 @@ ssize_t Curl_bufq_write_pass(struct bufq *q, /* real error, fail */ return -1; } - /* would block */ + /* would block, bufq is full, give up */ + break; } } @@ -562,16 +572,24 @@ ssize_t Curl_bufq_write_pass(struct bufq *q, /* real error, fail */ return -1; } - /* no room in bufq, bail out */ - goto out; + /* no room in bufq */ + break; } + /* edge case of writer returning 0 (and len is >0) + * break or we might enter an infinite loop here */ + if(n == 0) + break; + /* Maybe only part of `data` has been added, continue to loop */ buf += (size_t)n; len -= (size_t)n; nwritten += (size_t)n; } -out: + if(!nwritten && len) { + *err = CURLE_AGAIN; + return -1; + } return nwritten; }