Skip to content

Commit 924ea94

Browse files
authored
Update civetweb files to latest commit(3649a5f) (#474)
1 parent 2e94629 commit 924ea94

File tree

3 files changed

+376
-306
lines changed

3 files changed

+376
-306
lines changed

src/civetweb/civetweb.c

Lines changed: 55 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1551,7 +1551,7 @@ static void mg_snprintf(const struct mg_connection *conn,
15511551
#if defined(vsnprintf)
15521552
#undef vsnprintf
15531553
#endif
1554-
#ifndef NDEBUG
1554+
#if !defined(NDEBUG)
15551555
#define malloc DO_NOT_USE_THIS_FUNCTION__USE_mg_malloc
15561556
#define calloc DO_NOT_USE_THIS_FUNCTION__USE_mg_calloc
15571557
#define realloc DO_NOT_USE_THIS_FUNCTION__USE_mg_realloc
@@ -6213,13 +6213,18 @@ push_inner(struct mg_context *ctx,
62136213
/* For sockets, wait for the socket using poll */
62146214
struct mg_pollfd pfd[2];
62156215
int pollres;
6216+
unsigned int num_sock = 1;
62166217

62176218
pfd[0].fd = sock;
62186219
pfd[0].events = POLLOUT;
62196220

6220-
pfd[1].fd = ctx->thread_shutdown_notification_socket;
6221-
pfd[1].events = POLLIN;
6222-
pollres = mg_poll(pfd, 2, (int)(ms_wait), &(ctx->stop_flag));
6221+
if (ctx->context_type == CONTEXT_SERVER) {
6222+
pfd[num_sock].fd = ctx->thread_shutdown_notification_socket;
6223+
pfd[num_sock].events = POLLIN;
6224+
num_sock++;
6225+
}
6226+
6227+
pollres = mg_poll(pfd, num_sock, (int)(ms_wait), &(ctx->stop_flag));
62236228
if (!STOP_FLAG_IS_ZERO(&ctx->stop_flag)) {
62246229
return -2;
62256230
}
@@ -6330,6 +6335,7 @@ pull_inner(FILE *fp,
63306335
struct mg_pollfd pfd[2];
63316336
int to_read;
63326337
int pollres;
6338+
unsigned int num_sock = 1;
63336339

63346340
to_read = mbedtls_ssl_get_bytes_avail(conn->ssl);
63356341

@@ -6345,13 +6351,17 @@ pull_inner(FILE *fp,
63456351
pfd[0].fd = conn->client.sock;
63466352
pfd[0].events = POLLIN;
63476353

6348-
pfd[1].fd = conn->phys_ctx->thread_shutdown_notification_socket;
6349-
pfd[1].events = POLLIN;
6354+
if (conn->phys_ctx->context_type == CONTEXT_SERVER) {
6355+
pfd[num_sock].fd =
6356+
conn->phys_ctx->thread_shutdown_notification_socket;
6357+
pfd[num_sock].events = POLLIN;
6358+
num_sock++;
6359+
}
63506360

63516361
to_read = len;
63526362

63536363
pollres = mg_poll(pfd,
6354-
2,
6364+
num_sock,
63556365
(int)(timeout * 1000.0),
63566366
&(conn->phys_ctx->stop_flag));
63576367

@@ -6388,6 +6398,7 @@ pull_inner(FILE *fp,
63886398
int ssl_pending;
63896399
struct mg_pollfd pfd[2];
63906400
int pollres;
6401+
unsigned int num_sock = 1;
63916402

63926403
if ((ssl_pending = SSL_pending(conn->ssl)) > 0) {
63936404
/* We already know there is no more data buffered in conn->buf
@@ -6400,11 +6411,16 @@ pull_inner(FILE *fp,
64006411
} else {
64016412
pfd[0].fd = conn->client.sock;
64026413
pfd[0].events = POLLIN;
6403-
pfd[1].fd = conn->phys_ctx->thread_shutdown_notification_socket;
6404-
pfd[1].events = POLLIN;
6414+
6415+
if (conn->phys_ctx->context_type == CONTEXT_SERVER) {
6416+
pfd[num_sock].fd =
6417+
conn->phys_ctx->thread_shutdown_notification_socket;
6418+
pfd[num_sock].events = POLLIN;
6419+
num_sock++;
6420+
}
64056421

64066422
pollres = mg_poll(pfd,
6407-
2,
6423+
num_sock,
64086424
(int)(timeout * 1000.0),
64096425
&(conn->phys_ctx->stop_flag));
64106426
if (!STOP_FLAG_IS_ZERO(&conn->phys_ctx->stop_flag)) {
@@ -6444,15 +6460,20 @@ pull_inner(FILE *fp,
64446460
} else {
64456461
struct mg_pollfd pfd[2];
64466462
int pollres;
6463+
unsigned int num_sock = 1;
64476464

64486465
pfd[0].fd = conn->client.sock;
64496466
pfd[0].events = POLLIN;
64506467

6451-
pfd[1].fd = conn->phys_ctx->thread_shutdown_notification_socket;
6452-
pfd[1].events = POLLIN;
6468+
if (conn->phys_ctx->context_type == CONTEXT_SERVER) {
6469+
pfd[num_sock].fd =
6470+
conn->phys_ctx->thread_shutdown_notification_socket;
6471+
pfd[num_sock].events = POLLIN;
6472+
num_sock++;
6473+
}
64536474

64546475
pollres = mg_poll(pfd,
6455-
2,
6476+
num_sock,
64566477
(int)(timeout * 1000.0),
64576478
&(conn->phys_ctx->stop_flag));
64586479
if (!STOP_FLAG_IS_ZERO(&conn->phys_ctx->stop_flag)) {
@@ -10323,8 +10344,11 @@ send_file_data(struct mg_connection *conn,
1032310344
}
1032410345

1032510346
/* Read from file, exit the loop on error */
10326-
if ((num_read =
10327-
pull_inner(filep->access.fp, NULL, buf, to_read, /* unused */ 0.0))
10347+
if ((num_read = pull_inner(filep->access.fp,
10348+
NULL,
10349+
buf,
10350+
to_read,
10351+
/* unused */ 0.0))
1032810352
<= 0) {
1032910353
break;
1033010354
}
@@ -10957,7 +10981,7 @@ parse_http_headers(char **buf, struct mg_header hdr[MG_MAX_HEADERS])
1095710981
}
1095810982

1095910983
/* here *dp is either 0 or '\n' */
10960-
/* in any case, we have a new header */
10984+
/* in any case, we have found a complete header */
1096110985
num_headers = i + 1;
1096210986

1096310987
if (*dp) {
@@ -10966,9 +10990,11 @@ parse_http_headers(char **buf, struct mg_header hdr[MG_MAX_HEADERS])
1096610990
*buf = dp;
1096710991

1096810992
if ((dp[0] == '\r') || (dp[0] == '\n')) {
10969-
/* This is the end of the header */
10993+
/* We've had CRLF twice in a row
10994+
* This is the end of the headers */
1097010995
break;
1097110996
}
10997+
/* continue within the loop, find the next header */
1097210998
} else {
1097310999
*buf = dp;
1097411000
break;
@@ -16787,16 +16813,24 @@ sslize(struct mg_connection *conn,
1678716813
* This is typical for non-blocking sockets. */
1678816814
struct mg_pollfd pfd[2];
1678916815
int pollres;
16816+
unsigned int num_sock = 1;
1679016817
pfd[0].fd = conn->client.sock;
1679116818
pfd[0].events = ((err == SSL_ERROR_WANT_CONNECT)
1679216819
|| (err == SSL_ERROR_WANT_WRITE))
1679316820
? POLLOUT
1679416821
: POLLIN;
1679516822

16796-
pfd[1].fd =
16797-
conn->phys_ctx->thread_shutdown_notification_socket;
16798-
pfd[1].events = POLLIN;
16799-
pollres = mg_poll(pfd, 2, 50, &(conn->phys_ctx->stop_flag));
16823+
if (conn->phys_ctx->context_type == CONTEXT_SERVER) {
16824+
pfd[num_sock].fd =
16825+
conn->phys_ctx->thread_shutdown_notification_socket;
16826+
pfd[num_sock].events = POLLIN;
16827+
num_sock++;
16828+
}
16829+
16830+
pollres = mg_poll(pfd,
16831+
num_sock,
16832+
50,
16833+
&(conn->phys_ctx->stop_flag));
1680016834
if (pollres < 0) {
1680116835
/* Break if error occurred (-1)
1680216836
* or server shutdown (-2) */

src/civetweb/handle_form.inl

Lines changed: 59 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -162,14 +162,17 @@ search_boundary(const char *buf,
162162
const char *boundary,
163163
size_t boundary_len)
164164
{
165-
/* We must do a binary search here, not a string search, since the buffer
166-
* may contain '\x00' bytes, if binary data is transferred. */
167-
int clen = (int)buf_len - (int)boundary_len - 4;
165+
char *boundary_start = "\r\n--";
166+
size_t boundary_start_len = strlen(boundary_start);
167+
168+
/* We must do a binary search here, not a string search, since the
169+
* buffer may contain '\x00' bytes, if binary data is transferred. */
170+
int clen = (int)buf_len - (int)boundary_len - boundary_start_len;
168171
int i;
169172

170173
for (i = 0; i <= clen; i++) {
171-
if (!memcmp(buf + i, "\r\n--", 4)) {
172-
if (!memcmp(buf + i + 4, boundary, boundary_len)) {
174+
if (!memcmp(buf + i, boundary_start, boundary_start_len)) {
175+
if (!memcmp(buf + i + boundary_start_len, boundary, boundary_len)) {
173176
return buf + i;
174177
}
175178
}
@@ -624,6 +627,7 @@ mg_handle_form_request(struct mg_connection *conn,
624627
}
625628

626629
/* Copy boundary string to variable "boundary" */
630+
/* fbeg is pointer to start of value of boundary */
627631
fbeg = content_type + bl + 9;
628632
bl = strlen(fbeg);
629633
boundary = (char *)mg_malloc(bl + 1);
@@ -701,43 +705,75 @@ mg_handle_form_request(struct mg_connection *conn,
701705
return -1;
702706
}
703707

708+
/* @see https://www.rfc-editor.org/rfc/rfc2046.html#section-5.1.1
709+
*
710+
* multipart-body := [preamble CRLF]
711+
* dash-boundary transport-padding CRLF
712+
* body-part *encapsulation
713+
* close-delimiter transport-padding
714+
* [CRLF epilogue]
715+
*/
716+
704717
if (part_no == 0) {
705-
int d = 0;
706-
while ((d < buf_fill) && (buf[d] != '-')) {
707-
d++;
718+
size_t preamble_length = 0;
719+
/* skip over the preamble until we find a complete boundary
720+
* limit the preamble length to prevent abuse */
721+
/* +2 for the -- preceding the boundary */
722+
while (preamble_length < 1024
723+
&& (preamble_length < buf_fill - bl)
724+
&& strncmp(buf + preamble_length + 2, boundary, bl)) {
725+
preamble_length++;
708726
}
709-
if ((d > 0) && (buf[d] == '-')) {
710-
memmove(buf, buf + d, (unsigned)buf_fill - (unsigned)d);
711-
buf_fill -= d;
727+
/* reset the start of buf to remove the preamble */
728+
if (0 == strncmp(buf + preamble_length + 2, boundary, bl)) {
729+
memmove(buf,
730+
buf + preamble_length,
731+
(unsigned)buf_fill - (unsigned)preamble_length);
732+
buf_fill -= preamble_length;
712733
buf[buf_fill] = 0;
713734
}
714735
}
715736

716-
if (buf[0] != '-' || buf[1] != '-') {
737+
/* either it starts with a boundary and it's fine, or it's malformed
738+
* because:
739+
* - the preamble was longer than accepted
740+
* - couldn't find a boundary at all in the body
741+
* - didn't have a terminating boundary */
742+
if (buf_fill < (bl + 2) || strncmp(buf, "--", 2)
743+
|| strncmp(buf + 2, boundary, bl)) {
717744
/* Malformed request */
718745
mg_free(boundary);
719746
return -1;
720747
}
721-
if (0 != strncmp(buf + 2, boundary, bl)) {
722-
/* Malformed request */
723-
mg_free(boundary);
724-
return -1;
748+
749+
/* skip the -- */
750+
char *boundary_start = buf + 2;
751+
size_t transport_padding = 0;
752+
while (boundary_start[bl + transport_padding] == ' '
753+
|| boundary_start[bl + transport_padding] == '\t') {
754+
transport_padding++;
725755
}
726-
if (buf[bl + 2] != '\r' || buf[bl + 3] != '\n') {
727-
/* Every part must end with \r\n, if there is another part.
728-
* The end of the request has an extra -- */
729-
if (((size_t)buf_fill != (size_t)(bl + 6))
730-
|| (strncmp(buf + bl + 2, "--\r\n", 4))) {
756+
char *boundary_end = boundary_start + bl + transport_padding;
757+
758+
/* after the transport padding, if the boundary isn't
759+
* immediately followed by a \r\n then it is either... */
760+
if (strncmp(boundary_end, "\r\n", 2))
761+
{
762+
/* ...the final boundary, and it is followed by --, (in which
763+
* case it's the end of the request) or it's a malformed
764+
* request */
765+
if (strncmp(boundary_end, "--", 2)) {
731766
/* Malformed request */
732767
mg_free(boundary);
733768
return -1;
734769
}
735-
/* End of the request */
770+
/* Ingore any epilogue here */
736771
break;
737772
}
738773

774+
/* skip the \r\n */
775+
hbuf = boundary_end + 2;
739776
/* Next, we need to get the part header: Read until \r\n\r\n */
740-
hbuf = buf + bl + 4;
741777
hend = strstr(hbuf, "\r\n\r\n");
742778
if (!hend) {
743779
/* Malformed request */

0 commit comments

Comments
 (0)