|
22 | 22 | #include <stddef.h>
|
23 | 23 | #include <fcntl.h>
|
24 | 24 |
|
| 25 | +#ifndef ZEND_HEAP_CHECK |
| 26 | +# define ZEND_HEAP_CHECK(condition, message) do { \ |
| 27 | + if (UNEXPECTED(!(condition))) { \ |
| 28 | + zend_heap(message); \ |
| 29 | + } \ |
| 30 | + } while (0) |
| 31 | +#endif |
| 32 | + |
25 | 33 | #include "php_streams_int.h"
|
26 | 34 |
|
27 | 35 | /* Global filter hash, copied to FG(stream_filters) on registration of volatile filter */
|
28 | 36 | static HashTable stream_filters_hash;
|
29 | 37 |
|
| 38 | +static ZEND_COLD ZEND_NORETURN void zend_heap(const char *message) |
| 39 | +{ |
| 40 | + fprintf(stderr, "%s\n", message); |
| 41 | +/* See http://support.microsoft.com/kb/190351 */ |
| 42 | +#ifdef ZEND_WIN32 |
| 43 | + fflush(stderr); |
| 44 | +#endif |
| 45 | +#if ZEND_DEBUG && defined(HAVE_KILL) && defined(HAVE_GETPID) |
| 46 | + kill(getpid(), SIGSEGV); |
| 47 | +#endif |
| 48 | + abort(); |
| 49 | +} |
| 50 | + |
| 51 | + |
30 | 52 | /* Should only be used during core initialization */
|
31 | 53 | PHPAPI HashTable *php_get_stream_filters_hash_global(void)
|
32 | 54 | {
|
@@ -192,11 +214,13 @@ PHPAPI void php_stream_bucket_append(php_stream_bucket_brigade *brigade, php_str
|
192 | 214 | PHPAPI void php_stream_bucket_unlink(php_stream_bucket *bucket)
|
193 | 215 | {
|
194 | 216 | if (bucket->prev) {
|
| 217 | + ZEND_HEAP_CHECK(bucket->prev->next == bucket, "Stream bucket list corruption."); |
195 | 218 | bucket->prev->next = bucket->next;
|
196 | 219 | } else if (bucket->brigade) {
|
197 | 220 | bucket->brigade->head = bucket->next;
|
198 | 221 | }
|
199 | 222 | if (bucket->next) {
|
| 223 | + ZEND_HEAP_CHECK(bucket->next->prev == bucket, "Stream bucket list corruption."); |
200 | 224 | bucket->next->prev = bucket->prev;
|
201 | 225 | } else if (bucket->brigade) {
|
202 | 226 | bucket->brigade->tail = bucket->prev;
|
|
0 commit comments