diff options
author | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2023-04-05 16:48:35 +0300 |
---|---|---|
committer | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2023-04-05 19:44:49 +0300 |
commit | edf692a61627394c26132e203857afc5237495c3 (patch) | |
tree | 0d06ed9cad5859d2051553da6f492a8e15fc50f9 /src/microhttpd | |
parent | 95ad2a9a480435e86dfa1bbd7a6798150320d3bd (diff) | |
download | libmicrohttpd-edf692a61627394c26132e203857afc5237495c3.tar.gz libmicrohttpd-edf692a61627394c26132e203857afc5237495c3.zip |
Implemented and used new function MHD_pool_deallocate()
The new function has special handling for user-poison mode.
Diffstat (limited to 'src/microhttpd')
-rw-r--r-- | src/microhttpd/connection.c | 27 | ||||
-rw-r--r-- | src/microhttpd/memorypool.c | 103 | ||||
-rw-r--r-- | src/microhttpd/memorypool.h | 18 | ||||
-rw-r--r-- | src/microhttpd/response.c | 33 |
4 files changed, 152 insertions, 29 deletions
diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c index f378334c..82b127b9 100644 --- a/src/microhttpd/connection.c +++ b/src/microhttpd/connection.c | |||
@@ -1597,11 +1597,20 @@ connection_shrink_read_buffer (struct MHD_Connection *connection) | |||
1597 | } | 1597 | } |
1598 | 1598 | ||
1599 | mhd_assert (c->read_buffer_offset <= c->read_buffer_size); | 1599 | mhd_assert (c->read_buffer_offset <= c->read_buffer_size); |
1600 | new_buf = MHD_pool_reallocate (c->pool, c->read_buffer, c->read_buffer_size, | 1600 | if (0 == c->read_buffer_offset) |
1601 | c->read_buffer_offset); | 1601 | { |
1602 | mhd_assert (c->read_buffer == new_buf); | 1602 | MHD_pool_deallocate (c->pool, c->read_buffer, c->read_buffer_size); |
1603 | c->read_buffer = new_buf; | 1603 | c->read_buffer = NULL; |
1604 | c->read_buffer_size = c->read_buffer_offset; | 1604 | c->read_buffer_size = 0; |
1605 | } | ||
1606 | else | ||
1607 | { | ||
1608 | new_buf = MHD_pool_reallocate (c->pool, c->read_buffer, c->read_buffer_size, | ||
1609 | c->read_buffer_offset); | ||
1610 | mhd_assert (c->read_buffer == new_buf); | ||
1611 | c->read_buffer = new_buf; | ||
1612 | c->read_buffer_size = c->read_buffer_offset; | ||
1613 | } | ||
1605 | } | 1614 | } |
1606 | 1615 | ||
1607 | 1616 | ||
@@ -2424,10 +2433,10 @@ transmit_error_response_len (struct MHD_Connection *connection, | |||
2424 | { | 2433 | { |
2425 | /* Read buffer is not needed anymore, discard it | 2434 | /* Read buffer is not needed anymore, discard it |
2426 | * to free some space for error response. */ | 2435 | * to free some space for error response. */ |
2427 | connection->read_buffer = MHD_pool_reallocate (connection->pool, | 2436 | MHD_pool_deallocate (connection->pool, |
2428 | connection->read_buffer, | 2437 | connection->read_buffer, |
2429 | connection->read_buffer_size, | 2438 | connection->read_buffer_size); |
2430 | 0); | 2439 | connection->read_buffer = NULL; |
2431 | connection->read_buffer_size = 0; | 2440 | connection->read_buffer_size = 0; |
2432 | connection->read_buffer_offset = 0; | 2441 | connection->read_buffer_offset = 0; |
2433 | } | 2442 | } |
diff --git a/src/microhttpd/memorypool.c b/src/microhttpd/memorypool.c index e0511830..8d80f888 100644 --- a/src/microhttpd/memorypool.c +++ b/src/microhttpd/memorypool.c | |||
@@ -577,6 +577,109 @@ MHD_pool_reallocate (struct MemoryPool *pool, | |||
577 | 577 | ||
578 | 578 | ||
579 | /** | 579 | /** |
580 | * Deallocate a block of memory obtained from the pool. | ||
581 | * | ||
582 | * If the given block is not the most recently | ||
583 | * (re)allocated block, the memory of the this block | ||
584 | * allocation may be not released until the pool is | ||
585 | * destroyed or reset. | ||
586 | * | ||
587 | * @param pool memory pool to use for the operation | ||
588 | * @param block the allocated block, the NULL is tolerated | ||
589 | * @param block_size the size of the allocated block | ||
590 | */ | ||
591 | void | ||
592 | MHD_pool_deallocate (struct MemoryPool *pool, | ||
593 | void *block, | ||
594 | size_t block_size) | ||
595 | { | ||
596 | mhd_assert (pool->end >= pool->pos); | ||
597 | mhd_assert (pool->size >= pool->end - pool->pos); | ||
598 | mhd_assert (block != NULL || block_size == 0); | ||
599 | mhd_assert (pool->size >= block_size); | ||
600 | mhd_assert (pool->pos == ROUND_TO_ALIGN (pool->pos)); | ||
601 | |||
602 | if (NULL != block) | ||
603 | { /* Have previously allocated data */ | ||
604 | const size_t block_offset = mp_ptr_diff_ (block, pool->memory); | ||
605 | mhd_assert (mp_ptr_le_ (pool->memory, block)); | ||
606 | mhd_assert (block_offset <= pool->size); | ||
607 | mhd_assert ((block_offset != pool->pos) || (block_size == 0)); | ||
608 | /* Zero-out deallocated region */ | ||
609 | if (0 != block_size) | ||
610 | { | ||
611 | memset (block, 0, block_size); | ||
612 | _MHD_POISON_MEMORY (block, block_size); | ||
613 | } | ||
614 | #if ! defined(MHD_FAVOR_SMALL_CODE) && ! defined(MHD_ASAN_POISON_ACTIVE) | ||
615 | else | ||
616 | return; /* Zero size, no need to do anything */ | ||
617 | #endif /* ! MHD_FAVOR_SMALL_CODE && ! MHD_ASAN_POISON_ACTIVE */ | ||
618 | if (block_offset <= pool->pos) | ||
619 | { | ||
620 | /* "Normal" block, not allocated "from the end". */ | ||
621 | const size_t alg_end = | ||
622 | ROUND_TO_ALIGN_PLUS_RED_ZONE (block_offset + block_size); | ||
623 | mhd_assert (alg_end <= pool->pos); | ||
624 | if (alg_end == pool->pos) | ||
625 | { | ||
626 | /* The last allocated block, return deallocated block to the pool */ | ||
627 | size_t alg_start = ROUND_TO_ALIGN (block_offset); | ||
628 | mhd_assert (alg_start >= block_offset); | ||
629 | #if defined(MHD_ASAN_POISON_ACTIVE) | ||
630 | if (alg_start != block_offset) | ||
631 | { | ||
632 | _MHD_POISON_MEMORY (pool->memory + block_offset, \ | ||
633 | alg_start - block_offset); | ||
634 | } | ||
635 | else if (0 != alg_start) | ||
636 | { | ||
637 | bool need_red_zone_before; | ||
638 | mhd_assert (_MHD_RED_ZONE_SIZE <= alg_start); | ||
639 | #if defined(HAVE___ASAN_REGION_IS_POISONED) | ||
640 | need_red_zone_before = | ||
641 | (NULL == __asan_region_is_poisoned (pool->memory | ||
642 | + alg_start | ||
643 | - _MHD_RED_ZONE_SIZE, | ||
644 | _MHD_RED_ZONE_SIZE)); | ||
645 | #elif defined(HAVE___ASAN_ADDRESS_IS_POISONED) | ||
646 | need_red_zone_before = | ||
647 | (0 == __asan_address_is_poisoned (pool->memory + alg_start - 1)); | ||
648 | #else /* ! HAVE___ASAN_ADDRESS_IS_POISONED */ | ||
649 | need_red_zone_before = true; /* Unknown, assume new red zone needed */ | ||
650 | #endif /* ! HAVE___ASAN_ADDRESS_IS_POISONED */ | ||
651 | if (need_red_zone_before) | ||
652 | { | ||
653 | _MHD_POISON_MEMORY (pool->memory + alg_start, _MHD_RED_ZONE_SIZE); | ||
654 | alg_start += _MHD_RED_ZONE_SIZE; | ||
655 | } | ||
656 | } | ||
657 | #endif /* MHD_ASAN_POISON_ACTIVE */ | ||
658 | mhd_assert (alg_start <= pool->pos); | ||
659 | mhd_assert (alg_start == ROUND_TO_ALIGN (alg_start)); | ||
660 | pool->pos = alg_start; | ||
661 | } | ||
662 | } | ||
663 | else | ||
664 | { | ||
665 | /* Allocated "from the end" block. */ | ||
666 | /* The size and the pointers of such block should not be manipulated by | ||
667 | MHD code (block split is disallowed). */ | ||
668 | mhd_assert (block_offset >= pool->end); | ||
669 | mhd_assert (ROUND_TO_ALIGN (block_offset) == block_offset); | ||
670 | if (block_offset == pool->end) | ||
671 | { | ||
672 | /* The last allocated block, return deallocated block to the pool */ | ||
673 | const size_t alg_end = | ||
674 | ROUND_TO_ALIGN_PLUS_RED_ZONE (block_offset + block_size); | ||
675 | pool->end = alg_end; | ||
676 | } | ||
677 | } | ||
678 | } | ||
679 | } | ||
680 | |||
681 | |||
682 | /** | ||
580 | * Clear all entries from the memory pool except | 683 | * Clear all entries from the memory pool except |
581 | * for @a keep of the given @a copy_bytes. The pointer | 684 | * for @a keep of the given @a copy_bytes. The pointer |
582 | * returned should be a buffer of @a new_size where | 685 | * returned should be a buffer of @a new_size where |
diff --git a/src/microhttpd/memorypool.h b/src/microhttpd/memorypool.h index 98f96bda..49bbcbe1 100644 --- a/src/microhttpd/memorypool.h +++ b/src/microhttpd/memorypool.h | |||
@@ -148,6 +148,24 @@ MHD_pool_get_free (struct MemoryPool *pool); | |||
148 | 148 | ||
149 | 149 | ||
150 | /** | 150 | /** |
151 | * Deallocate a block of memory obtained from the pool. | ||
152 | * | ||
153 | * If the given block is not the most recently | ||
154 | * (re)allocated block, the memory of the this block | ||
155 | * allocation may be not released until the pool is | ||
156 | * destroyed or reset. | ||
157 | * | ||
158 | * @param pool memory pool to use for the operation | ||
159 | * @param block the allocated block, the NULL is tolerated | ||
160 | * @param block_size the size of the allocated block | ||
161 | */ | ||
162 | void | ||
163 | MHD_pool_deallocate (struct MemoryPool *pool, | ||
164 | void *block, | ||
165 | size_t block_size); | ||
166 | |||
167 | |||
168 | /** | ||
151 | * Clear all entries from the memory pool except | 169 | * Clear all entries from the memory pool except |
152 | * for @a keep of the given @a copy_bytes. The pointer | 170 | * for @a keep of the given @a copy_bytes. The pointer |
153 | * returned should be a buffer of @a new_size where | 171 | * returned should be a buffer of @a new_size where |
diff --git a/src/microhttpd/response.c b/src/microhttpd/response.c index 159c8ecb..d125ea24 100644 --- a/src/microhttpd/response.c +++ b/src/microhttpd/response.c | |||
@@ -2148,28 +2148,21 @@ MHD_response_execute_upgrade_ (struct MHD_Response *response, | |||
2148 | size_t avail; | 2148 | size_t avail; |
2149 | char *buf; | 2149 | char *buf; |
2150 | 2150 | ||
2151 | if (0 != connection->write_buffer_size) | 2151 | /* All data should be sent already */ |
2152 | { | 2152 | mhd_assert (connection->write_buffer_send_offset == \ |
2153 | mhd_assert (NULL != connection->write_buffer); | 2153 | connection->write_buffer_append_offset); |
2154 | /* All data should be sent already */ | 2154 | MHD_pool_deallocate (pool, connection->write_buffer, |
2155 | mhd_assert (connection->write_buffer_send_offset == \ | 2155 | connection->write_buffer_size); |
2156 | connection->write_buffer_append_offset); | 2156 | connection->write_buffer_append_offset = 0; |
2157 | (void) MHD_pool_reallocate (pool, connection->write_buffer, | 2157 | connection->write_buffer_send_offset = 0; |
2158 | connection->write_buffer_size, 0); | 2158 | connection->write_buffer_size = 0; |
2159 | connection->write_buffer_append_offset = 0; | ||
2160 | connection->write_buffer_send_offset = 0; | ||
2161 | connection->write_buffer_size = 0; | ||
2162 | } | ||
2163 | connection->write_buffer = NULL; | 2159 | connection->write_buffer = NULL; |
2164 | 2160 | ||
2165 | if (0 != connection->read_buffer_size) | 2161 | /* Extra read data should be processed already by the application */ |
2166 | { | 2162 | MHD_pool_deallocate (pool, connection->read_buffer, |
2167 | mhd_assert (NULL != connection->read_buffer); | 2163 | connection->read_buffer_size); |
2168 | (void) MHD_pool_reallocate (pool, connection->read_buffer, | 2164 | connection->read_buffer_offset = 0; |
2169 | connection->read_buffer_size, 0); | 2165 | connection->read_buffer_size = 0; |
2170 | connection->read_buffer_offset = 0; | ||
2171 | connection->read_buffer_size = 0; | ||
2172 | } | ||
2173 | connection->read_buffer = NULL; | 2166 | connection->read_buffer = NULL; |
2174 | 2167 | ||
2175 | avail = MHD_pool_get_free (pool); | 2168 | avail = MHD_pool_get_free (pool); |