diff options
author | Christian Grothoff <christian@grothoff.org> | 2024-01-21 11:44:15 +0100 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2024-01-21 11:44:15 +0100 |
commit | 45aa83f172b53e1700826cd223b3d95776b053b4 (patch) | |
tree | 0a94cdd7216da3c35fa452fa962ac8c4041ff6b8 | |
parent | 0e4d6c2f934f44886816d701eef4a7edae81dc47 (diff) | |
download | libmicrohttpd-45aa83f172b53e1700826cd223b3d95776b053b4.tar.gz libmicrohttpd-45aa83f172b53e1700826cd223b3d95776b053b4.zip |
fix memory leak on error path
-rw-r--r-- | src/microhttpd/connection.c | 40 |
1 files changed, 27 insertions, 13 deletions
diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c index a452afcf..963aaf04 100644 --- a/src/microhttpd/connection.c +++ b/src/microhttpd/connection.c | |||
@@ -104,7 +104,7 @@ | |||
104 | "<body><p>The total size of the request headers, which includes the " \ | 104 | "<body><p>The total size of the request headers, which includes the " \ |
105 | "request target and the request field lines, exceeds the memory " \ | 105 | "request target and the request field lines, exceeds the memory " \ |
106 | "constraints of this web server.</p>" \ | 106 | "constraints of this web server.</p>" \ |
107 | "<p>The request could be re-tried with shorter field lines, a shorter "\ | 107 | "<p>The request could be re-tried with shorter field lines, a shorter " \ |
108 | "request target or a shorter request method token.</p></body>" \ | 108 | "request target or a shorter request method token.</p></body>" \ |
109 | "</html>" | 109 | "</html>" |
110 | #else | 110 | #else |
@@ -120,7 +120,7 @@ | |||
120 | "<head><title>Request too big</title></head>" \ | 120 | "<head><title>Request too big</title></head>" \ |
121 | "<body><p>The total size of the request headers, which includes the " \ | 121 | "<body><p>The total size of the request headers, which includes the " \ |
122 | "request target and the request field lines, exceeds the memory " \ | 122 | "request target and the request field lines, exceeds the memory " \ |
123 | "constraints of this web server.</p> "\ | 123 | "constraints of this web server.</p> " \ |
124 | "<p>The request could be re-tried with smaller " \ | 124 | "<p>The request could be re-tried with smaller " \ |
125 | "<b>"Cookie:"</b> field value, shorter other field lines, " \ | 125 | "<b>"Cookie:"</b> field value, shorter other field lines, " \ |
126 | "a shorter request target or a shorter request method token.</p></body> " \ | 126 | "a shorter request target or a shorter request method token.</p></body> " \ |
@@ -447,7 +447,7 @@ | |||
447 | #define REQUEST_LACKS_HOST \ | 447 | #define REQUEST_LACKS_HOST \ |
448 | "<html>" \ | 448 | "<html>" \ |
449 | "<head><title>"Host:" header required</title></head>" \ | 449 | "<head><title>"Host:" header required</title></head>" \ |
450 | "<body>HTTP/1.1 request without <b>"Host:"</b>.</body>"\ | 450 | "<body>HTTP/1.1 request without <b>"Host:"</b>.</body>" \ |
451 | "</html>" | 451 | "</html>" |
452 | 452 | ||
453 | #else | 453 | #else |
@@ -556,7 +556,7 @@ | |||
556 | #define ERROR_MSG_DATA_NOT_HANDLED_BY_APP \ | 556 | #define ERROR_MSG_DATA_NOT_HANDLED_BY_APP \ |
557 | "<html><head><title>Internal server error</title></head>" \ | 557 | "<html><head><title>Internal server error</title></head>" \ |
558 | "<body>Please ask the developer of this Web server to carefully " \ | 558 | "<body>Please ask the developer of this Web server to carefully " \ |
559 | "read the GNU libmicrohttpd documentation about connection "\ | 559 | "read the GNU libmicrohttpd documentation about connection " \ |
560 | "management and blocking.</body></html>" | 560 | "management and blocking.</body></html>" |
561 | #else | 561 | #else |
562 | #define ERROR_MSG_DATA_NOT_HANDLED_BY_APP "" | 562 | #define ERROR_MSG_DATA_NOT_HANDLED_BY_APP "" |
@@ -2785,7 +2785,8 @@ transmit_error_response_len (struct MHD_Connection *connection, | |||
2785 | { /* Should not happen */ | 2785 | { /* Should not happen */ |
2786 | if (MHD_CONNECTION_CLOSED > connection->state) | 2786 | if (MHD_CONNECTION_CLOSED > connection->state) |
2787 | connection->state = MHD_CONNECTION_CLOSED; | 2787 | connection->state = MHD_CONNECTION_CLOSED; |
2788 | 2788 | free (header_name); | |
2789 | free (header_value); | ||
2789 | return; | 2790 | return; |
2790 | } | 2791 | } |
2791 | connection->stop_with_error = true; | 2792 | connection->stop_with_error = true; |
@@ -2808,6 +2809,8 @@ transmit_error_response_len (struct MHD_Connection *connection, | |||
2808 | #endif | 2809 | #endif |
2809 | CONNECTION_CLOSE_ERROR (connection, | 2810 | CONNECTION_CLOSE_ERROR (connection, |
2810 | _ ("Too late for error response.")); | 2811 | _ ("Too late for error response.")); |
2812 | free (header_name); | ||
2813 | free (header_value); | ||
2811 | return; | 2814 | return; |
2812 | } | 2815 | } |
2813 | /* TODO: remove when special error queue function is implemented */ | 2816 | /* TODO: remove when special error queue function is implemented */ |
@@ -2840,6 +2843,8 @@ transmit_error_response_len (struct MHD_Connection *connection, | |||
2840 | #endif | 2843 | #endif |
2841 | /* can't even send a reply, at least close the connection */ | 2844 | /* can't even send a reply, at least close the connection */ |
2842 | connection->state = MHD_CONNECTION_CLOSED; | 2845 | connection->state = MHD_CONNECTION_CLOSED; |
2846 | free (header_name); | ||
2847 | free (header_value); | ||
2843 | return; | 2848 | return; |
2844 | } | 2849 | } |
2845 | mhd_assert ((0 == header_name_len) || (NULL != header_name)); | 2850 | mhd_assert ((0 == header_name_len) || (NULL != header_name)); |
@@ -2850,7 +2855,8 @@ transmit_error_response_len (struct MHD_Connection *connection, | |||
2850 | mhd_assert ((NULL != header_value) || (NULL == header_name)); | 2855 | mhd_assert ((NULL != header_value) || (NULL == header_name)); |
2851 | if (NULL != header_name) | 2856 | if (NULL != header_name) |
2852 | { | 2857 | { |
2853 | iret = MHD_add_response_entry_no_alloc_ (response, MHD_HEADER_KIND, | 2858 | iret = MHD_add_response_entry_no_alloc_ (response, |
2859 | MHD_HEADER_KIND, | ||
2854 | header_name, header_name_len, | 2860 | header_name, header_name_len, |
2855 | header_value, header_value_len); | 2861 | header_value, header_value_len); |
2856 | if (MHD_NO == iret) | 2862 | if (MHD_NO == iret) |
@@ -5447,15 +5453,16 @@ send_redirect_fixed_rq_target (struct MHD_Connection *c) | |||
5447 | size_t o; | 5453 | size_t o; |
5448 | char *hdr_name; | 5454 | char *hdr_name; |
5449 | size_t hdr_name_len; | 5455 | size_t hdr_name_len; |
5456 | |||
5450 | mhd_assert (MHD_CONNECTION_REQ_LINE_RECEIVING == c->state); | 5457 | mhd_assert (MHD_CONNECTION_REQ_LINE_RECEIVING == c->state); |
5451 | mhd_assert (0 != c->rq.hdrs.rq_line.num_ws_in_uri); | 5458 | mhd_assert (0 != c->rq.hdrs.rq_line.num_ws_in_uri); |
5452 | mhd_assert (c->rq.hdrs.rq_line.num_ws_in_uri <= \ | 5459 | mhd_assert (c->rq.hdrs.rq_line.num_ws_in_uri <= \ |
5453 | c->rq.req_target_len); | 5460 | c->rq.req_target_len); |
5454 | fixed_uri_len = c->rq.req_target_len | 5461 | fixed_uri_len = c->rq.req_target_len |
5455 | + 2 * c->rq.hdrs.rq_line.num_ws_in_uri; | 5462 | + 2 * c->rq.hdrs.rq_line.num_ws_in_uri; |
5456 | if ((fixed_uri_len + 200 > c->daemon->pool_size) || | 5463 | if ( (fixed_uri_len + 200 > c->daemon->pool_size) || |
5457 | (fixed_uri_len > MHD_MAX_FIXED_URI_LEN) || | 5464 | (fixed_uri_len > MHD_MAX_FIXED_URI_LEN) || |
5458 | (NULL == (b = malloc (fixed_uri_len + 1)))) | 5465 | (NULL == (b = malloc (fixed_uri_len + 1))) ) |
5459 | { | 5466 | { |
5460 | connection_close_error (c, | 5467 | connection_close_error (c, |
5461 | _ ("The request has whitespace character is " \ | 5468 | _ ("The request has whitespace character is " \ |
@@ -5469,6 +5476,7 @@ send_redirect_fixed_rq_target (struct MHD_Connection *c) | |||
5469 | do | 5476 | do |
5470 | { | 5477 | { |
5471 | const char chr = c->rq.hdrs.rq_line.rq_tgt[i++]; | 5478 | const char chr = c->rq.hdrs.rq_line.rq_tgt[i++]; |
5479 | |||
5472 | mhd_assert ('\r' != chr); /* Replaced during request line parsing */ | 5480 | mhd_assert ('\r' != chr); /* Replaced during request line parsing */ |
5473 | mhd_assert ('\n' != chr); /* Rejected during request line parsing */ | 5481 | mhd_assert ('\n' != chr); /* Rejected during request line parsing */ |
5474 | mhd_assert (0 != chr); /* Rejected during request line parsing */ | 5482 | mhd_assert (0 != chr); /* Rejected during request line parsing */ |
@@ -5506,11 +5514,17 @@ send_redirect_fixed_rq_target (struct MHD_Connection *c) | |||
5506 | hdr_name = malloc (hdr_name_len + 1); | 5514 | hdr_name = malloc (hdr_name_len + 1); |
5507 | if (NULL != hdr_name) | 5515 | if (NULL != hdr_name) |
5508 | { | 5516 | { |
5509 | memcpy (hdr_name, MHD_HTTP_HEADER_LOCATION, hdr_name_len + 1); | 5517 | memcpy (hdr_name, |
5510 | transmit_error_response_header (c, MHD_HTTP_MOVED_PERMANENTLY, | 5518 | MHD_HTTP_HEADER_LOCATION, |
5519 | hdr_name_len + 1); | ||
5520 | /* hdr_name and b are free()d within this call */ | ||
5521 | transmit_error_response_header (c, | ||
5522 | MHD_HTTP_MOVED_PERMANENTLY, | ||
5511 | RQ_TARGET_INVALID_CHAR, | 5523 | RQ_TARGET_INVALID_CHAR, |
5512 | hdr_name, hdr_name_len, | 5524 | hdr_name, |
5513 | b, o); | 5525 | hdr_name_len, |
5526 | b, | ||
5527 | o); | ||
5514 | return; | 5528 | return; |
5515 | } | 5529 | } |
5516 | free (b); | 5530 | free (b); |