aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvgeny Grin (Karlson2k) <k2k@narod.ru>2021-06-06 17:24:10 +0300
committerEvgeny Grin (Karlson2k) <k2k@narod.ru>2021-06-08 09:54:38 +0300
commit7d53b1eb9e979e199d8014a878630b061d129011 (patch)
treef75a8987543f5f7b00780eb3a2163a530617e8f9
parent149eaabc678adc8845421b91e477b0b39e792ecd (diff)
downloadlibmicrohttpd-7d53b1eb9e979e199d8014a878630b061d129011.tar.gz
libmicrohttpd-7d53b1eb9e979e199d8014a878630b061d129011.zip
try_ready_chunked_body: handle large chunks properly
Do not try to call user call-back with buffer larger than MHD is able to process.
-rw-r--r--src/microhttpd/connection.c16
1 files changed, 10 insertions, 6 deletions
diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c
index 044b9a01..a860a8fb 100644
--- a/src/microhttpd/connection.c
+++ b/src/microhttpd/connection.c
@@ -993,7 +993,8 @@ try_ready_chunked_body (struct MHD_Connection *connection)
993{ 993{
994 ssize_t ret; 994 ssize_t ret;
995 struct MHD_Response *response; 995 struct MHD_Response *response;
996 char cbuf[10]; /* 10: max strlen of "%x\r\n" */ 996 static const size_t max_chunk = 0xFFFFFF;
997 char cbuf[10]; /* 10: max strlen of "FFFFFF\r\n" */
997 int cblen; 998 int cblen;
998 999
999 response = connection->response; 1000 response = connection->response;
@@ -1014,8 +1015,8 @@ try_ready_chunked_body (struct MHD_Connection *connection)
1014 _ ("Closing connection (out of memory).")); 1015 _ ("Closing connection (out of memory)."));
1015 return MHD_NO; 1016 return MHD_NO;
1016 } 1017 }
1017 if ( (2 * (0xFFFFFF + sizeof(cbuf) + 2)) < size) 1018 if ( (max_chunk + sizeof(cbuf) + 2) < size)
1018 size = 2 * (0xFFFFFF + sizeof(cbuf) + 2); 1019 size = max_chunk + sizeof(cbuf) + 2;
1019 connection->write_buffer = MHD_pool_allocate (connection->pool, 1020 connection->write_buffer = MHD_pool_allocate (connection->pool,
1020 size, 1021 size,
1021 false); 1022 false);
@@ -1045,10 +1046,15 @@ try_ready_chunked_body (struct MHD_Connection *connection)
1045 else 1046 else
1046 { 1047 {
1047 /* buffer not in range, try to fill it */ 1048 /* buffer not in range, try to fill it */
1049 size_t size_to_fill;
1050
1051 size_to_fill = connection->write_buffer_size - sizeof (cbuf) - 2;
1052 if (max_chunk < size_to_fill)
1053 size_to_fill = max_chunk;
1048 ret = response->crc (response->crc_cls, 1054 ret = response->crc (response->crc_cls,
1049 connection->response_write_position, 1055 connection->response_write_position,
1050 &connection->write_buffer[sizeof (cbuf)], 1056 &connection->write_buffer[sizeof (cbuf)],
1051 connection->write_buffer_size - sizeof (cbuf) - 2); 1057 size_to_fill);
1052 } 1058 }
1053 if ( ((ssize_t) MHD_CONTENT_READER_END_WITH_ERROR) == ret) 1059 if ( ((ssize_t) MHD_CONTENT_READER_END_WITH_ERROR) == ret)
1054 { 1060 {
@@ -1082,8 +1088,6 @@ try_ready_chunked_body (struct MHD_Connection *connection)
1082#endif 1088#endif
1083 return MHD_NO; 1089 return MHD_NO;
1084 } 1090 }
1085 if (ret > 0xFFFFFF)
1086 ret = 0xFFFFFF;
1087 cblen = MHD_snprintf_ (cbuf, 1091 cblen = MHD_snprintf_ (cbuf,
1088 sizeof (cbuf), 1092 sizeof (cbuf),
1089 "%X\r\n", 1093 "%X\r\n",