← Commit list

a4d3c4e847

Stefan Eissing
Stefan Eissing
2025-10-10
SUCCESS Duration: 220s

Subject

ws: fix some edge cases

Binary

No binary (build failed)

Architecture & Compiler Flags

Architecture: x86_64-linux-gnu Compiler: gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0

—

Build Log

(log yok)

Commit Diff GitHub →

lib/ws.c+38 -5
@@ -647,6 +647,22 @@ static CURLcode ws_enc_add_cntrl(struct Curl_easy *data,
return CURLE_OK;
}
+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;
+ if((payload_total < 0) || (payload_offset < 0) || (remain < 0))
+ return -1;
+#if SIZEOF_OFF_T <= SIZEOF_SIZE_T
+ if((curl_off_t)payload_buffered < 0)
+ return -1;
+#endif
+ if(remain < (curl_off_t)payload_buffered)
+ return -1;
+ return remain - (curl_off_t)payload_buffered;
+}
+
static CURLcode ws_cw_dec_next(const unsigned char *buf, size_t buflen,
int frame_age, int frame_flags,
curl_off_t payload_offset,
@@ -658,11 +674,16 @@ static CURLcode ws_cw_dec_next(const unsigned char *buf, size_t buflen,
struct Curl_easy *data = ctx->data;
struct websocket *ws = ctx->ws;
bool auto_pong = !data->set.ws_no_auto_pong;
- curl_off_t remain = (payload_len - (payload_offset + buflen));
+ curl_off_t remain;
CURLcode result;
(void)frame_age;
*pnwritten = 0;
+ remain = ws_payload_remain(payload_len, payload_offset, buflen);
+ if(remain < 0) {
+ DEBUGASSERT(0); /* parameter mismatch */
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ }
if(auto_pong && (frame_flags & CURLWS_PING) && !remain) {
/* auto-respond to PINGs, only works for single-frame payloads atm */
@@ -981,12 +1002,18 @@ static CURLcode ws_enc_add_pending(struct Curl_easy *data,
result);
goto out;
}
- /* our buffer should always be able to take in a control frame */
- DEBUGASSERT(n == ws->pending.payload_len);
+ if(n != ws->pending.payload_len) {
+ DEBUGASSERT(0); /* buffer should always be able to take all */
+ CURL_TRC_WS(data, "ws_enc_cntrl(), error added only %zu/%zu payload,",
+ n, ws->pending.payload_len);
+ result = CURLE_SEND_ERROR;
+ goto out;
+ }
+ /* the frame should be complete now */
DEBUGASSERT(!ws->enc.payload_remain);
+ memset(&ws->pending, 0, sizeof(ws->pending));
out:
- memset(&ws->pending, 0, sizeof(ws->pending));
return result;
}
@@ -1445,10 +1472,16 @@ static CURLcode ws_client_collect(const unsigned char *buf, size_t buflen,
struct ws_collect *ctx = userp;
struct Curl_easy *data = ctx->data;
bool auto_pong = !data->set.ws_no_auto_pong;
- curl_off_t remain = (payload_len - (payload_offset + buflen));
+ curl_off_t remain;
CURLcode result = CURLE_OK;
*pnwritten = 0;
+ remain = ws_payload_remain(payload_len, payload_offset, buflen);
+ if(remain < 0) {
+ DEBUGASSERT(0); /* parameter mismatch */
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ }
+
if(!ctx->bufidx) {
/* first write */
ctx->frame_age = frame_age;