Diff for /embedaddon/php/Zend/zend_alloc.c between versions 1.1.1.1 and 1.1.1.2

version 1.1.1.1, 2012/02/21 23:47:52 version 1.1.1.2, 2012/05/29 12:34:35
Line 32 Line 32
 # include <unistd.h>  # include <unistd.h>
 #endif  #endif
   
 #if SUHOSIN_PATCH  
 #include "suhosin_patch.h"  
 #endif  
   
 #ifdef ZEND_WIN32  #ifdef ZEND_WIN32
 # include <wincrypt.h>  # include <wincrypt.h>
 # include <process.h>  # include <process.h>
Line 63 Line 59
 # define PTR_FMT "0x%0.8lx"  # define PTR_FMT "0x%0.8lx"
 #endif  #endif
   
 #ifndef SUHOSIN_MM_CLONE_FILE  
 #if ZEND_DEBUG  #if ZEND_DEBUG
 void zend_debug_alloc_output(char *format, ...)  void zend_debug_alloc_output(char *format, ...)
 {  {
Line 81  void zend_debug_alloc_output(char *format, ...) Line 76  void zend_debug_alloc_output(char *format, ...)
 #endif  #endif
 }  }
 #endif  #endif
 #endif  
   
 #if (defined (__GNUC__) && __GNUC__ > 2 ) && !defined(__INTEL_COMPILER) && !defined(DARWIN) && !defined(__hpux) && !defined(_AIX)  #if (defined (__GNUC__) && __GNUC__ > 2 ) && !defined(__INTEL_COMPILER) && !defined(DARWIN) && !defined(__hpux) && !defined(_AIX)
 static void zend_mm_panic(const char *message) __attribute__ ((noreturn));  static void zend_mm_panic(const char *message) __attribute__ ((noreturn));
Line 140  static void zend_mm_panic(const char *message) Line 134  static void zend_mm_panic(const char *message)
 # endif  # endif
 #endif  #endif
   
 static zend_intptr_t SUHOSIN_POINTER_GUARD = 0;  
   
 static zend_mm_storage* zend_mm_mem_dummy_init(void *params)  static zend_mm_storage* zend_mm_mem_dummy_init(void *params)
 {  {
         return malloc(sizeof(zend_mm_storage));          return malloc(sizeof(zend_mm_storage));
Line 340  static const zend_mm_mem_handlers mem_handlers[] = { Line 332  static const zend_mm_mem_handlers mem_handlers[] = {
 #define MEM_BLOCK_GUARD  0x2A8FCC84  #define MEM_BLOCK_GUARD  0x2A8FCC84
 #define MEM_BLOCK_LEAK   0x6C5E8F2D  #define MEM_BLOCK_LEAK   0x6C5E8F2D
   
 #if SUHOSIN_MM_WITH_CANARY_PROTECTION  
 # define CANARY_SIZE sizeof(size_t)  
 #else  
 # define CANARY_SIZE 0  
 #endif  
   
 /* mm block type */  /* mm block type */
 typedef struct _zend_mm_block_info {  typedef struct _zend_mm_block_info {
 #if ZEND_MM_COOKIES  #if ZEND_MM_COOKIES
         size_t _cookie;          size_t _cookie;
 #endif  #endif
#if SUHOSIN_MM_WITH_CANARY_PROTECTION        size_t _size;
        size_t canary_1;        size_t _prev;
#endif 
        size_t _size; 
        size_t _prev; 
#if SUHOSIN_PATCH 
        size_t size; 
#if SUHOSIN_MM_WITH_CANARY_PROTECTION 
        size_t canary_2; 
#endif 
#endif 
 } zend_mm_block_info;  } zend_mm_block_info;
   
 #if ZEND_DEBUG  #if ZEND_DEBUG
   
 typedef struct _zend_mm_debug_info {  typedef struct _zend_mm_debug_info {
        char *filename;        const char *filename;
         uint lineno;          uint lineno;
        char *orig_filename;        const char *orig_filename;
         uint orig_lineno;          uint orig_lineno;
         size_t size;          size_t size;
 #if ZEND_MM_HEAP_PROTECTION  #if ZEND_MM_HEAP_PROTECTION
Line 435  typedef struct _zend_mm_free_block { Line 412  typedef struct _zend_mm_free_block {
 # define ZEND_MM_CACHE_STAT 0  # define ZEND_MM_CACHE_STAT 0
 #endif  #endif
   
typedef struct _zend_mm_heap {struct _zend_mm_heap {
         int                 use_zend_alloc;          int                 use_zend_alloc;
         void               *(*_malloc)(size_t);          void               *(*_malloc)(size_t);
         void                (*_free)(void*);          void                (*_free)(void*);
Line 462  typedef struct _zend_mm_heap { Line 439  typedef struct _zend_mm_heap {
         zend_mm_free_block *free_buckets[ZEND_MM_NUM_BUCKETS*2];          zend_mm_free_block *free_buckets[ZEND_MM_NUM_BUCKETS*2];
         zend_mm_free_block *large_free_buckets[ZEND_MM_NUM_BUCKETS];          zend_mm_free_block *large_free_buckets[ZEND_MM_NUM_BUCKETS];
         zend_mm_free_block *rest_buckets[2];          zend_mm_free_block *rest_buckets[2];
           int                 rest_count;
 #if ZEND_MM_CACHE_STAT  #if ZEND_MM_CACHE_STAT
         struct {          struct {
                 int count;                  int count;
Line 470  typedef struct _zend_mm_heap { Line 448  typedef struct _zend_mm_heap {
                 int miss;                  int miss;
         } cache_stat[ZEND_MM_NUM_BUCKETS+1];          } cache_stat[ZEND_MM_NUM_BUCKETS+1];
 #endif  #endif
 #if SUHOSIN_PATCH  
         size_t              canary_1,canary_2,canary_3;  
 #endif  
 };  };
   
 #define ZEND_MM_SMALL_FREE_BUCKET(heap, index) \  #define ZEND_MM_SMALL_FREE_BUCKET(heap, index) \
Line 485  typedef struct _zend_mm_heap { Line 460  typedef struct _zend_mm_heap {
                 sizeof(zend_mm_free_block*) * 2 - \                  sizeof(zend_mm_free_block*) * 2 - \
                 sizeof(zend_mm_small_free_block))                  sizeof(zend_mm_small_free_block))
   
   #define ZEND_MM_REST_BLOCK ((zend_mm_free_block**)(zend_uintptr_t)(1))
   
   #define ZEND_MM_MAX_REST_BLOCKS 16
   
 #if ZEND_MM_COOKIES  #if ZEND_MM_COOKIES
   
 static unsigned int _zend_mm_cookie = 0;  static unsigned int _zend_mm_cookie = 0;
Line 546  static unsigned int _zend_mm_cookie = 0; Line 525  static unsigned int _zend_mm_cookie = 0;
 /* optimized access */  /* optimized access */
 #define ZEND_MM_FREE_BLOCK_SIZE(b)              (b)->info._size  #define ZEND_MM_FREE_BLOCK_SIZE(b)              (b)->info._size
   
 #ifndef ZEND_MM_ALIGNMENT  
 # define ZEND_MM_ALIGNMENT 8  
 # define ZEND_MM_ALIGNMENT_LOG2 3  
 #elif ZEND_MM_ALIGNMENT < 4  
 # undef ZEND_MM_ALIGNMENT  
 # undef ZEND_MM_ALIGNMENT_LOG2  
 # define ZEND_MM_ALIGNMENT 4  
 # define ZEND_MM_ALIGNMENT_LOG2 2  
 #endif  
   
 #define ZEND_MM_ALIGNMENT_MASK ~(ZEND_MM_ALIGNMENT-1)  
   
 /* Aligned header size */  /* Aligned header size */
 #define ZEND_MM_ALIGNED_SIZE(size)                      ((size + ZEND_MM_ALIGNMENT - 1) & ZEND_MM_ALIGNMENT_MASK)  
 #define ZEND_MM_ALIGNED_HEADER_SIZE                     ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_block))  #define ZEND_MM_ALIGNED_HEADER_SIZE                     ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_block))
 #define ZEND_MM_ALIGNED_FREE_HEADER_SIZE        ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_small_free_block))  #define ZEND_MM_ALIGNED_FREE_HEADER_SIZE        ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_small_free_block))
#define ZEND_MM_MIN_ALLOC_BLOCK_SIZE            ZEND_MM_ALIGNED_SIZE(ZEND_MM_ALIGNED_HEADER_SIZE + END_MAGIC_SIZE + CANARY_SIZE)#define ZEND_MM_MIN_ALLOC_BLOCK_SIZE            ZEND_MM_ALIGNED_SIZE(ZEND_MM_ALIGNED_HEADER_SIZE + END_MAGIC_SIZE)
 #define ZEND_MM_ALIGNED_MIN_HEADER_SIZE         (ZEND_MM_MIN_ALLOC_BLOCK_SIZE>ZEND_MM_ALIGNED_FREE_HEADER_SIZE?ZEND_MM_MIN_ALLOC_BLOCK_SIZE:ZEND_MM_ALIGNED_FREE_HEADER_SIZE)  #define ZEND_MM_ALIGNED_MIN_HEADER_SIZE         (ZEND_MM_MIN_ALLOC_BLOCK_SIZE>ZEND_MM_ALIGNED_FREE_HEADER_SIZE?ZEND_MM_MIN_ALLOC_BLOCK_SIZE:ZEND_MM_ALIGNED_FREE_HEADER_SIZE)
 #define ZEND_MM_ALIGNED_SEGMENT_SIZE            ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_segment))  #define ZEND_MM_ALIGNED_SEGMENT_SIZE            ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_segment))
   
#define ZEND_MM_MIN_SIZE                                        ((ZEND_MM_ALIGNED_MIN_HEADER_SIZE>(ZEND_MM_ALIGNED_HEADER_SIZE+END_MAGIC_SIZE+CANARY_SIZE))?(ZEND_MM_ALIGNED_MIN_HEADER_SIZE-(ZEND_MM_ALIGNED_HEADER_SIZE+END_MAGIC_SIZE+CANARY_SIZE)):0)#define ZEND_MM_MIN_SIZE                                        ((ZEND_MM_ALIGNED_MIN_HEADER_SIZE>(ZEND_MM_ALIGNED_HEADER_SIZE+END_MAGIC_SIZE))?(ZEND_MM_ALIGNED_MIN_HEADER_SIZE-(ZEND_MM_ALIGNED_HEADER_SIZE+END_MAGIC_SIZE)):0)
   
 #define ZEND_MM_MAX_SMALL_SIZE                          ((ZEND_MM_NUM_BUCKETS<<ZEND_MM_ALIGNMENT_LOG2)+ZEND_MM_ALIGNED_MIN_HEADER_SIZE)  #define ZEND_MM_MAX_SMALL_SIZE                          ((ZEND_MM_NUM_BUCKETS<<ZEND_MM_ALIGNMENT_LOG2)+ZEND_MM_ALIGNED_MIN_HEADER_SIZE)
   
#define ZEND_MM_TRUE_SIZE(size)                         ((size<ZEND_MM_MIN_SIZE)?(ZEND_MM_ALIGNED_MIN_HEADER_SIZE):(ZEND_MM_ALIGNED_SIZE(size+ZEND_MM_ALIGNED_HEADER_SIZE+END_MAGIC_SIZE+CANARY_SIZE)))#define ZEND_MM_TRUE_SIZE(size)                         ((size<ZEND_MM_MIN_SIZE)?(ZEND_MM_ALIGNED_MIN_HEADER_SIZE):(ZEND_MM_ALIGNED_SIZE(size+ZEND_MM_ALIGNED_HEADER_SIZE+END_MAGIC_SIZE)))
   
 #define ZEND_MM_BUCKET_INDEX(true_size)         ((true_size>>ZEND_MM_ALIGNMENT_LOG2)-(ZEND_MM_ALIGNED_MIN_HEADER_SIZE>>ZEND_MM_ALIGNMENT_LOG2))  #define ZEND_MM_BUCKET_INDEX(true_size)         ((true_size>>ZEND_MM_ALIGNMENT_LOG2)-(ZEND_MM_ALIGNED_MIN_HEADER_SIZE>>ZEND_MM_ALIGNMENT_LOG2))
   
Line 632  static unsigned int _zend_mm_cookie = 0; Line 598  static unsigned int _zend_mm_cookie = 0;
   
 #endif  #endif
   
 #if SUHOSIN_MM_WITH_CANARY_PROTECTION  
   
 # define SUHOSIN_MM_CHECK_CANARIES(block, MFUNCTION) do { \  
         char *p = SUHOSIN_MM_END_CANARY_PTR(block); size_t check; \  
         if (((block)->info.canary_1 != heap->canary_1) || ((block)->info.canary_2 != heap->canary_2)) { \  
                 canary_mismatch: \  
                 zend_suhosin_log(S_MEMORY, "canary mismatch on " MFUNCTION " - heap overflow detected at %p", (block)); \  
                 if (SUHOSIN_CONFIG(SUHOSIN_MM_IGNORE_CANARY_VIOLATION) == 0) { _exit(1); } else { (block)->info.canary_1 = heap->canary_1; (block)->info.canary_2 = heap->canary_2; }\  
         } \  
         memcpy(&check, p, CANARY_SIZE); \  
         if (check != heap->canary_3) { \  
                 zend_suhosin_log(S_MEMORY, "end canary mismatch on " MFUNCTION " - heap overflow detected at %p", (block)); \  
                 if (SUHOSIN_CONFIG(SUHOSIN_MM_IGNORE_CANARY_VIOLATION) == 0) { _exit(1); } else { memcpy(p, heap->canary_3, CANARY_SIZE); } \  
         } \  
         } while (0)  
   
 # define SUHOSIN_MM_SET_CANARIES(block) do { \  
         (block)->info.canary_1 = heap->canary_1; \  
         (block)->info.canary_2 = heap->canary_2; \  
         } while (0)        
   
 # define SUHOSIN_MM_END_CANARY_PTR(block) \  
         (char *)(((char*)(ZEND_MM_DATA_OF(block))) + ((zend_mm_block*)(block))->info.size + END_MAGIC_SIZE)  
   
 # define SUHOSIN_MM_SET_END_CANARY(block) do { \  
         char *p = SUHOSIN_MM_END_CANARY_PTR(block); \  
         memcpy(p, &heap->canary_3, CANARY_SIZE); \  
         } while (0)  
   
 #else  
   
 # define SUHOSIN_MM_CHECK_CANARIES(block, MFUNCTION)  
 # define SUHOSIN_MM_SET_CANARIES(block)  
 # define SUHOSIN_MM_END_CANARY_PTR(block)  
 # define SUHOSIN_MM_SET_END_CANARY(block)  
   
 #endif  
   
   
 #if ZEND_MM_HEAP_PROTECTION  #if ZEND_MM_HEAP_PROTECTION
   
 # define ZEND_MM_CHECK_PROTECTION(block) \  # define ZEND_MM_CHECK_PROTECTION(block) \
Line 792  static inline unsigned int zend_mm_low_bit(size_t _siz Line 720  static inline unsigned int zend_mm_low_bit(size_t _siz
 #endif  #endif
 }  }
   
static void zend_mm_add_to_rest_list(zend_mm_heap *heap, zend_mm_free_block *mm_block)static inline void zend_mm_add_to_free_list(zend_mm_heap *heap, zend_mm_free_block *mm_block)
 {  {
         zend_mm_free_block *prev, *next;  
   
         ZEND_MM_SET_MAGIC(mm_block, MEM_BLOCK_FREED);  
   
         if (!ZEND_MM_SMALL_SIZE(ZEND_MM_FREE_BLOCK_SIZE(mm_block))) {  
                 mm_block->parent = NULL;  
         }  
   
         prev = SUHOSIN_MANGLE_PTR(heap->rest_buckets[0]);  
         next = SUHOSIN_MANGLE_PTR(prev->next_free_block);  
         mm_block->prev_free_block = SUHOSIN_MANGLE_PTR(prev);  
         mm_block->next_free_block = SUHOSIN_MANGLE_PTR(next);  
         prev->next_free_block = next->prev_free_block = SUHOSIN_MANGLE_PTR(mm_block);  
 }  
   
 static void zend_mm_add_to_free_list(zend_mm_heap *heap, zend_mm_free_block *mm_block)  
 {  
         size_t size;          size_t size;
         size_t index;          size_t index;
   
Line 826  static void zend_mm_add_to_free_list(zend_mm_heap *hea Line 737  static void zend_mm_add_to_free_list(zend_mm_heap *hea
                 if (!*p) {                  if (!*p) {
                         *p = mm_block;                          *p = mm_block;
                         mm_block->parent = p;                          mm_block->parent = p;
                        mm_block->prev_free_block = mm_block->next_free_block = SUHOSIN_MANGLE_PTR(mm_block);                        mm_block->prev_free_block = mm_block->next_free_block = mm_block;
                         heap->large_free_bitmap |= (ZEND_MM_LONG_CONST(1) << index);                          heap->large_free_bitmap |= (ZEND_MM_LONG_CONST(1) << index);
                 } else {                  } else {
                         size_t m;                          size_t m;
Line 839  static void zend_mm_add_to_free_list(zend_mm_heap *hea Line 750  static void zend_mm_add_to_free_list(zend_mm_heap *hea
                                         if (!*p) {                                          if (!*p) {
                                                 *p = mm_block;                                                  *p = mm_block;
                                                 mm_block->parent = p;                                                  mm_block->parent = p;
                                                mm_block->prev_free_block = mm_block->next_free_block = SUHOSIN_MANGLE_PTR(mm_block);                                                mm_block->prev_free_block = mm_block->next_free_block = mm_block;
                                                 break;                                                  break;
                                         }                                          }
                                 } else {                                  } else {
                                        zend_mm_free_block *next = SUHOSIN_MANGLE_PTR(prev->next_free_block);                                        zend_mm_free_block *next = prev->next_free_block;
   
                                        prev->next_free_block = next->prev_free_block = SUHOSIN_MANGLE_PTR(mm_block);                                        prev->next_free_block = next->prev_free_block = mm_block;
                                        mm_block->next_free_block = SUHOSIN_MANGLE_PTR(next);                                        mm_block->next_free_block = next;
                                        mm_block->prev_free_block = SUHOSIN_MANGLE_PTR(prev);                                        mm_block->prev_free_block = prev;
                                         mm_block->parent = NULL;                                          mm_block->parent = NULL;
                                         break;                                          break;
                                 }                                  }
Line 859  static void zend_mm_add_to_free_list(zend_mm_heap *hea Line 770  static void zend_mm_add_to_free_list(zend_mm_heap *hea
                 index = ZEND_MM_BUCKET_INDEX(size);                  index = ZEND_MM_BUCKET_INDEX(size);
   
                 prev = ZEND_MM_SMALL_FREE_BUCKET(heap, index);                  prev = ZEND_MM_SMALL_FREE_BUCKET(heap, index);
                if (SUHOSIN_MANGLE_PTR(prev->prev_free_block) == prev) {                if (prev->prev_free_block == prev) {
                         heap->free_bitmap |= (ZEND_MM_LONG_CONST(1) << index);                          heap->free_bitmap |= (ZEND_MM_LONG_CONST(1) << index);
                 }                  }
                next = SUHOSIN_MANGLE_PTR(prev->next_free_block);                next = prev->next_free_block;
   
                mm_block->prev_free_block = SUHOSIN_MANGLE_PTR(prev);                mm_block->prev_free_block = prev;
                mm_block->next_free_block = SUHOSIN_MANGLE_PTR(next);                mm_block->next_free_block = next;
                prev->next_free_block = next->prev_free_block = SUHOSIN_MANGLE_PTR(mm_block);                prev->next_free_block = next->prev_free_block = mm_block;
         }          }
 }  }
   
static void zend_mm_remove_from_free_list(zend_mm_heap *heap, zend_mm_free_block *mm_block)static inline void zend_mm_remove_from_free_list(zend_mm_heap *heap, zend_mm_free_block *mm_block)
 {  {
        zend_mm_free_block *prev = SUHOSIN_MANGLE_PTR(mm_block->prev_free_block);        zend_mm_free_block *prev = mm_block->prev_free_block;
        zend_mm_free_block *next = SUHOSIN_MANGLE_PTR(mm_block->next_free_block);        zend_mm_free_block *next = mm_block->next_free_block;
   
         ZEND_MM_CHECK_MAGIC(mm_block, MEM_BLOCK_FREED);          ZEND_MM_CHECK_MAGIC(mm_block, MEM_BLOCK_FREED);
   
         if (EXPECTED(prev == mm_block)) {          if (EXPECTED(prev == mm_block)) {
                 zend_mm_free_block **rp, **cp;                  zend_mm_free_block **rp, **cp;
   
 #if SUHOSIN_PATCH  
                 if (next != mm_block) {  
                         zend_suhosin_log(S_MEMORY, "zend_mm_heap corrupted at %p", mm_block);  
                         _exit(1);  
                 }  
 #endif  
 #if ZEND_MM_SAFE_UNLINKING  #if ZEND_MM_SAFE_UNLINKING
                 if (UNEXPECTED(next != mm_block)) {                  if (UNEXPECTED(next != mm_block)) {
                         zend_mm_panic("zend_mm_heap corrupted");                          zend_mm_panic("zend_mm_heap corrupted");
Line 924  subst_block: Line 829  subst_block:
                 }                  }
         } else {          } else {
   
 #if SUHOSIN_PATCH  
                 if (SUHOSIN_MANGLE_PTR(prev->next_free_block) != mm_block || SUHOSIN_MANGLE_PTR(next->prev_free_block) != mm_block) {  
                         zend_suhosin_log(S_MEMORY, "zend_mm_head corrupted at %p", mm_block);  
                         _exit(1);  
                 }  
 #endif      
   
 #if ZEND_MM_SAFE_UNLINKING  #if ZEND_MM_SAFE_UNLINKING
                if (UNEXPECTED(SUHOSIN_MANGLE_PTR(prev->next_free_block) != mm_block) || UNEXPECTED(SUHOSIN_MANGLE_PTR(next->prev_free_block) != mm_block)) {                if (UNEXPECTED(prev->next_free_block != mm_block) || UNEXPECTED(next->prev_free_block != mm_block)) {
                         zend_mm_panic("zend_mm_heap corrupted");                          zend_mm_panic("zend_mm_heap corrupted");
                 }                  }
 #endif  #endif
   
                prev->next_free_block = SUHOSIN_MANGLE_PTR(next);                prev->next_free_block = next;
                next->prev_free_block = SUHOSIN_MANGLE_PTR(prev);                next->prev_free_block = prev;
   
                 if (EXPECTED(ZEND_MM_SMALL_SIZE(ZEND_MM_FREE_BLOCK_SIZE(mm_block)))) {                  if (EXPECTED(ZEND_MM_SMALL_SIZE(ZEND_MM_FREE_BLOCK_SIZE(mm_block)))) {
                         if (EXPECTED(prev == next)) {                          if (EXPECTED(prev == next)) {
Line 948  subst_block: Line 846  subst_block:
                                         heap->free_bitmap &= ~(ZEND_MM_LONG_CONST(1) << index);                                          heap->free_bitmap &= ~(ZEND_MM_LONG_CONST(1) << index);
                                 }                                  }
                         }                          }
                   } else if (UNEXPECTED(mm_block->parent == ZEND_MM_REST_BLOCK)) {
                           heap->rest_count--;
                 } else if (UNEXPECTED(mm_block->parent != NULL)) {                  } else if (UNEXPECTED(mm_block->parent != NULL)) {
                         goto subst_block;                          goto subst_block;
                 }                  }
         }          }
 }  }
   
static void zend_mm_init(zend_mm_heap *heap)static inline void zend_mm_add_to_rest_list(zend_mm_heap *heap, zend_mm_free_block *mm_block)
 {  {
           zend_mm_free_block *prev, *next;
   
           while (heap->rest_count >= ZEND_MM_MAX_REST_BLOCKS) {
                   zend_mm_free_block *p = heap->rest_buckets[1];
   
                   if (!ZEND_MM_SMALL_SIZE(ZEND_MM_FREE_BLOCK_SIZE(p))) {
                           heap->rest_count--;
                   }
                   prev = p->prev_free_block;
                   next = p->next_free_block;
                   prev->next_free_block = next;
                   next->prev_free_block = prev;
                   zend_mm_add_to_free_list(heap, p);
           }
   
           if (!ZEND_MM_SMALL_SIZE(ZEND_MM_FREE_BLOCK_SIZE(mm_block))) {
                   mm_block->parent = ZEND_MM_REST_BLOCK;
                   heap->rest_count++;
           }
   
           ZEND_MM_SET_MAGIC(mm_block, MEM_BLOCK_FREED);
   
           prev = heap->rest_buckets[0];
           next = prev->next_free_block;
           mm_block->prev_free_block = prev;
           mm_block->next_free_block = next;
           prev->next_free_block = next->prev_free_block = mm_block;
   }
   
   static inline void zend_mm_init(zend_mm_heap *heap)
   {
         zend_mm_free_block* p;          zend_mm_free_block* p;
         int i;          int i;
   
Line 972  static void zend_mm_init(zend_mm_heap *heap) Line 903  static void zend_mm_init(zend_mm_heap *heap)
 #endif  #endif
         p = ZEND_MM_SMALL_FREE_BUCKET(heap, 0);          p = ZEND_MM_SMALL_FREE_BUCKET(heap, 0);
         for (i = 0; i < ZEND_MM_NUM_BUCKETS; i++) {          for (i = 0; i < ZEND_MM_NUM_BUCKETS; i++) {
                p->next_free_block = SUHOSIN_MANGLE_PTR(p);                p->next_free_block = p;
                p->prev_free_block = SUHOSIN_MANGLE_PTR(p);                p->prev_free_block = p;
                 p = (zend_mm_free_block*)((char*)p + sizeof(zend_mm_free_block*) * 2);                  p = (zend_mm_free_block*)((char*)p + sizeof(zend_mm_free_block*) * 2);
                 heap->large_free_buckets[i] = NULL;                  heap->large_free_buckets[i] = NULL;
         }          }
        heap->rest_buckets[0] = heap->rest_buckets[1] = SUHOSIN_MANGLE_PTR(ZEND_MM_REST_BUCKET(heap));        heap->rest_buckets[0] = heap->rest_buckets[1] = ZEND_MM_REST_BUCKET(heap);
#if SUHOSIN_PATCH        heap->rest_count = 0;
        if (SUHOSIN_CONFIG(SUHOSIN_MM_USE_CANARY_PROTECTION)) { 
                zend_canary(&heap->canary_1, sizeof(heap->canary_1)); 
                zend_canary(&heap->canary_2, sizeof(heap->canary_2)); 
                zend_canary(&heap->canary_3, sizeof(heap->canary_3)); 
        } 
#endif 
 }  }
   
 static void zend_mm_del_segment(zend_mm_heap *heap, zend_mm_segment *segment)  static void zend_mm_del_segment(zend_mm_heap *heap, zend_mm_segment *segment)
Line 1005  static void zend_mm_free_cache(zend_mm_heap *heap) Line 930  static void zend_mm_free_cache(zend_mm_heap *heap)
         int i;          int i;
   
         for (i = 0; i < ZEND_MM_NUM_BUCKETS; i++) {          for (i = 0; i < ZEND_MM_NUM_BUCKETS; i++) {
                 /* NULL means NULL even MANGLED */  
                 if (heap->cache[i]) {                  if (heap->cache[i]) {
                        zend_mm_free_block *mm_block = SUHOSIN_MANGLE_PTR(heap->cache[i]);                        zend_mm_free_block *mm_block = heap->cache[i];
   
                         while (mm_block) {                          while (mm_block) {
                                 size_t size = ZEND_MM_BLOCK_SIZE(mm_block);                                  size_t size = ZEND_MM_BLOCK_SIZE(mm_block);
                                zend_mm_free_block *q = SUHOSIN_MANGLE_PTR(mm_block->prev_free_block);                                zend_mm_free_block *q = mm_block->prev_free_block;
                                 zend_mm_block *next_block = ZEND_MM_NEXT_BLOCK(mm_block);                                  zend_mm_block *next_block = ZEND_MM_NEXT_BLOCK(mm_block);
   
                                 heap->cached -= size;                                  heap->cached -= size;
Line 1107  static void zend_mm_random(unsigned char *buf, size_t  Line 1031  static void zend_mm_random(unsigned char *buf, size_t 
 /* }}} */  /* }}} */
 #endif  #endif
   
   
 /* Notes:  /* Notes:
  * - This function may alter the block_sizes values to match platform alignment   * - This function may alter the block_sizes values to match platform alignment
  * - This function does *not* perform sanity checks on the arguments   * - This function does *not* perform sanity checks on the arguments
  */   */
#if SUHOSIN_MM_WITH_CANARY_PROTECTIONZEND_API zend_mm_heap *zend_mm_startup_ex(const zend_mm_mem_handlers *handlers, size_t block_size, size_t reserve_size, int internal, void *params)
zend_mm_heap *__zend_mm_startup_canary_ex(const zend_mm_mem_handlers *handlers, size_t block_size, size_t reserve_size, int internal, void *params) 
#else 
static zend_mm_heap *__zend_mm_startup_ex(const zend_mm_mem_handlers *handlers, size_t block_size, size_t reserve_size, int internal, void *params) 
#endif 
 {  {
         zend_mm_storage *storage;          zend_mm_storage *storage;
         zend_mm_heap    *heap;          zend_mm_heap    *heap;
         zend_mm_free_block *tmp;  
   
 #if 0  #if 0
         int i;          int i;
Line 1154  static zend_mm_heap *__zend_mm_startup_ex(const zend_m Line 1072  static zend_mm_heap *__zend_mm_startup_ex(const zend_m
         }          }
 #endif  #endif
   
         /* get the pointer guardian and ensure low 3 bits are 1 */  
         if (SUHOSIN_POINTER_GUARD == 0) {  
                 zend_canary(&SUHOSIN_POINTER_GUARD, sizeof(SUHOSIN_POINTER_GUARD));  
                 SUHOSIN_POINTER_GUARD |= 7;  
         }  
   
         if (zend_mm_low_bit(block_size) != zend_mm_high_bit(block_size)) {          if (zend_mm_low_bit(block_size) != zend_mm_high_bit(block_size)) {
                 fprintf(stderr, "'block_size' must be a power of two\n");                  fprintf(stderr, "'block_size' must be a power of two\n");
 /* See http://support.microsoft.com/kb/190351 */  /* See http://support.microsoft.com/kb/190351 */
Line 1187  static zend_mm_heap *__zend_mm_startup_ex(const zend_m Line 1099  static zend_mm_heap *__zend_mm_startup_ex(const zend_m
 #endif  #endif
                 exit(255);                  exit(255);
         }          }
           
         heap->storage = storage;          heap->storage = storage;
         heap->block_size = block_size;          heap->block_size = block_size;
         heap->compact_size = 0;          heap->compact_size = 0;
Line 1208  static zend_mm_heap *__zend_mm_startup_ex(const zend_m Line 1119  static zend_mm_heap *__zend_mm_startup_ex(const zend_m
         heap->reserve = NULL;          heap->reserve = NULL;
         heap->reserve_size = reserve_size;          heap->reserve_size = reserve_size;
         if (reserve_size > 0) {          if (reserve_size > 0) {
                heap->reserve = _zend_mm_alloc(heap, reserve_size ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC);                heap->reserve = _zend_mm_alloc_int(heap, reserve_size ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC);
         }          }
         if (internal) {          if (internal) {
                 int i;                  int i;
                 zend_mm_free_block *p, *q, *orig;                  zend_mm_free_block *p, *q, *orig;
                zend_mm_heap *mm_heap = _zend_mm_alloc(heap, sizeof(zend_mm_heap)  ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC);                zend_mm_heap *mm_heap = _zend_mm_alloc_int(heap, sizeof(zend_mm_heap)  ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC);
   
                 *mm_heap = *heap;                  *mm_heap = *heap;
   
Line 1221  static zend_mm_heap *__zend_mm_startup_ex(const zend_m Line 1132  static zend_mm_heap *__zend_mm_startup_ex(const zend_m
                 orig = ZEND_MM_SMALL_FREE_BUCKET(heap, 0);                  orig = ZEND_MM_SMALL_FREE_BUCKET(heap, 0);
                 for (i = 0; i < ZEND_MM_NUM_BUCKETS; i++) {                  for (i = 0; i < ZEND_MM_NUM_BUCKETS; i++) {
                         q = p;                          q = p;
                        while (SUHOSIN_MANGLE_PTR(q->prev_free_block) != orig) {                        while (q->prev_free_block != orig) {
                                q = SUHOSIN_MANGLE_PTR(q->prev_free_block);                                q = q->prev_free_block;
                         }                          }
                        q->prev_free_block = SUHOSIN_MANGLE_PTR(p);                        q->prev_free_block = p;
                         q = p;                          q = p;
                        while (SUHOSIN_MANGLE_PTR(q->next_free_block) != orig) {                        while (q->next_free_block != orig) {
                                q = SUHOSIN_MANGLE_PTR(q->next_free_block);                                q = q->next_free_block;
                         }                          }
                        q->next_free_block = SUHOSIN_MANGLE_PTR(p);                        q->next_free_block = p;
                         p = (zend_mm_free_block*)((char*)p + sizeof(zend_mm_free_block*) * 2);                          p = (zend_mm_free_block*)((char*)p + sizeof(zend_mm_free_block*) * 2);
                         orig = (zend_mm_free_block*)((char*)orig + sizeof(zend_mm_free_block*) * 2);                          orig = (zend_mm_free_block*)((char*)orig + sizeof(zend_mm_free_block*) * 2);
                         if (mm_heap->large_free_buckets[i]) {                          if (mm_heap->large_free_buckets[i]) {
                                 mm_heap->large_free_buckets[i]->parent = &mm_heap->large_free_buckets[i];                                  mm_heap->large_free_buckets[i]->parent = &mm_heap->large_free_buckets[i];
                         }                          }
                 }                  }
                mm_heap->rest_buckets[0] = mm_heap->rest_buckets[1] = SUHOSIN_MANGLE_PTR(ZEND_MM_REST_BUCKET(mm_heap));                mm_heap->rest_buckets[0] = mm_heap->rest_buckets[1] = ZEND_MM_REST_BUCKET(mm_heap);
                 mm_heap->rest_count = 0;
   
                 free(heap);                  free(heap);
                 heap = mm_heap;                  heap = mm_heap;
Line 1244  static zend_mm_heap *__zend_mm_startup_ex(const zend_m Line 1156  static zend_mm_heap *__zend_mm_startup_ex(const zend_m
         return heap;          return heap;
 }  }
   
#if SUHOSIN_MM_WITH_CANARY_PROTECTIONZEND_API zend_mm_heap *zend_mm_startup(void)
zend_mm_heap *__zend_mm_startup_canary(void) 
#else 
static zend_mm_heap *__zend_mm_startup(void) 
#endif 
 {  {
         int i;          int i;
         size_t seg_size;          size_t seg_size;
Line 1318  static zend_mm_heap *__zend_mm_startup(void) Line 1226  static zend_mm_heap *__zend_mm_startup(void)
         return heap;          return heap;
 }  }
   
 #ifndef SUHOSIN_MM_CLONE_FILE  
 zend_mm_heap_canary *__zend_mm_startup_canary_ex(const zend_mm_mem_handlers *handlers, size_t block_size, size_t reserve_size, int internal, void *params);  
 zend_mm_heap_canary *__zend_mm_startup_canary(void);  
   
 ZEND_API zend_mm_heap *zend_mm_startup_ex(const zend_mm_mem_handlers *handlers, size_t block_size, size_t reserve_size, int internal, void *params)  
 {  
         if (SUHOSIN_CONFIG(SUHOSIN_MM_USE_CANARY_PROTECTION)) {  
                 return (zend_mm_heap *)__zend_mm_startup_canary_ex(handlers, block_size, reserve_size, internal, params);  
         }  
         return __zend_mm_startup_ex(handlers, block_size, reserve_size, internal, params);  
 }  
 ZEND_API zend_mm_heap *zend_mm_startup(void)  
 {  
         if (SUHOSIN_CONFIG(SUHOSIN_MM_USE_CANARY_PROTECTION)) {  
                 return (zend_mm_heap *)__zend_mm_startup_canary();  
         }  
         return __zend_mm_startup();          
 }  
   
 #endif  
   
 #if ZEND_DEBUG  #if ZEND_DEBUG
 static long zend_mm_find_leaks(zend_mm_segment *segment, zend_mm_block *b)  static long zend_mm_find_leaks(zend_mm_segment *segment, zend_mm_block *b)
 {  {
Line 1707  static int zend_mm_check_heap(zend_mm_heap *heap, int  Line 1594  static int zend_mm_check_heap(zend_mm_heap *heap, int 
 }  }
 #endif  #endif
   
#if SUHOSIN_MM_WITH_CANARY_PROTECTIONZEND_API void zend_mm_shutdown(zend_mm_heap *heap, int full_shutdown, int silent TSRMLS_DC)
void __zend_mm_shutdown_canary(zend_mm_heap *heap, int full_shutdown, int silent TSRMLS_DC) 
#else 
static void __zend_mm_shutdown(zend_mm_heap *heap, int full_shutdown, int silent TSRMLS_DC) 
#endif 
 {  {
         zend_mm_storage *storage;          zend_mm_storage *storage;
         zend_mm_segment *segment;          zend_mm_segment *segment;
         zend_mm_segment *prev;          zend_mm_segment *prev;
         int internal;          int internal;
   
           if (!heap->use_zend_alloc) {
                   if (full_shutdown) {
                           free(heap);
                   }
                   return;
           }
   
         if (heap->reserve) {          if (heap->reserve) {
 #if ZEND_DEBUG  #if ZEND_DEBUG
                 if (!silent) {                  if (!silent) {
                        _zend_mm_free(heap, heap->reserve ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC);                        _zend_mm_free_int(heap, heap->reserve ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC);
                 }                  }
 #endif  #endif
                 heap->reserve = NULL;                  heap->reserve = NULL;
Line 1782  static void __zend_mm_shutdown(zend_mm_heap *heap, int Line 1672  static void __zend_mm_shutdown(zend_mm_heap *heap, int
         internal = heap->internal;          internal = heap->internal;
         storage = heap->storage;          storage = heap->storage;
         segment = heap->segments_list;          segment = heap->segments_list;
         while (segment) {  
                 prev = segment;  
                 segment = segment->next_segment;  
                 ZEND_MM_STORAGE_FREE(prev);  
         }  
         if (full_shutdown) {          if (full_shutdown) {
                   while (segment) {
                           prev = segment;
                           segment = segment->next_segment;
                           ZEND_MM_STORAGE_FREE(prev);
                   }
                   heap->segments_list = NULL;
                 storage->handlers->dtor(storage);                  storage->handlers->dtor(storage);
                 if (!internal) {                  if (!internal) {
                         free(heap);                          free(heap);
                 }                  }
         } else {          } else {
                   if (segment) {
   #ifndef ZEND_WIN32
                           if (heap->reserve_size) {
                                   while (segment->next_segment) {
                                           prev = segment;
                                           segment = segment->next_segment;
                                           ZEND_MM_STORAGE_FREE(prev);
                                   }
                                   heap->segments_list = segment;
                           } else {
   #endif
                                   do {
                                           prev = segment;
                                           segment = segment->next_segment;
                                           ZEND_MM_STORAGE_FREE(prev);
                                   } while (segment);
                                   heap->segments_list = NULL;
   #ifndef ZEND_WIN32
                           }
   #endif
                   }
                 if (heap->compact_size &&                  if (heap->compact_size &&
                     heap->real_peak > heap->compact_size) {                      heap->real_peak > heap->compact_size) {
                         storage->handlers->compact(storage);                          storage->handlers->compact(storage);
                 }                  }
                 heap->segments_list = NULL;  
                 zend_mm_init(heap);                  zend_mm_init(heap);
                heap->real_size = 0;                if (heap->segments_list) {
                heap->real_peak = 0;                        heap->real_size = heap->segments_list->size;
                         heap->real_peak = heap->segments_list->size;
                 } else {
                         heap->real_size = 0;
                         heap->real_peak = 0;
                 }
                 heap->size = 0;                  heap->size = 0;
                 heap->peak = 0;                  heap->peak = 0;
                   if (heap->segments_list) {
                           /* mark segment as a free block */
                           zend_mm_free_block *b = (zend_mm_free_block*)((char*)heap->segments_list + ZEND_MM_ALIGNED_SEGMENT_SIZE);
                           size_t block_size = heap->segments_list->size - ZEND_MM_ALIGNED_SEGMENT_SIZE - ZEND_MM_ALIGNED_HEADER_SIZE;
   
                           ZEND_MM_MARK_FIRST_BLOCK(b);
                           ZEND_MM_LAST_BLOCK(ZEND_MM_BLOCK_AT(b, block_size));
                           ZEND_MM_BLOCK(b, ZEND_MM_FREE_BLOCK, block_size);
                           zend_mm_add_to_free_list(heap, b);
                   }
                 if (heap->reserve_size) {                  if (heap->reserve_size) {
                        heap->reserve = _zend_mm_alloc(heap, heap->reserve_size  ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC);                        heap->reserve = _zend_mm_alloc_int(heap, heap->reserve_size  ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC);
                 }                  }
                 heap->overflow = 0;                  heap->overflow = 0;
         }          }
 }  }
   
 #ifndef SUHOSIN_MM_CLONE_FILE  
 ZEND_API void zend_mm_shutdown(zend_mm_heap *heap, int full_shutdown, int silent TSRMLS_DC)  
 {  
         if (SUHOSIN_CONFIG(SUHOSIN_MM_USE_CANARY_PROTECTION)) {  
                 __zend_mm_shutdown_canary(heap, full_shutdown, silent TSRMLS_CC);  
                 return;  
         }  
         __zend_mm_shutdown(heap, full_shutdown, silent TSRMLS_CC);  
 }  
 #endif  
   
 static void zend_mm_safe_error(zend_mm_heap *heap,  static void zend_mm_safe_error(zend_mm_heap *heap,
         const char *format,          const char *format,
         size_t limit,          size_t limit,
Line 1831  static void zend_mm_safe_error(zend_mm_heap *heap, Line 1746  static void zend_mm_safe_error(zend_mm_heap *heap,
         size_t size)          size_t size)
 {  {
         if (heap->reserve) {          if (heap->reserve) {
 #if SUHOSIN_MM_WITH_CANARY_PROTECTION             
                 _zend_mm_free_canary_int(heap, heap->reserve ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC);  
 #else  
                 _zend_mm_free_int(heap, heap->reserve ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC);                  _zend_mm_free_int(heap, heap->reserve ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC);
 #endif  
                 heap->reserve = NULL;                  heap->reserve = NULL;
         }          }
         if (heap->overflow == 0) {          if (heap->overflow == 0) {
                char *error_filename;                const char *error_filename;
                 uint error_lineno;                  uint error_lineno;
                 TSRMLS_FETCH();                  TSRMLS_FETCH();
                 if (zend_is_compiling(TSRMLS_C)) {                  if (zend_is_compiling(TSRMLS_C)) {
Line 1910  static zend_mm_free_block *zend_mm_search_large_block( Line 1821  static zend_mm_free_block *zend_mm_search_large_block(
                 p = heap->large_free_buckets[index];                  p = heap->large_free_buckets[index];
                 for (m = true_size << (ZEND_MM_NUM_BUCKETS - index); ; m <<= 1) {                  for (m = true_size << (ZEND_MM_NUM_BUCKETS - index); ; m <<= 1) {
                         if (UNEXPECTED(ZEND_MM_FREE_BLOCK_SIZE(p) == true_size)) {                          if (UNEXPECTED(ZEND_MM_FREE_BLOCK_SIZE(p) == true_size)) {
                                return SUHOSIN_MANGLE_PTR(p->next_free_block);                                return p->next_free_block;
                         } else if (ZEND_MM_FREE_BLOCK_SIZE(p) >= true_size &&                          } else if (ZEND_MM_FREE_BLOCK_SIZE(p) >= true_size &&
                                    ZEND_MM_FREE_BLOCK_SIZE(p) < best_size) {                                     ZEND_MM_FREE_BLOCK_SIZE(p) < best_size) {
                                 best_size = ZEND_MM_FREE_BLOCK_SIZE(p);                                  best_size = ZEND_MM_FREE_BLOCK_SIZE(p);
Line 1934  static zend_mm_free_block *zend_mm_search_large_block( Line 1845  static zend_mm_free_block *zend_mm_search_large_block(
   
                 for (p = rst; p; p = p->child[p->child[0] != NULL]) {                  for (p = rst; p; p = p->child[p->child[0] != NULL]) {
                         if (UNEXPECTED(ZEND_MM_FREE_BLOCK_SIZE(p) == true_size)) {                          if (UNEXPECTED(ZEND_MM_FREE_BLOCK_SIZE(p) == true_size)) {
                                return SUHOSIN_MANGLE_PTR(p->next_free_block);                                return p->next_free_block;
                         } else if (ZEND_MM_FREE_BLOCK_SIZE(p) > true_size &&                          } else if (ZEND_MM_FREE_BLOCK_SIZE(p) > true_size &&
                                    ZEND_MM_FREE_BLOCK_SIZE(p) < best_size) {                                     ZEND_MM_FREE_BLOCK_SIZE(p) < best_size) {
                                 best_size = ZEND_MM_FREE_BLOCK_SIZE(p);                                  best_size = ZEND_MM_FREE_BLOCK_SIZE(p);
Line 1943  static zend_mm_free_block *zend_mm_search_large_block( Line 1854  static zend_mm_free_block *zend_mm_search_large_block(
                 }                  }
   
                 if (best_fit) {                  if (best_fit) {
                        return SUHOSIN_MANGLE_PTR(best_fit->next_free_block);                        return best_fit->next_free_block;
                 }                  }
                 bitmap = bitmap >> 1;                  bitmap = bitmap >> 1;
                 if (!bitmap) {                  if (!bitmap) {
Line 1959  static zend_mm_free_block *zend_mm_search_large_block( Line 1870  static zend_mm_free_block *zend_mm_search_large_block(
                         best_fit = p;                          best_fit = p;
                 }                  }
         }          }
        return SUHOSIN_MANGLE_PTR(best_fit->next_free_block);        return best_fit->next_free_block;
 }  }
   
 #if SUHOSIN_PATCH  
 void *_zend_mm_alloc_canary_int(zend_mm_heap_canary *heap, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);  
 #endif  
 static void *_zend_mm_alloc_int(zend_mm_heap *heap, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)  static void *_zend_mm_alloc_int(zend_mm_heap *heap, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
 {  {
         zend_mm_free_block *best_fit;          zend_mm_free_block *best_fit;
Line 1974  static void *_zend_mm_alloc_int(zend_mm_heap *heap, si Line 1882  static void *_zend_mm_alloc_int(zend_mm_heap *heap, si
         size_t segment_size;          size_t segment_size;
         zend_mm_segment *segment;          zend_mm_segment *segment;
         int keep_rest = 0;          int keep_rest = 0;
        #ifdef ZEND_SIGNALS
         TSRMLS_FETCH();
 #endif
 
         HANDLE_BLOCK_INTERRUPTIONS();
 
         if (EXPECTED(ZEND_MM_SMALL_SIZE(true_size))) {          if (EXPECTED(ZEND_MM_SMALL_SIZE(true_size))) {
                 size_t index = ZEND_MM_BUCKET_INDEX(true_size);                  size_t index = ZEND_MM_BUCKET_INDEX(true_size);
                 size_t bitmap;                  size_t bitmap;
Line 1989  static void *_zend_mm_alloc_int(zend_mm_heap *heap, si Line 1902  static void *_zend_mm_alloc_int(zend_mm_heap *heap, si
                         heap->cache_stat[index].count--;                          heap->cache_stat[index].count--;
                         heap->cache_stat[index].hit++;                          heap->cache_stat[index].hit++;
 #endif  #endif
                        best_fit = SUHOSIN_MANGLE_PTR(heap->cache[index]);                        best_fit = heap->cache[index];
                         heap->cache[index] = best_fit->prev_free_block;                          heap->cache[index] = best_fit->prev_free_block;
                         heap->cached -= true_size;                          heap->cached -= true_size;
 #if SUHOSIN_PATCH  
                         SUHOSIN_MM_SET_CANARIES(best_fit);  
                         ((zend_mm_block*)best_fit)->info.size = size;  
                         SUHOSIN_MM_SET_END_CANARY(best_fit);  
 #endif                    
                         ZEND_MM_CHECK_MAGIC(best_fit, MEM_BLOCK_CACHED);                          ZEND_MM_CHECK_MAGIC(best_fit, MEM_BLOCK_CACHED);
                         ZEND_MM_SET_DEBUG_INFO(best_fit, size, 1, 0);                          ZEND_MM_SET_DEBUG_INFO(best_fit, size, 1, 0);
                           HANDLE_UNBLOCK_INTERRUPTIONS();
                         return ZEND_MM_DATA_OF(best_fit);                          return ZEND_MM_DATA_OF(best_fit);
                 }                  }
 #if ZEND_MM_CACHE_STAT  #if ZEND_MM_CACHE_STAT
Line 2010  static void *_zend_mm_alloc_int(zend_mm_heap *heap, si Line 1919  static void *_zend_mm_alloc_int(zend_mm_heap *heap, si
                 if (bitmap) {                  if (bitmap) {
                         /* Found some "small" free block that can be used */                          /* Found some "small" free block that can be used */
                         index += zend_mm_low_bit(bitmap);                          index += zend_mm_low_bit(bitmap);
                        best_fit = SUHOSIN_MANGLE_PTR(heap->free_buckets[index*2]);                        best_fit = heap->free_buckets[index*2];
 #if ZEND_MM_CACHE_STAT  #if ZEND_MM_CACHE_STAT
                         heap->cache_stat[ZEND_MM_NUM_BUCKETS].hit++;                          heap->cache_stat[ZEND_MM_NUM_BUCKETS].hit++;
 #endif  #endif
Line 2025  static void *_zend_mm_alloc_int(zend_mm_heap *heap, si Line 1934  static void *_zend_mm_alloc_int(zend_mm_heap *heap, si
         best_fit = zend_mm_search_large_block(heap, true_size);          best_fit = zend_mm_search_large_block(heap, true_size);
   
         if (!best_fit && heap->real_size >= heap->limit - heap->block_size) {          if (!best_fit && heap->real_size >= heap->limit - heap->block_size) {
                zend_mm_free_block *p = SUHOSIN_MANGLE_PTR(heap->rest_buckets[0]);                zend_mm_free_block *p = heap->rest_buckets[0];
                 size_t best_size = -1;                  size_t best_size = -1;
   
                 while (p != ZEND_MM_REST_BUCKET(heap)) {                  while (p != ZEND_MM_REST_BUCKET(heap)) {
Line 2037  static void *_zend_mm_alloc_int(zend_mm_heap *heap, si Line 1946  static void *_zend_mm_alloc_int(zend_mm_heap *heap, si
                                 best_size = ZEND_MM_FREE_BLOCK_SIZE(p);                                  best_size = ZEND_MM_FREE_BLOCK_SIZE(p);
                                 best_fit = p;                                  best_fit = p;
                         }                          }
                        p = SUHOSIN_MANGLE_PTR(p->prev_free_block);                        p = p->prev_free_block;
                 }                  }
         }          }
   
Line 2052  static void *_zend_mm_alloc_int(zend_mm_heap *heap, si Line 1961  static void *_zend_mm_alloc_int(zend_mm_heap *heap, si
                         segment_size = heap->block_size;                          segment_size = heap->block_size;
                 }                  }
   
                 HANDLE_BLOCK_INTERRUPTIONS();  
   
                 if (segment_size < true_size ||                  if (segment_size < true_size ||
                     heap->real_size + segment_size > heap->limit) {                      heap->real_size + segment_size > heap->limit) {
                         /* Memory limit overflow */                          /* Memory limit overflow */
Line 2075  static void *_zend_mm_alloc_int(zend_mm_heap *heap, si Line 1982  static void *_zend_mm_alloc_int(zend_mm_heap *heap, si
 #if ZEND_MM_CACHE  #if ZEND_MM_CACHE
                         zend_mm_free_cache(heap);                          zend_mm_free_cache(heap);
 #endif  #endif
                         HANDLE_UNBLOCK_INTERRUPTIONS();  
 out_of_memory:  out_of_memory:
                           HANDLE_UNBLOCK_INTERRUPTIONS();
 #if ZEND_DEBUG  #if ZEND_DEBUG
                         zend_mm_safe_error(heap, "Out of memory (allocated %ld) at %s:%d (tried to allocate %lu bytes)", heap->real_size, __zend_filename, __zend_lineno, size);                          zend_mm_safe_error(heap, "Out of memory (allocated %ld) at %s:%d (tried to allocate %lu bytes)", heap->real_size, __zend_filename, __zend_lineno, size);
 #else  #else
Line 2104  out_of_memory: Line 2011  out_of_memory:
         } else {          } else {
 zend_mm_finished_searching_for_block:  zend_mm_finished_searching_for_block:
                 /* remove from free list */                  /* remove from free list */
                 HANDLE_BLOCK_INTERRUPTIONS();  
                 ZEND_MM_CHECK_MAGIC(best_fit, MEM_BLOCK_FREED);                  ZEND_MM_CHECK_MAGIC(best_fit, MEM_BLOCK_FREED);
                 ZEND_MM_CHECK_COOKIE(best_fit);                  ZEND_MM_CHECK_COOKIE(best_fit);
                 ZEND_MM_CHECK_BLOCK_LINKAGE(best_fit);                  ZEND_MM_CHECK_BLOCK_LINKAGE(best_fit);
Line 2136  zend_mm_finished_searching_for_block: Line 2042  zend_mm_finished_searching_for_block:
   
         ZEND_MM_SET_DEBUG_INFO(best_fit, size, 1, 1);          ZEND_MM_SET_DEBUG_INFO(best_fit, size, 1, 1);
   
 #if SUHOSIN_PATCH  
         SUHOSIN_MM_SET_CANARIES(best_fit);  
         ((zend_mm_block*)best_fit)->info.size = size;  
         SUHOSIN_MM_SET_END_CANARY(best_fit);  
 #endif  
           
         heap->size += true_size;          heap->size += true_size;
         if (heap->peak < heap->size) {          if (heap->peak < heap->size) {
                 heap->peak = heap->size;                  heap->peak = heap->size;
         }          }
   
         HANDLE_UNBLOCK_INTERRUPTIONS();          HANDLE_UNBLOCK_INTERRUPTIONS();
        
         return ZEND_MM_DATA_OF(best_fit);          return ZEND_MM_DATA_OF(best_fit);
 }  }
   
Line 2158  static void _zend_mm_free_int(zend_mm_heap *heap, void Line 2058  static void _zend_mm_free_int(zend_mm_heap *heap, void
         zend_mm_block *mm_block;          zend_mm_block *mm_block;
         zend_mm_block *next_block;          zend_mm_block *next_block;
         size_t size;          size_t size;
#ifdef ZEND_SIGNALS
         TSRMLS_FETCH();
 #endif
         if (!ZEND_MM_VALID_PTR(p)) {          if (!ZEND_MM_VALID_PTR(p)) {
                 return;                  return;
         }          }
   
           HANDLE_BLOCK_INTERRUPTIONS();
   
         mm_block = ZEND_MM_HEADER_OF(p);          mm_block = ZEND_MM_HEADER_OF(p);
         size = ZEND_MM_BLOCK_SIZE(mm_block);          size = ZEND_MM_BLOCK_SIZE(mm_block);
 #if SUHOSIN_PATCH  
         SUHOSIN_MM_CHECK_CANARIES(mm_block, "efree()");  
 #endif      
         ZEND_MM_CHECK_PROTECTION(mm_block);          ZEND_MM_CHECK_PROTECTION(mm_block);
   
 #if ZEND_DEBUG || ZEND_MM_HEAP_PROTECTION  #if ZEND_DEBUG || ZEND_MM_HEAP_PROTECTION
         memset(ZEND_MM_DATA_OF(mm_block), 0x5a, mm_block->debug.size);          memset(ZEND_MM_DATA_OF(mm_block), 0x5a, mm_block->debug.size);
 #endif  #endif
#if SUHOSIN_PATCH
        if (UNEXPECTED(SUHOSIN_CONFIG(SUHOSIN_MM_DESTROY_FREE_MEMORY))) { 
                memset(ZEND_MM_DATA_OF(mm_block), 0x5a, mm_block->info.size); 
        } 
#endif 
 #if ZEND_MM_CACHE  #if ZEND_MM_CACHE
         if (EXPECTED(ZEND_MM_SMALL_SIZE(size)) && EXPECTED(heap->cached < ZEND_MM_CACHE_SIZE)) {          if (EXPECTED(ZEND_MM_SMALL_SIZE(size)) && EXPECTED(heap->cached < ZEND_MM_CACHE_SIZE)) {
                 size_t index = ZEND_MM_BUCKET_INDEX(size);                  size_t index = ZEND_MM_BUCKET_INDEX(size);
                 zend_mm_free_block **cache = &heap->cache[index];                  zend_mm_free_block **cache = &heap->cache[index];
   
                 ((zend_mm_free_block*)mm_block)->prev_free_block = *cache;                  ((zend_mm_free_block*)mm_block)->prev_free_block = *cache;
                *cache = (zend_mm_free_block*)SUHOSIN_MANGLE_PTR(mm_block);                *cache = (zend_mm_free_block*)mm_block;
                 heap->cached += size;                  heap->cached += size;
                 ZEND_MM_SET_MAGIC(mm_block, MEM_BLOCK_CACHED);                  ZEND_MM_SET_MAGIC(mm_block, MEM_BLOCK_CACHED);
 #if ZEND_MM_CACHE_STAT  #if ZEND_MM_CACHE_STAT
Line 2192  static void _zend_mm_free_int(zend_mm_heap *heap, void Line 2089  static void _zend_mm_free_int(zend_mm_heap *heap, void
                         heap->cache_stat[index].max_count = heap->cache_stat[index].count;                          heap->cache_stat[index].max_count = heap->cache_stat[index].count;
                 }                  }
 #endif  #endif
                   HANDLE_UNBLOCK_INTERRUPTIONS();
                 return;                  return;
         }          }
 #endif  #endif
   
         HANDLE_BLOCK_INTERRUPTIONS();  
   
         heap->size -= size;          heap->size -= size;
   
         next_block = ZEND_MM_BLOCK_AT(mm_block, size);          next_block = ZEND_MM_BLOCK_AT(mm_block, size);
Line 2220  static void _zend_mm_free_int(zend_mm_heap *heap, void Line 2116  static void _zend_mm_free_int(zend_mm_heap *heap, void
         HANDLE_UNBLOCK_INTERRUPTIONS();          HANDLE_UNBLOCK_INTERRUPTIONS();
 }  }
   
 #if SUHOSIN_PATCH  
 void *_zend_mm_realloc_canary_int(zend_mm_heap_canary *heap, void *p, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);  
 #endif  
 static void *_zend_mm_realloc_int(zend_mm_heap *heap, void *p, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)  static void *_zend_mm_realloc_int(zend_mm_heap *heap, void *p, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
 {  {
         zend_mm_block *mm_block = ZEND_MM_HEADER_OF(p);          zend_mm_block *mm_block = ZEND_MM_HEADER_OF(p);
Line 2230  static void *_zend_mm_realloc_int(zend_mm_heap *heap,  Line 2123  static void *_zend_mm_realloc_int(zend_mm_heap *heap, 
         size_t true_size;          size_t true_size;
         size_t orig_size;          size_t orig_size;
         void *ptr;          void *ptr;
#ifdef ZEND_SIGNALS
         TSRMLS_FETCH();
 #endif
         if (UNEXPECTED(!p) || !ZEND_MM_VALID_PTR(p)) {          if (UNEXPECTED(!p) || !ZEND_MM_VALID_PTR(p)) {
 #ifdef SUHOSIN_MM_WITH_CANARY_PROTECTION  
                 return _zend_mm_alloc_canary_int(heap, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);  
 #else  
                 return _zend_mm_alloc_int(heap, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);                  return _zend_mm_alloc_int(heap, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
 #endif  
         }          }
   
           HANDLE_BLOCK_INTERRUPTIONS();
   
         mm_block = ZEND_MM_HEADER_OF(p);          mm_block = ZEND_MM_HEADER_OF(p);
         true_size = ZEND_MM_TRUE_SIZE(size);          true_size = ZEND_MM_TRUE_SIZE(size);
         orig_size = ZEND_MM_BLOCK_SIZE(mm_block);          orig_size = ZEND_MM_BLOCK_SIZE(mm_block);
 #if SUHOSIN_PATCH  
         SUHOSIN_MM_CHECK_CANARIES(mm_block, "erealloc()");  
 #endif    
         ZEND_MM_CHECK_PROTECTION(mm_block);          ZEND_MM_CHECK_PROTECTION(mm_block);
   
         if (UNEXPECTED(true_size < size)) {          if (UNEXPECTED(true_size < size)) {
Line 2256  static void *_zend_mm_realloc_int(zend_mm_heap *heap,  Line 2147  static void *_zend_mm_realloc_int(zend_mm_heap *heap, 
                 if (remaining_size >= ZEND_MM_ALIGNED_MIN_HEADER_SIZE) {                  if (remaining_size >= ZEND_MM_ALIGNED_MIN_HEADER_SIZE) {
                         zend_mm_free_block *new_free_block;                          zend_mm_free_block *new_free_block;
   
                         HANDLE_BLOCK_INTERRUPTIONS();  
                         next_block = ZEND_MM_BLOCK_AT(mm_block, orig_size);                          next_block = ZEND_MM_BLOCK_AT(mm_block, orig_size);
                         if (ZEND_MM_IS_FREE_BLOCK(next_block)) {                          if (ZEND_MM_IS_FREE_BLOCK(next_block)) {
                                 remaining_size += ZEND_MM_FREE_BLOCK_SIZE(next_block);                                  remaining_size += ZEND_MM_FREE_BLOCK_SIZE(next_block);
Line 2272  static void *_zend_mm_realloc_int(zend_mm_heap *heap,  Line 2162  static void *_zend_mm_realloc_int(zend_mm_heap *heap, 
                         /* add the new free block to the free list */                          /* add the new free block to the free list */
                         zend_mm_add_to_free_list(heap, new_free_block);                          zend_mm_add_to_free_list(heap, new_free_block);
                         heap->size += (true_size - orig_size);                          heap->size += (true_size - orig_size);
                         HANDLE_UNBLOCK_INTERRUPTIONS();  
                 }                  }
                 ZEND_MM_SET_DEBUG_INFO(mm_block, size, 0, 0);                  ZEND_MM_SET_DEBUG_INFO(mm_block, size, 0, 0);
#if SUHOSIN_PATCH                HANDLE_UNBLOCK_INTERRUPTIONS();
                SUHOSIN_MM_SET_CANARIES(mm_block); 
                ((zend_mm_block*)mm_block)->info.size = size; 
                SUHOSIN_MM_SET_END_CANARY(mm_block); 
#endif 
                 return p;                  return p;
         }          }
   
Line 2295  static void *_zend_mm_realloc_int(zend_mm_heap *heap,  Line 2180  static void *_zend_mm_realloc_int(zend_mm_heap *heap, 
                         heap->cache_stat[index].count--;                          heap->cache_stat[index].count--;
                         heap->cache_stat[index].hit++;                          heap->cache_stat[index].hit++;
 #endif  #endif
                        best_fit = SUHOSIN_MANGLE_PTR(heap->cache[index]);                        best_fit = heap->cache[index];
                         heap->cache[index] = best_fit->prev_free_block;                          heap->cache[index] = best_fit->prev_free_block;
                         ZEND_MM_CHECK_MAGIC(best_fit, MEM_BLOCK_CACHED);                          ZEND_MM_CHECK_MAGIC(best_fit, MEM_BLOCK_CACHED);
                        ZEND_MM_SET_DEBUG_INFO(best_fit, size, 1, 0);                                                   ZEND_MM_SET_DEBUG_INFO(best_fit, size, 1, 0);
#if SUHOSIN_PATCH        
                        SUHOSIN_MM_SET_CANARIES(best_fit); 
                        ((zend_mm_block*)best_fit)->info.size = size; 
                        SUHOSIN_MM_SET_END_CANARY(best_fit); 
#endif 
 
                         ptr = ZEND_MM_DATA_OF(best_fit);                          ptr = ZEND_MM_DATA_OF(best_fit);
   
 #if ZEND_DEBUG || ZEND_MM_HEAP_PROTECTION  #if ZEND_DEBUG || ZEND_MM_HEAP_PROTECTION
                         memcpy(ptr, p, mm_block->debug.size);                          memcpy(ptr, p, mm_block->debug.size);
 #else  #else
                        memcpy(ptr, p, orig_size - ZEND_MM_ALIGNED_HEADER_SIZE - CANARY_SIZE);                        memcpy(ptr, p, orig_size - ZEND_MM_ALIGNED_HEADER_SIZE);
 #endif  #endif
   
                         heap->cached -= true_size - orig_size;                          heap->cached -= true_size - orig_size;
Line 2319  static void *_zend_mm_realloc_int(zend_mm_heap *heap,  Line 2199  static void *_zend_mm_realloc_int(zend_mm_heap *heap, 
                         cache = &heap->cache[index];                          cache = &heap->cache[index];
   
                         ((zend_mm_free_block*)mm_block)->prev_free_block = *cache;                          ((zend_mm_free_block*)mm_block)->prev_free_block = *cache;
                        *cache = (zend_mm_free_block*)SUHOSIN_MANGLE_PTR(mm_block);                        *cache = (zend_mm_free_block*)mm_block;
                         ZEND_MM_SET_MAGIC(mm_block, MEM_BLOCK_CACHED);                          ZEND_MM_SET_MAGIC(mm_block, MEM_BLOCK_CACHED);
 #if ZEND_MM_CACHE_STAT  #if ZEND_MM_CACHE_STAT
                         if (++heap->cache_stat[index].count > heap->cache_stat[index].max_count) {                          if (++heap->cache_stat[index].count > heap->cache_stat[index].max_count) {
                                 heap->cache_stat[index].max_count = heap->cache_stat[index].count;                                  heap->cache_stat[index].max_count = heap->cache_stat[index].count;
                         }                          }
 #endif  #endif
   
                           HANDLE_UNBLOCK_INTERRUPTIONS();
                         return ptr;                          return ptr;
                 }                  }
         }          }
Line 2340  static void *_zend_mm_realloc_int(zend_mm_heap *heap,  Line 2222  static void *_zend_mm_realloc_int(zend_mm_heap *heap, 
                         size_t block_size = orig_size + ZEND_MM_FREE_BLOCK_SIZE(next_block);                          size_t block_size = orig_size + ZEND_MM_FREE_BLOCK_SIZE(next_block);
                         size_t remaining_size = block_size - true_size;                          size_t remaining_size = block_size - true_size;
   
                         HANDLE_BLOCK_INTERRUPTIONS();  
                         zend_mm_remove_from_free_list(heap, (zend_mm_free_block *) next_block);                          zend_mm_remove_from_free_list(heap, (zend_mm_free_block *) next_block);
   
                         if (remaining_size < ZEND_MM_ALIGNED_MIN_HEADER_SIZE) {                          if (remaining_size < ZEND_MM_ALIGNED_MIN_HEADER_SIZE) {
Line 2368  static void *_zend_mm_realloc_int(zend_mm_heap *heap,  Line 2249  static void *_zend_mm_realloc_int(zend_mm_heap *heap, 
                                 heap->peak = heap->size;                                  heap->peak = heap->size;
                         }                          }
                         HANDLE_UNBLOCK_INTERRUPTIONS();                          HANDLE_UNBLOCK_INTERRUPTIONS();
 #if SUHOSIN_PATCH  
                         SUHOSIN_MM_SET_CANARIES(mm_block);  
                         ((zend_mm_block*)mm_block)->info.size = size;  
                         SUHOSIN_MM_SET_END_CANARY(mm_block);  
 #endif  
                         return p;                          return p;
                 } else if (ZEND_MM_IS_FIRST_BLOCK(mm_block) &&                  } else if (ZEND_MM_IS_FIRST_BLOCK(mm_block) &&
                                    ZEND_MM_IS_GUARD_BLOCK(ZEND_MM_BLOCK_AT(next_block, ZEND_MM_FREE_BLOCK_SIZE(next_block)))) {                                     ZEND_MM_IS_GUARD_BLOCK(ZEND_MM_BLOCK_AT(next_block, ZEND_MM_FREE_BLOCK_SIZE(next_block)))) {
                         HANDLE_BLOCK_INTERRUPTIONS();  
                         zend_mm_remove_from_free_list(heap, (zend_mm_free_block *) next_block);                          zend_mm_remove_from_free_list(heap, (zend_mm_free_block *) next_block);
                         goto realloc_segment;                          goto realloc_segment;
                 }                  }
Line 2387  static void *_zend_mm_realloc_int(zend_mm_heap *heap,  Line 2262  static void *_zend_mm_realloc_int(zend_mm_heap *heap, 
                 size_t block_size;                  size_t block_size;
                 size_t remaining_size;                  size_t remaining_size;
   
                 HANDLE_BLOCK_INTERRUPTIONS();  
 realloc_segment:  realloc_segment:
                 /* segment size, size of block and size of guard block */                  /* segment size, size of block and size of guard block */
                 if (true_size > heap->block_size - (ZEND_MM_ALIGNED_SEGMENT_SIZE + ZEND_MM_ALIGNED_HEADER_SIZE)) {                  if (true_size > heap->block_size - (ZEND_MM_ALIGNED_SEGMENT_SIZE + ZEND_MM_ALIGNED_HEADER_SIZE)) {
Line 2420  realloc_segment: Line 2294  realloc_segment:
 #if ZEND_MM_CACHE  #if ZEND_MM_CACHE
                         zend_mm_free_cache(heap);                          zend_mm_free_cache(heap);
 #endif  #endif
                         HANDLE_UNBLOCK_INTERRUPTIONS();  
 out_of_memory:  out_of_memory:
                           HANDLE_UNBLOCK_INTERRUPTIONS();
 #if ZEND_DEBUG  #if ZEND_DEBUG
                         zend_mm_safe_error(heap, "Out of memory (allocated %ld) at %s:%d (tried to allocate %ld bytes)", heap->real_size, __zend_filename, __zend_lineno, size);                          zend_mm_safe_error(heap, "Out of memory (allocated %ld) at %s:%d (tried to allocate %ld bytes)", heap->real_size, __zend_filename, __zend_lineno, size);
 #else  #else
Line 2475  out_of_memory: Line 2349  out_of_memory:
                 }                  }
   
                 HANDLE_UNBLOCK_INTERRUPTIONS();                  HANDLE_UNBLOCK_INTERRUPTIONS();
 #if SUHOSIN_PATCH  
                 SUHOSIN_MM_SET_CANARIES(mm_block);  
                 ((zend_mm_block*)mm_block)->info.size = size;  
                 SUHOSIN_MM_SET_END_CANARY(mm_block);  
 #endif  
                 return ZEND_MM_DATA_OF(mm_block);                  return ZEND_MM_DATA_OF(mm_block);
         }          }
   
 #ifdef SUHOSIN_MM_WITH_CANARY_PROTECTION  
         ptr = _zend_mm_alloc_canary_int(heap, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);  
 #else  
         ptr = _zend_mm_alloc_int(heap, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);          ptr = _zend_mm_alloc_int(heap, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
 #endif  
 #if ZEND_DEBUG || ZEND_MM_HEAP_PROTECTION  #if ZEND_DEBUG || ZEND_MM_HEAP_PROTECTION
         memcpy(ptr, p, mm_block->debug.size);          memcpy(ptr, p, mm_block->debug.size);
 #else  #else
        memcpy(ptr, p, orig_size - ZEND_MM_ALIGNED_HEADER_SIZE - CANARY_SIZE);        memcpy(ptr, p, orig_size - ZEND_MM_ALIGNED_HEADER_SIZE);
 #endif  #endif
 #ifdef SUHOSIN_MM_WITH_CANARY_PROTECTION  
         _zend_mm_free_canary_int(heap, p ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);  
 #else  
         _zend_mm_free_int(heap, p ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);          _zend_mm_free_int(heap, p ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
#endif        HANDLE_UNBLOCK_INTERRUPTIONS();
         return ptr;          return ptr;
 }  }
   
 #ifndef SUHOSIN_MM_CLONE_FILE  
 ZEND_API void *_zend_mm_alloc(zend_mm_heap *heap, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)  ZEND_API void *_zend_mm_alloc(zend_mm_heap *heap, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
 {  {
#if SUHOSIN_PATCH               return _zend_mm_alloc_int(heap, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
        if (UNEXPECTED(SUHOSIN_CONFIG(SUHOSIN_MM_USE_CANARY_PROTECTION) == 0)) 
#endif 
                return _zend_mm_alloc_int(heap, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); 
#if SUHOSIN_PATCH 
        return _zend_mm_alloc_canary_int((zend_mm_heap_canary *)heap, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); 
#endif 
 }  }
   
 ZEND_API void _zend_mm_free(zend_mm_heap *heap, void *p ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)  ZEND_API void _zend_mm_free(zend_mm_heap *heap, void *p ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
 {  {
#if SUHOSIN_PATCH               _zend_mm_free_int(heap, p ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
        if (UNEXPECTED(SUHOSIN_CONFIG(SUHOSIN_MM_USE_CANARY_PROTECTION) == 0)) 
#endif 
                { _zend_mm_free_int(heap, p ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); return; } 
#if SUHOSIN_PATCH 
        _zend_mm_free_canary_int((zend_mm_heap_canary *)heap, p ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); 
#endif 
 }  }
   
 ZEND_API void *_zend_mm_realloc(zend_mm_heap *heap, void *ptr, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)  ZEND_API void *_zend_mm_realloc(zend_mm_heap *heap, void *ptr, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
 {  {
#if SUHOSIN_PATCH               return _zend_mm_realloc_int(heap, ptr, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
        if (UNEXPECTED(SUHOSIN_CONFIG(SUHOSIN_MM_USE_CANARY_PROTECTION) == 0)) 
#endif 
                return _zend_mm_realloc_int(heap, ptr, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); 
#if SUHOSIN_PATCH        
        return _zend_mm_realloc_canary_int((zend_mm_heap_canary *)heap, ptr, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); 
#endif 
 }  }
   
 ZEND_API size_t _zend_mm_block_size(zend_mm_heap *heap, void *p ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)  ZEND_API size_t _zend_mm_block_size(zend_mm_heap *heap, void *p ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
 {  {
         zend_mm_block *mm_block;          zend_mm_block *mm_block;
   
         if (SUHOSIN_CONFIG(SUHOSIN_MM_USE_CANARY_PROTECTION) != 0) {  
                 return _zend_mm_block_size_canary((zend_mm_heap_canary *)heap, p ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);  
         }  
   
         if (!ZEND_MM_VALID_PTR(p)) {          if (!ZEND_MM_VALID_PTR(p)) {
                 return 0;                  return 0;
         }          }
Line 2554  ZEND_API size_t _zend_mm_block_size(zend_mm_heap *heap Line 2393  ZEND_API size_t _zend_mm_block_size(zend_mm_heap *heap
         return ZEND_MM_BLOCK_SIZE(mm_block);          return ZEND_MM_BLOCK_SIZE(mm_block);
 #endif  #endif
 }  }
 #else  
 ZEND_API size_t _zend_mm_block_size_canary(zend_mm_heap *heap, void *p ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)  
 {  
         zend_mm_block *mm_block;  
   
         if (!ZEND_MM_VALID_PTR(p)) {  
                 return 0;  
         }  
         mm_block = ZEND_MM_HEADER_OF(p);  
         ZEND_MM_CHECK_PROTECTION(mm_block);  
 #if ZEND_DEBUG || ZEND_MM_HEAP_PROTECTION  
         return mm_block->debug.size;  
 #else  
         return ZEND_MM_BLOCK_SIZE(mm_block);  
 #endif  
 }  
   
 #endif  
   
 /**********************/  /**********************/
 /* Allocation Manager */  /* Allocation Manager */
 /**********************/  /**********************/
Line 2589  static int alloc_globals_id; Line 2410  static int alloc_globals_id;
 static zend_alloc_globals alloc_globals;  static zend_alloc_globals alloc_globals;
 #endif  #endif
   
 #ifndef SUHOSIN_MM_CLONE_FILE  
 ZEND_API int is_zend_mm(TSRMLS_D)  ZEND_API int is_zend_mm(TSRMLS_D)
 {  {
         return AG(mm_heap)->use_zend_alloc;          return AG(mm_heap)->use_zend_alloc;
Line 2602  ZEND_API void *_emalloc(size_t size ZEND_FILE_LINE_DC  Line 2422  ZEND_API void *_emalloc(size_t size ZEND_FILE_LINE_DC 
         if (UNEXPECTED(!AG(mm_heap)->use_zend_alloc)) {          if (UNEXPECTED(!AG(mm_heap)->use_zend_alloc)) {
                 return AG(mm_heap)->_malloc(size);                  return AG(mm_heap)->_malloc(size);
         }          }
 #if SUHOSIN_PATCH         
         if (UNEXPECTED(SUHOSIN_CONFIG(SUHOSIN_MM_USE_CANARY_PROTECTION) == 0))  
 #endif  
         return _zend_mm_alloc_int(AG(mm_heap), size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);          return _zend_mm_alloc_int(AG(mm_heap), size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
 #if SUHOSIN_PATCH         
         return _zend_mm_alloc_canary_int((zend_mm_heap_canary *)AG(mm_heap), size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);  
 #endif  
 }  }
   
 ZEND_API void _efree(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)  ZEND_API void _efree(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
Line 2619  ZEND_API void _efree(void *ptr ZEND_FILE_LINE_DC ZEND_ Line 2433  ZEND_API void _efree(void *ptr ZEND_FILE_LINE_DC ZEND_
                 AG(mm_heap)->_free(ptr);                  AG(mm_heap)->_free(ptr);
                 return;                  return;
         }          }
#if SUHOSIN_PATCH               _zend_mm_free_int(AG(mm_heap), ptr ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
        if (UNEXPECTED(SUHOSIN_CONFIG(SUHOSIN_MM_USE_CANARY_PROTECTION) == 0)) 
#endif 
                { _zend_mm_free_int(AG(mm_heap), ptr ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); return; } 
#if SUHOSIN_PATCH        
        _zend_mm_free_canary_int((zend_mm_heap_canary *)AG(mm_heap), ptr ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); 
#endif 
 }  }
   
 ZEND_API void *_erealloc(void *ptr, size_t size, int allow_failure ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)  ZEND_API void *_erealloc(void *ptr, size_t size, int allow_failure ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
Line 2635  ZEND_API void *_erealloc(void *ptr, size_t size, int a Line 2443  ZEND_API void *_erealloc(void *ptr, size_t size, int a
         if (UNEXPECTED(!AG(mm_heap)->use_zend_alloc)) {          if (UNEXPECTED(!AG(mm_heap)->use_zend_alloc)) {
                 return AG(mm_heap)->_realloc(ptr, size);                  return AG(mm_heap)->_realloc(ptr, size);
         }          }
 #if SUHOSIN_PATCH         
         if (UNEXPECTED(SUHOSIN_CONFIG(SUHOSIN_MM_USE_CANARY_PROTECTION) == 0))  
 #endif  
         return _zend_mm_realloc_int(AG(mm_heap), ptr, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);          return _zend_mm_realloc_int(AG(mm_heap), ptr, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
 #if SUHOSIN_PATCH         
         return _zend_mm_realloc_canary_int((zend_mm_heap_canary *)AG(mm_heap), ptr, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);  
 #endif  
 }  }
   
 ZEND_API size_t _zend_mem_block_size(void *ptr TSRMLS_DC ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)  ZEND_API size_t _zend_mem_block_size(void *ptr TSRMLS_DC ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
Line 2649  ZEND_API size_t _zend_mem_block_size(void *ptr TSRMLS_ Line 2451  ZEND_API size_t _zend_mem_block_size(void *ptr TSRMLS_
         if (UNEXPECTED(!AG(mm_heap)->use_zend_alloc)) {          if (UNEXPECTED(!AG(mm_heap)->use_zend_alloc)) {
                 return 0;                  return 0;
         }          }
#if SUHOSIN_PATCH               return _zend_mm_block_size(AG(mm_heap), ptr ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
        if (UNEXPECTED(SUHOSIN_CONFIG(SUHOSIN_MM_USE_CANARY_PROTECTION) == 0)) 
#endif 
                return _zend_mm_block_size(AG(mm_heap), ptr ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); 
#if SUHOSIN_PATCH        
        return _zend_mm_block_size_canary((zend_mm_heap_canary *)AG(mm_heap), ptr ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); 
#endif 
 }  }
 #endif  
   
 #if defined(__GNUC__) && defined(i386)  #if defined(__GNUC__) && defined(i386)
   
Line 2728  static inline size_t safe_address(size_t nmemb, size_t Line 2523  static inline size_t safe_address(size_t nmemb, size_t
 }  }
 #endif  #endif
   
#ifndef SUHOSIN_MM_CLONE_FILE
 ZEND_API void *_safe_emalloc(size_t nmemb, size_t size, size_t offset ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)  ZEND_API void *_safe_emalloc(size_t nmemb, size_t size, size_t offset ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
 {  {
         return emalloc_rel(safe_address(nmemb, size, offset));          return emalloc_rel(safe_address(nmemb, size, offset));
Line 2753  ZEND_API void *_safe_realloc(void *ptr, size_t nmemb,  Line 2548  ZEND_API void *_safe_realloc(void *ptr, size_t nmemb, 
 ZEND_API void *_ecalloc(size_t nmemb, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)  ZEND_API void *_ecalloc(size_t nmemb, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
 {  {
         void *p;          void *p;
   #ifdef ZEND_SIGNALS
           TSRMLS_FETCH();
   #endif
           HANDLE_BLOCK_INTERRUPTIONS();
   
         p = _safe_emalloc(nmemb, size, 0 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);          p = _safe_emalloc(nmemb, size, 0 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
         if (UNEXPECTED(p == NULL)) {          if (UNEXPECTED(p == NULL)) {
                   HANDLE_UNBLOCK_INTERRUPTIONS();
                 return p;                  return p;
         }          }
         memset(p, 0, size * nmemb);          memset(p, 0, size * nmemb);
           HANDLE_UNBLOCK_INTERRUPTIONS();
         return p;          return p;
 }  }
   
Line 2766  ZEND_API char *_estrdup(const char *s ZEND_FILE_LINE_D Line 2567  ZEND_API char *_estrdup(const char *s ZEND_FILE_LINE_D
 {  {
         int length;          int length;
         char *p;          char *p;
   #ifdef ZEND_SIGNALS
           TSRMLS_FETCH();
   #endif
   
           HANDLE_BLOCK_INTERRUPTIONS();
   
         length = strlen(s)+1;          length = strlen(s)+1;
         p = (char *) _emalloc(length ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);          p = (char *) _emalloc(length ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
         if (UNEXPECTED(p == NULL)) {          if (UNEXPECTED(p == NULL)) {
                   HANDLE_UNBLOCK_INTERRUPTIONS();
                 return p;                  return p;
         }          }
         memcpy(p, s, length);          memcpy(p, s, length);
           HANDLE_UNBLOCK_INTERRUPTIONS();
         return p;          return p;
 }  }
   
 ZEND_API char *_estrndup(const char *s, uint length ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)  ZEND_API char *_estrndup(const char *s, uint length ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
 {  {
         char *p;          char *p;
   #ifdef ZEND_SIGNALS
           TSRMLS_FETCH();
   #endif
   
           HANDLE_BLOCK_INTERRUPTIONS();
   
         p = (char *) _emalloc(length+1 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);          p = (char *) _emalloc(length+1 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
         if (UNEXPECTED(p == NULL)) {          if (UNEXPECTED(p == NULL)) {
                   HANDLE_UNBLOCK_INTERRUPTIONS();
                 return p;                  return p;
         }          }
         memcpy(p, s, length);          memcpy(p, s, length);
         p[length] = 0;          p[length] = 0;
           HANDLE_UNBLOCK_INTERRUPTIONS();
         return p;          return p;
 }  }
   
Line 2793  ZEND_API char *_estrndup(const char *s, uint length ZE Line 2608  ZEND_API char *_estrndup(const char *s, uint length ZE
 ZEND_API char *zend_strndup(const char *s, uint length)  ZEND_API char *zend_strndup(const char *s, uint length)
 {  {
         char *p;          char *p;
   #ifdef ZEND_SIGNALS
           TSRMLS_FETCH();
   #endif
   
           HANDLE_BLOCK_INTERRUPTIONS();
   
         p = (char *) malloc(length+1);          p = (char *) malloc(length+1);
         if (UNEXPECTED(p == NULL)) {          if (UNEXPECTED(p == NULL)) {
                   HANDLE_UNBLOCK_INTERRUPTIONS();
                 return p;                  return p;
         }          }
         if (length) {          if (length) {
                 memcpy(p, s, length);                  memcpy(p, s, length);
         }          }
         p[length] = 0;          p[length] = 0;
           HANDLE_UNBLOCK_INTERRUPTIONS();
         return p;          return p;
 }  }
   
Line 2841  ZEND_API void shutdown_memory_manager(int silent, int  Line 2663  ZEND_API void shutdown_memory_manager(int silent, int 
 {  {
         zend_mm_shutdown(AG(mm_heap), full_shutdown, silent TSRMLS_CC);          zend_mm_shutdown(AG(mm_heap), full_shutdown, silent TSRMLS_CC);
 }  }
 #endif  
   
 static void alloc_globals_ctor(zend_alloc_globals *alloc_globals TSRMLS_DC)  static void alloc_globals_ctor(zend_alloc_globals *alloc_globals TSRMLS_DC)
 {  {
        char *tmp;        char *tmp = getenv("USE_ZEND_ALLOC");
        alloc_globals->mm_heap = zend_mm_startup(); 
   
        tmp = getenv("USE_ZEND_ALLOC");        if (tmp && !zend_atoi(tmp, 0)) {
        if (tmp) {                alloc_globals->mm_heap = malloc(sizeof(struct _zend_mm_heap));
                alloc_globals->mm_heap->use_zend_alloc = zend_atoi(tmp, 0);                memset(alloc_globals->mm_heap, 0, sizeof(struct _zend_mm_heap));
                if (!alloc_globals->mm_heap->use_zend_alloc) {                alloc_globals->mm_heap->use_zend_alloc = 0;
                        alloc_globals->mm_heap->_malloc = malloc;                alloc_globals->mm_heap->_malloc = malloc;
                        alloc_globals->mm_heap->_free = free;                alloc_globals->mm_heap->_free = free;
                        alloc_globals->mm_heap->_realloc = realloc;                alloc_globals->mm_heap->_realloc = realloc;
                }        } else {
                 alloc_globals->mm_heap = zend_mm_startup();
         }          }
 }  }
   
Line 2866  static void alloc_globals_dtor(zend_alloc_globals *all Line 2687  static void alloc_globals_dtor(zend_alloc_globals *all
 }  }
 #endif  #endif
   
 #ifndef SUHOSIN_MM_CLONE_FILE  
 ZEND_API void start_memory_manager(TSRMLS_D)  ZEND_API void start_memory_manager(TSRMLS_D)
 {  {
 #ifdef ZTS  #ifdef ZTS
Line 2930  ZEND_API void _full_mem_check(int silent ZEND_FILE_LIN Line 2750  ZEND_API void _full_mem_check(int silent ZEND_FILE_LIN
         zend_debug_alloc_output("End of full memory check %s:%d (%d errors)\n" ZEND_FILE_LINE_RELAY_CC, errors);          zend_debug_alloc_output("End of full memory check %s:%d (%d errors)\n" ZEND_FILE_LINE_RELAY_CC, errors);
         zend_debug_alloc_output("------------------------------------------------\n");          zend_debug_alloc_output("------------------------------------------------\n");
 }  }
 #endif  
 #endif  #endif
   
 /*  /*

Removed from v.1.1.1.1  
changed lines
  Added in v.1.1.1.2


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>