fix chunkheader parser not detecting EOF correctly in some cases

Fri, 20 Feb 2026 13:57:40 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Fri, 20 Feb 2026 13:57:40 +0100
changeset 688
02360295ec58
parent 687
4bded456b4a7
child 689
dc422b7fc59a

fix chunkheader parser not detecting EOF correctly in some cases

src/server/proxy/httpclient.c file | annotate | diff | comparison | revisions
src/server/util/io.c file | annotate | diff | comparison | revisions
--- a/src/server/proxy/httpclient.c	Thu Feb 19 18:34:36 2026 +0100
+++ b/src/server/proxy/httpclient.c	Fri Feb 20 13:57:40 2026 +0100
@@ -524,8 +524,8 @@
     }
     
     if(r < 0) {
-        if(r != HTTP_CLIENT_CALLBACK_WOULD_BLOCK) {
-            client->error;
+        if(client->stream->st.io_errno != EWOULDBLOCK) {
+            client->error = 1;
         }
         return 1;
     }
@@ -1041,11 +1041,16 @@
 
 static CX_TEST(test_http_client_io_chunked_transfer_1b) {
     CX_TEST_DO {
-        CX_TEST_CALL_SUBROUTINE(test_http_client_io_chunked_transfer, 10);
+        CX_TEST_CALL_SUBROUTINE(test_http_client_io_chunked_transfer, 1);
     }
 }
 
-/*
+static CX_TEST(test_http_client_io_chunked_transfer_2b) {
+    CX_TEST_DO {
+        CX_TEST_CALL_SUBROUTINE(test_http_client_io_chunked_transfer, 2);
+    }
+}
+
 static CX_TEST(test_http_client_io_chunked_transfer_8b) {
     CX_TEST_DO {
         CX_TEST_CALL_SUBROUTINE(test_http_client_io_chunked_transfer, 16);
@@ -1057,7 +1062,6 @@
         CX_TEST_CALL_SUBROUTINE(test_http_client_io_chunked_transfer, 64);
     }
 }
-*/
 
 void http_client_add_tests(CxTestSuite *suite) {
     cx_test_register(suite, test_http_client_send_request);
@@ -1071,4 +1075,7 @@
     cx_test_register(suite, test_http_client_io_simple_16b);
     cx_test_register(suite, test_http_client_io_simple_512b);
     cx_test_register(suite, test_http_client_io_chunked_transfer_1b);
+    cx_test_register(suite, test_http_client_io_chunked_transfer_2b);
+    cx_test_register(suite, test_http_client_io_chunked_transfer_8b);
+    cx_test_register(suite, test_http_client_io_chunked_transfer_64b);
 }
--- a/src/server/util/io.c	Thu Feb 19 18:34:36 2026 +0100
+++ b/src/server/util/io.c	Fri Feb 20 13:57:40 2026 +0100
@@ -629,6 +629,7 @@
 int http_stream_parse_chunk_header(char *str, int len, WSBool first, int64_t *chunklen) {
     char *hdr_start = NULL;
     char *hdr_end = NULL;
+    char *chk_end = str + len;
     int i = 0;
     if(first) {
         hdr_start = str;
@@ -660,6 +661,10 @@
        
     if(*hdr_end == '\r') {
         // we also need '\n'
+        if(hdr_end + 1 >= chk_end) {
+            return 0; // incomplete
+        }
+        
         if(hdr_end[1] != '\n') {
             return -1;
         }
@@ -717,7 +722,7 @@
     }
     
     char *rbuf = buf; // buffer pos
-    size_t rd = 0; // number of bytes read
+    ssize_t rd = 0; // number of bytes read
     size_t rbuflen = nbytes; // number of bytes until end of buf
     WSBool perform_io = WS_TRUE; // we do only 1 read before we abort
     while(rd < nbytes && (perform_io || (st->max_read - st->read) > 0)) {

mercurial