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,
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 */
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;
}
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;