From 740b609e1e04c9d74c623280b48c688c13a29bef Mon Sep 17 00:00:00 2001 From: cpq Date: Sat, 6 Aug 2022 09:01:34 +0100 Subject: [PATCH] Fix for deliver_normal_chunks() and a test case --- mongoose.c | 14 +++++++------- src/http.c | 14 +++++++------- test/unit_test.c | 13 ++++++++++++- 3 files changed, 26 insertions(+), 15 deletions(-) diff --git a/mongoose.c b/mongoose.c index 2bb9178a..e009bd2e 100644 --- a/mongoose.c +++ b/mongoose.c @@ -2321,7 +2321,7 @@ static void deliver_chunked_chunks(struct mg_connection *c, size_t hlen, static void deliver_normal_chunks(struct mg_connection *c, size_t hlen, struct mg_http_message *hm, bool *next) { size_t left, processed = ((size_t) c->pfn_data) & ~MG_DMARK; - bool deleted = ((size_t) c->pfn_data) & MG_DMARK; + size_t deleted = ((size_t) c->pfn_data) & MG_DMARK; hm->chunk = mg_str_n((char *) &c->recv.buf[hlen], c->recv.len - hlen); if (processed <= hm->chunk.len && !deleted) { hm->chunk.len -= processed; @@ -2331,14 +2331,14 @@ static void deliver_normal_chunks(struct mg_connection *c, size_t hlen, if (hm->chunk.len > left) hm->chunk.len = left; if (hm->chunk.len > 0) mg_call(c, MG_EV_HTTP_CHUNK, hm); processed += hm->chunk.len; - if (processed >= hm->body.len) { // Last, 0-len chunk - hm->chunk.len = 0; // Reset length - mg_call(c, MG_EV_HTTP_CHUNK, hm); // Call user handler - c->pfn_data = NULL; // Reset processed counter + deleted = ((size_t) c->pfn_data) & MG_DMARK; // Re-evaluate after user call + if (processed >= hm->body.len) { // Last, 0-len chunk + hm->chunk.len = 0; // Reset length + mg_call(c, MG_EV_HTTP_CHUNK, hm); // Call user handler + c->pfn_data = NULL; // Reset processed counter if (processed && deleted) mg_iobuf_del(&c->recv, 0, hlen), *next = true; } else { - size_t del = ((size_t) c->pfn_data) & MG_DMARK; // Keep deletion marker - c->pfn_data = (void *) (processed | del); // if it is set + c->pfn_data = (void *) (processed | deleted); // if it is set } } diff --git a/src/http.c b/src/http.c index 2d3a4401..e2362bbc 100644 --- a/src/http.c +++ b/src/http.c @@ -899,7 +899,7 @@ static void deliver_chunked_chunks(struct mg_connection *c, size_t hlen, static void deliver_normal_chunks(struct mg_connection *c, size_t hlen, struct mg_http_message *hm, bool *next) { size_t left, processed = ((size_t) c->pfn_data) & ~MG_DMARK; - bool deleted = ((size_t) c->pfn_data) & MG_DMARK; + size_t deleted = ((size_t) c->pfn_data) & MG_DMARK; hm->chunk = mg_str_n((char *) &c->recv.buf[hlen], c->recv.len - hlen); if (processed <= hm->chunk.len && !deleted) { hm->chunk.len -= processed; @@ -909,14 +909,14 @@ static void deliver_normal_chunks(struct mg_connection *c, size_t hlen, if (hm->chunk.len > left) hm->chunk.len = left; if (hm->chunk.len > 0) mg_call(c, MG_EV_HTTP_CHUNK, hm); processed += hm->chunk.len; - if (processed >= hm->body.len) { // Last, 0-len chunk - hm->chunk.len = 0; // Reset length - mg_call(c, MG_EV_HTTP_CHUNK, hm); // Call user handler - c->pfn_data = NULL; // Reset processed counter + deleted = ((size_t) c->pfn_data) & MG_DMARK; // Re-evaluate after user call + if (processed >= hm->body.len) { // Last, 0-len chunk + hm->chunk.len = 0; // Reset length + mg_call(c, MG_EV_HTTP_CHUNK, hm); // Call user handler + c->pfn_data = NULL; // Reset processed counter if (processed && deleted) mg_iobuf_del(&c->recv, 0, hlen), *next = true; } else { - size_t del = ((size_t) c->pfn_data) & MG_DMARK; // Keep deletion marker - c->pfn_data = (void *) (processed | del); // if it is set + c->pfn_data = (void *) (processed | deleted); // if it is set } } diff --git a/test/unit_test.c b/test/unit_test.c index 6e536e78..fd2fd099 100644 --- a/test/unit_test.c +++ b/test/unit_test.c @@ -1909,6 +1909,13 @@ static void eY(struct mg_connection *c, int ev, void *ev_data, void *fn_data) { (void) ev_data, (void) fn_data; } +static void eZ(struct mg_connection *c, int ev, void *ev_data, void *fn_data) { + if (ev == MG_EV_HTTP_MSG) { + mg_http_reply(c, 200, "", "abcd"); + } + (void) ev_data, (void) fn_data; +} + // Do not delete chunks as they arrive static void eh4(struct mg_connection *c, int ev, void *ev_data, void *fn_data) { uint32_t *crc = (uint32_t *) fn_data; @@ -1962,9 +1969,13 @@ static void test_http_chunked_case(mg_event_handler_t s, mg_event_handler_t c, static void test_http_chunked(void) { // Non-chunked encoding test_http_chunked_case(eY, eh4, 1, "axbcxdxxabcd"); // Chunks not deleted - test_http_chunked_case(eY, eh5, 1, "axbcxdxx"); // Chunks deleted test_http_chunked_case(eY, eh4, 2, "axbcxdxxabcdaxbcxdxxabcd"); + test_http_chunked_case(eY, eh5, 1, "axbcxdxx"); // Chunks deleted test_http_chunked_case(eY, eh5, 2, "axbcxdxxaxbcxdxx"); + test_http_chunked_case(eZ, eh4, 1, "abcdxxabcd"); // Not deleted + test_http_chunked_case(eZ, eh4, 2, "abcdxxabcdabcdxxabcd"); + test_http_chunked_case(eZ, eh5, 1, "abcdxx"); // Deleted + test_http_chunked_case(eZ, eh5, 2, "abcdxxabcdxx"); // Chunked encoding test_http_chunked_case(eX, eh4, 1, "axbxcxdxxabcd"); // Chunks not deleted