6425531 integer overflows in FreeType
authorAlan Coopersmith <Alan.Coopersmith@Sun.COM>
Tue, 23 May 2006 13:36:15 -0700
changeset 22 fbbfc53a5a1d
parent 21 bfabea52140f
child 23 04fb0c4c58b9
6425531 integer overflows in FreeType
open-src/lib/freetype/6425531.patch
open-src/lib/freetype/Makefile
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/open-src/lib/freetype/6425531.patch	Tue May 23 13:36:15 2006 -0700
@@ -0,0 +1,2014 @@
+Memory allocation fixes from FreeType 2.2.1 to fix
+Sun bug #6425531: integer overflows in FreeType.
+
+diff -urp -x '*~' /builds/unix/ftsystem.c builds/unix/ftsystem.c
+--- /builds/unix/ftsystem.c	2004-12-28 15:08:51.000000000 -0800
++++ builds/unix/ftsystem.c	2006-05-22 18:30:42.925611000 -0700
+@@ -4,7 +4,7 @@
+ /*                                                                         */
+ /*    Unix-specific FreeType low-level system interface (body).            */
+ /*                                                                         */
+-/*  Copyright 1996-2001, 2002, 2004 by                                     */
++/*  Copyright 1996-2001, 2002, 2004, 2005, 2006 by                         */
+ /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
+ /*                                                                         */
+ /*  This file is part of the FreeType project, and may only be used,       */
+@@ -23,7 +23,7 @@
+ #include FT_SYSTEM_H
+ #include FT_ERRORS_H
+ #include FT_TYPES_H
+-#include FT_INTERNAL_OBJECTS_H
++#include FT_INTERNAL_STREAM_H
+ 
+   /* memory-mapping includes and definitions */
+ #ifdef HAVE_UNISTD_H
+@@ -303,9 +303,9 @@
+                            stream->base + total_read_count, 
+                            stream->size - total_read_count );
+ 
+-        if ( ( read_count == -1 ) )
++        if ( read_count <= 0 )
+         {
+-          if ( errno == EINTR )
++          if ( read_count == -1 && errno == EINTR )
+             continue;
+ 
+           FT_ERROR(( "FT_Stream_Open:" ));
+diff -urp -x '*~' /include/freetype/fterrdef.h include/freetype/fterrdef.h
+--- /include/freetype/fterrdef.h	2004-02-12 00:33:20.000000000 -0800
++++ include/freetype/fterrdef.h	2006-05-22 18:30:42.961551000 -0700
+@@ -4,7 +4,7 @@
+ /*                                                                         */
+ /*    FreeType error codes (specification).                                */
+ /*                                                                         */
+-/*  Copyright 2002, 2004 by                                                */
++/*  Copyright 2002, 2004, 2006 by                                          */
+ /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
+ /*                                                                         */
+ /*  This file is part of the FreeType project, and may only be used,       */
+@@ -52,6 +52,8 @@
+                 "broken table" )
+   FT_ERRORDEF_( Invalid_Offset,                              0x09, \
+                 "broken offset within table" )
++  FT_ERRORDEF_( Array_Too_Large,                             0x0A, \
++                "array allocation size too large" )
+ 
+   /* glyph/character errors */
+ 
+diff -urp -x '*~' /include/freetype/internal/ftmemory.h include/freetype/internal/ftmemory.h
+--- /include/freetype/internal/ftmemory.h	2005-06-03 22:17:10.000000000 -0700
++++ include/freetype/internal/ftmemory.h	2006-05-22 18:30:42.997897000 -0700
+@@ -4,7 +4,7 @@
+ /*                                                                         */
+ /*    The FreeType memory management macros (specification).               */
+ /*                                                                         */
+-/*  Copyright 1996-2001, 2002, 2004, 2005 by                               */
++/*  Copyright 1996-2001, 2002, 2004, 2005, 2006 by                         */
+ /*  David Turner, Robert Wilhelm, and Werner Lemberg                       */
+ /*                                                                         */
+ /*  This file is part of the FreeType project, and may only be used,       */
+@@ -56,198 +56,134 @@ FT_BEGIN_HEADER
+   /*************************************************************************/
+   /*************************************************************************/
+ 
++
++  /*
++   *  C++ refuses to handle statements like p = (void*)anything; where `p'
++   *  is a typed pointer.  Since we don't have a `typeof' operator in
++   *  standard C++, we have to use ugly casts.
++   */
++
++#ifdef __cplusplus
++#define FT_ASSIGNP( p, val )  *((void**)&(p)) = (val)
++#else
++#define FT_ASSIGNP( p, val )  (p) = (val)
++#endif
++
++
++
+ #ifdef FT_DEBUG_MEMORY
+ 
+-  FT_BASE( FT_Error )
+-  FT_Alloc_Debug( FT_Memory    memory,
+-                  FT_Long      size,
+-                  void*       *P,
+-                  const char*  file_name,
+-                  FT_Long      line_no );
++  FT_BASE( const char* )  _ft_debug_file;
++  FT_BASE( long )         _ft_debug_lineno;
+ 
+-  FT_BASE( FT_Error )
+-  FT_QAlloc_Debug( FT_Memory    memory,
+-                   FT_Long      size,
+-                   void*       *P,
+-                   const char*  file_name,
+-                   FT_Long      line_no );
++#define FT_DEBUG_INNER( exp )  ( _ft_debug_file   = __FILE__, \
++                                 _ft_debug_lineno = __LINE__, \
++                                 (exp) )
+ 
+-  FT_BASE( FT_Error )
+-  FT_Realloc_Debug( FT_Memory    memory,
+-                    FT_Long      current,
++#define FT_ASSIGNP_INNER( p, exp )  ( _ft_debug_file   = __FILE__, \
++                                      _ft_debug_lineno = __LINE__, \
++                                      FT_ASSIGNP( p, exp ) )
++
++#else /* !FT_DEBUG_MEMORY */
++
++#define FT_DEBUG_INNER( exp )       (exp)
++#define FT_ASSIGNP_INNER( p, exp )  FT_ASSIGNP( p, exp )
++
++#endif /* !FT_DEBUG_MEMORY */
++
++
++  /*
++   *  The allocation functions return a pointer, and the error code
++   *  is written to through the `p_error' parameter.  See below for
++   *  for documentation.
++   */
++
++  FT_BASE( FT_Pointer )
++  ft_mem_alloc( FT_Memory  memory,
+                     FT_Long      size,
+-                    void*       *P,
+-                    const char*  file_name,
+-                    FT_Long      line_no );
++                FT_Error  *p_error );
+ 
+-  FT_BASE( FT_Error )
+-  FT_QRealloc_Debug( FT_Memory    memory,
+-                     FT_Long      current,
++  FT_BASE( FT_Pointer )
++  ft_mem_qalloc( FT_Memory  memory,
+                      FT_Long      size,
+-                     void*       *P,
+-                     const char*  file_name,
+-                     FT_Long      line_no );
++                 FT_Error  *p_error );
++
++  FT_BASE( FT_Pointer )
++  ft_mem_realloc( FT_Memory  memory,
++                  FT_Long    item_size,
++                  FT_Long    cur_count,
++                  FT_Long    new_count,
++                  void*      block,
++                  FT_Error  *p_error );
++
++  FT_BASE( FT_Pointer )
++  ft_mem_qrealloc( FT_Memory  memory,
++                   FT_Long    item_size,
++                   FT_Long    cur_count,
++                   FT_Long    new_count,
++                   void*      block,
++                   FT_Error  *p_error );
+ 
+   FT_BASE( void )
+-  FT_Free_Debug( FT_Memory    memory,
+-                 FT_Pointer   block,
+-                 const char*  file_name,
+-                 FT_Long      line_no );
++  ft_mem_free( FT_Memory    memory,
++               const void*  P );
+ 
+-#endif
+ 
++#define FT_MEM_ALLOC( ptr, size )                                         \
++          FT_ASSIGNP_INNER( ptr, ft_mem_alloc( memory, (size), &error ) )
+ 
+-  /*************************************************************************/
+-  /*                                                                       */
+-  /* <Function>                                                            */
+-  /*    FT_Alloc                                                           */
+-  /*                                                                       */
+-  /* <Description>                                                         */
+-  /*    Allocates a new block of memory.  The returned area is always      */
+-  /*    zero-filled; this is a strong convention in many FreeType parts.   */
+-  /*                                                                       */
+-  /* <Input>                                                               */
+-  /*    memory :: A handle to a given `memory object' which handles        */
+-  /*              allocation.                                              */
+-  /*                                                                       */
+-  /*    size   :: The size in bytes of the block to allocate.              */
+-  /*                                                                       */
+-  /* <Output>                                                              */
+-  /*    P      :: A pointer to the fresh new block.  It should be set to   */
+-  /*              NULL if `size' is 0, or in case of error.                */
+-  /*                                                                       */
+-  /* <Return>                                                              */
+-  /*    FreeType error code.  0 means success.                             */
+-  /*                                                                       */
+-  FT_BASE( FT_Error )
+-  FT_Alloc( FT_Memory  memory,
+-            FT_Long    size,
+-            void*     *P );
++#define FT_MEM_FREE( ptr )                \
++          FT_BEGIN_STMNT                  \
++            ft_mem_free( memory, (ptr) ); \
++            (ptr) = NULL;                 \
++          FT_END_STMNT
+ 
++#define FT_MEM_NEW( ptr )                        \
++          FT_MEM_ALLOC( ptr, sizeof ( *(ptr) ) )
+ 
+-  /*************************************************************************/
+-  /*                                                                       */
+-  /* <Function>                                                            */
+-  /*    FT_QAlloc                                                          */
+-  /*                                                                       */
+-  /* <Description>                                                         */
+-  /*    Allocates a new block of memory.  The returned area is *not*       */
+-  /*    zero-filled, making allocation quicker.                            */
+-  /*                                                                       */
+-  /* <Input>                                                               */
+-  /*    memory :: A handle to a given `memory object' which handles        */
+-  /*              allocation.                                              */
+-  /*                                                                       */
+-  /*    size   :: The size in bytes of the block to allocate.              */
+-  /*                                                                       */
+-  /* <Output>                                                              */
+-  /*    P      :: A pointer to the fresh new block.  It should be set to   */
+-  /*              NULL if `size' is 0, or in case of error.                */
+-  /*                                                                       */
+-  /* <Return>                                                              */
+-  /*    FreeType error code.  0 means success.                             */
+-  /*                                                                       */
+-  FT_BASE( FT_Error )
+-  FT_QAlloc( FT_Memory  memory,
+-             FT_Long    size,
+-             void*     *p );
++#define FT_MEM_REALLOC( ptr, cursz, newsz )                        \
++          FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, 1,        \
++                                                 (cursz), (newsz), \
++                                                 (ptr), &error ) )
+ 
++#define FT_MEM_QALLOC( ptr, size )                                         \
++          FT_ASSIGNP_INNER( ptr, ft_mem_qalloc( memory, (size), &error ) )
+ 
+-  /*************************************************************************/
+-  /*                                                                       */
+-  /* <Function>                                                            */
+-  /*    FT_Realloc                                                         */
+-  /*                                                                       */
+-  /* <Description>                                                         */
+-  /*    Reallocates a block of memory pointed to by `*P' to `Size' bytes   */
+-  /*    from the heap, possibly changing `*P'.  The returned area is       */
+-  /*    zero-filled.                                                       */
+-  /*                                                                       */
+-  /* <Input>                                                               */
+-  /*    memory  :: A handle to a given `memory object' which handles       */
+-  /*               reallocation.                                           */
+-  /*                                                                       */
+-  /*    current :: The current block size in bytes.                        */
+-  /*                                                                       */
+-  /*    size    :: The new block size in bytes.                            */
+-  /*                                                                       */
+-  /* <InOut>                                                               */
+-  /*    P       :: A pointer to the fresh new block.  It should be set to  */
+-  /*               NULL if `size' is 0, or in case of error.               */
+-  /*                                                                       */
+-  /* <Return>                                                              */
+-  /*    FreeType error code.  0 means success.                             */
+-  /*                                                                       */
+-  /* <Note>                                                                */
+-  /*    All callers of FT_Realloc() _must_ provide the current block size  */
+-  /*    as well as the new one.                                            */
+-  /*                                                                       */
+-  FT_BASE( FT_Error )
+-  FT_Realloc( FT_Memory  memory,
+-              FT_Long    current,
+-              FT_Long    size,
+-              void*     *P );
++#define FT_MEM_QNEW( ptr )                        \
++          FT_MEM_QALLOC( ptr, sizeof ( *(ptr) ) )
+ 
++#define FT_MEM_QREALLOC( ptr, cursz, newsz )                         \
++          FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, 1,        \
++                                                  (cursz), (newsz), \
++                                                  (ptr), &error ) )
+ 
+-  /*************************************************************************/
+-  /*                                                                       */
+-  /* <Function>                                                            */
+-  /*    FT_QRealloc                                                        */
+-  /*                                                                       */
+-  /* <Description>                                                         */
+-  /*    Reallocates a block of memory pointed to by `*P' to `Size' bytes   */
+-  /*    from the heap, possibly changing `*P'.  The returned area is *not* */
+-  /*    zero-filled, making reallocation quicker.                          */
+-  /*                                                                       */
+-  /* <Input>                                                               */
+-  /*    memory  :: A handle to a given `memory object' which handles       */
+-  /*               reallocation.                                           */
+-  /*                                                                       */
+-  /*    current :: The current block size in bytes.                        */
+-  /*                                                                       */
+-  /*    size    :: The new block size in bytes.                            */
+-  /*                                                                       */
+-  /* <InOut>                                                               */
+-  /*    P       :: A pointer to the fresh new block.  It should be set to  */
+-  /*               NULL if `size' is 0, or in case of error.               */
+-  /*                                                                       */
+-  /* <Return>                                                              */
+-  /*    FreeType error code.  0 means success.                             */
+-  /*                                                                       */
+-  /* <Note>                                                                */
+-  /*    All callers of FT_Realloc() _must_ provide the current block size  */
+-  /*    as well as the new one.                                            */
+-  /*                                                                       */
+-  FT_BASE( FT_Error )
+-  FT_QRealloc( FT_Memory  memory,
+-               FT_Long    current,
+-               FT_Long    size,
+-               void*     *p );
++#define FT_MEM_QRENEW_ARRAY( ptr, cursz, newsz )                             \
++          FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, sizeof ( *(ptr) ), \
++                                                  (cursz), (newsz),          \
++                                                  (ptr), &error ) )
+ 
++#define FT_MEM_ALLOC_MULT( ptr, count, item_size )                    \
++          FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, (item_size), \
++                                                 0, (count),          \
++                                                 NULL, &error ) )
+ 
+-  /*************************************************************************/
+-  /*                                                                       */
+-  /* <Function>                                                            */
+-  /*    FT_Free                                                            */
+-  /*                                                                       */
+-  /* <Description>                                                         */
+-  /*    Releases a given block of memory allocated through FT_Alloc().     */
+-  /*                                                                       */
+-  /* <Input>                                                               */
+-  /*    memory :: A handle to a given `memory object' which handles        */
+-  /*              memory deallocation                                      */
+-  /*                                                                       */
+-  /*    P      :: This is the _address_ of a _pointer_ which points to the */
+-  /*              allocated block.  It is always set to NULL on exit.      */
+-  /*                                                                       */
+-  /* <Note>                                                                */
+-  /*    If P or *P is NULL, this function should return successfully.      */
+-  /*    This is a strong convention within all of FreeType and its         */
+-  /*    drivers.                                                           */
+-  /*                                                                       */
+-  FT_BASE( void )
+-  FT_Free( FT_Memory  memory,
+-           void*     *P );
++#define FT_MEM_REALLOC_MULT( ptr, oldcnt, newcnt, itmsz )            \
++          FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, (itmsz),    \
++                                                 (oldcnt), (newcnt), \
++                                                 (ptr), &error ) )
++
++#define FT_MEM_QALLOC_MULT( ptr, count, item_size )                    \
++          FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, (item_size), \
++                                                  0, (count),          \
++                                                  NULL, &error ) )
++
++#define FT_MEM_QREALLOC_MULT( ptr, oldcnt, newcnt, itmsz)             \
++          FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, (itmsz),    \
++                                                  (oldcnt), (newcnt), \
++                                                  (ptr), &error ) )
++
++
++#define FT_MEM_SET_ERROR( cond )  ( (cond), error != 0 )
+ 
+ 
+ #define FT_MEM_SET( dest, byte, count )     ft_memset( dest, byte, count )
+@@ -261,6 +197,7 @@ FT_BEGIN_HEADER
+ 
+ #define FT_ZERO( p )                FT_MEM_ZERO( p, sizeof ( *(p) ) )
+ 
++
+ #define FT_ARRAY_ZERO( dest, count )                        \
+           FT_MEM_ZERO( dest, (count) * sizeof ( *(dest) ) )
+ 
+@@ -283,155 +220,109 @@ FT_BEGIN_HEADER
+ 
+   /*************************************************************************/
+   /*                                                                       */
+-  /* We first define FT_MEM_ALLOC, FT_MEM_REALLOC, and FT_MEM_FREE.  All   */
+-  /* macros use an _implicit_ `memory' parameter to access the current     */
+-  /* memory allocator.                                                     */
+-  /*                                                                       */
+-
+-#ifdef FT_DEBUG_MEMORY
+-
+-#define FT_MEM_ALLOC( _pointer_, _size_ )              \
+-          FT_Alloc_Debug( memory, _size_,              \
+-                          (void**)(void*)&(_pointer_), \
+-                          __FILE__, __LINE__ )
+-
+-#define FT_MEM_REALLOC( _pointer_, _current_, _size_ )   \
+-          FT_Realloc_Debug( memory, _current_, _size_,   \
+-                            (void**)(void*)&(_pointer_), \
+-                            __FILE__, __LINE__ )
+-
+-#define FT_MEM_QALLOC( _pointer_, _size_ )              \
+-          FT_QAlloc_Debug( memory, _size_,              \
+-                           (void**)(void*)&(_pointer_), \
+-                           __FILE__, __LINE__ )
+-
+-#define FT_MEM_QREALLOC( _pointer_, _current_, _size_ )   \
+-          FT_QRealloc_Debug( memory, _current_, _size_,   \
+-                             (void**)(void*)&(_pointer_), \
+-                             __FILE__, __LINE__ )
+-
+-#define FT_MEM_FREE( _pointer_ )                              \
+-          FT_Free_Debug( memory, (void**)(void*)&(_pointer_), \
+-                         __FILE__, __LINE__ )
+-
+-
+-#else  /* !FT_DEBUG_MEMORY */
+-
+-
+-#define FT_MEM_ALLOC( _pointer_, _size_ )         \
+-          FT_Alloc( memory, _size_,               \
+-                    (void**)(void*)&(_pointer_) )
+-
+-#define FT_MEM_FREE( _pointer_ )                 \
+-          FT_Free( memory,                       \
+-                   (void**)(void*)&(_pointer_) )
+-
+-#define FT_MEM_REALLOC( _pointer_, _current_, _size_ ) \
+-          FT_Realloc( memory, _current_, _size_,       \
+-                      (void**)(void*)&(_pointer_) )
+-
+-#define FT_MEM_QALLOC( _pointer_, _size_ )         \
+-          FT_QAlloc( memory, _size_,               \
+-                     (void**)(void*)&(_pointer_) )
+-
+-#define FT_MEM_QREALLOC( _pointer_, _current_, _size_ ) \
+-          FT_QRealloc( memory, _current_, _size_,       \
+-          (void**)(void*)&(_pointer_) )
+-
+-#endif /* !FT_DEBUG_MEMORY */
+-
+-
+-  /*************************************************************************/
+-  /*                                                                       */
+   /* The following functions macros expect that their pointer argument is  */
+   /* _typed_ in order to automatically compute array element sizes.        */
+   /*                                                                       */
+ 
+-#define FT_MEM_NEW( _pointer_ )                              \
+-          FT_MEM_ALLOC( _pointer_, sizeof ( *(_pointer_) ) )
++#define FT_MEM_NEW_ARRAY( ptr, count )                                      \
++          FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, sizeof ( *(ptr) ), \
++                                                 0, (count),                \
++                                                 NULL, &error ) )
+ 
+-#define FT_MEM_NEW_ARRAY( _pointer_, _count_ )                           \
+-          FT_MEM_ALLOC( _pointer_, (_count_) * sizeof ( *(_pointer_) ) )
++#define FT_MEM_RENEW_ARRAY( ptr, cursz, newsz )                             \
++          FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, sizeof ( *(ptr) ), \
++                                                 (cursz), (newsz),          \
++                                                 (ptr), &error ) )
+ 
+-#define FT_MEM_RENEW_ARRAY( _pointer_, _old_, _new_ )                    \
+-          FT_MEM_REALLOC( _pointer_, (_old_) * sizeof ( *(_pointer_) ),  \
+-                                     (_new_) * sizeof ( *(_pointer_) ) )
++#define FT_MEM_QNEW_ARRAY( ptr, count )                                      \
++          FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, sizeof ( *(ptr) ), \
++                                                  0, (count),                \
++                                                  NULL, &error ) )
+ 
+-#define FT_MEM_QNEW( _pointer_ )                              \
+-          FT_MEM_QALLOC( _pointer_, sizeof ( *(_pointer_) ) )
++#define FT_MEM_QRENEW_ARRAY( ptr, cursz, newsz )                             \
++          FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, sizeof ( *(ptr) ), \
++                                                  (cursz), (newsz),          \
++                                                  (ptr), &error ) )
+ 
+-#define FT_MEM_QNEW_ARRAY( _pointer_, _count_ )                           \
+-          FT_MEM_QALLOC( _pointer_, (_count_) * sizeof ( *(_pointer_) ) )
+ 
+-#define FT_MEM_QRENEW_ARRAY( _pointer_, _old_, _new_ )                    \
+-          FT_MEM_QREALLOC( _pointer_, (_old_) * sizeof ( *(_pointer_) ),  \
+-                                      (_new_) * sizeof ( *(_pointer_) ) )
++#define FT_ALLOC( ptr, size )                           \
++          FT_MEM_SET_ERROR( FT_MEM_ALLOC( ptr, size ) )
+ 
++#define FT_REALLOC( ptr, cursz, newsz )                           \
++          FT_MEM_SET_ERROR( FT_MEM_REALLOC( ptr, cursz, newsz ) )
+ 
+-  /*************************************************************************/
+-  /*                                                                       */
+-  /* the following macros are obsolete but kept for compatibility reasons  */
+-  /*                                                                       */
++#define FT_ALLOC_MULT( ptr, count, item_size )                           \
++          FT_MEM_SET_ERROR( FT_MEM_ALLOC_MULT( ptr, count, item_size ) )
+ 
+-#define FT_MEM_ALLOC_ARRAY( _pointer_, _count_, _type_ )           \
+-          FT_MEM_ALLOC( _pointer_, (_count_) * sizeof ( _type_ ) )
++#define FT_MEM_ALLOC_ARRAY( _pointer_, _count_, _type_ )           \
++          FT_ALLOC_MULT( _pointer_, (_count_) , sizeof ( _type_ ) )
++ 
++#define FT_REALLOC_MULT( ptr, oldcnt, newcnt, itmsz )              \
++          FT_MEM_SET_ERROR( FT_MEM_REALLOC_MULT( ptr, oldcnt,      \
++                                                 newcnt, itmsz ) )
+ 
+-#define FT_MEM_REALLOC_ARRAY( _pointer_, _old_, _new_, _type_ )    \
+-          FT_MEM_REALLOC( _pointer_, (_old_) * sizeof ( _type ),   \
+-                                     (_new_) * sizeof ( _type_ ) )
++#define FT_QALLOC( ptr, size )                           \
++          FT_MEM_SET_ERROR( FT_MEM_QALLOC( ptr, size ) )
+ 
++#define FT_QREALLOC( ptr, cursz, newsz )                           \
++          FT_MEM_SET_ERROR( FT_MEM_QREALLOC( ptr, cursz, newsz ) )
+ 
+-  /*************************************************************************/
+-  /*                                                                       */
+-  /* The following macros are variants of their FT_MEM_XXXX equivalents;   */
+-  /* they are used to set an _implicit_ `error' variable and return TRUE   */
+-  /* if an error occured (i.e. if 'error != 0').                           */
+-  /*                                                                       */
++#define FT_QALLOC_MULT( ptr, count, item_size )                           \
++          FT_MEM_SET_ERROR( FT_MEM_QALLOC_MULT( ptr, count, item_size ) )
+ 
+-#define FT_ALLOC( _pointer_, _size_ )                       \
+-          FT_SET_ERROR( FT_MEM_ALLOC( _pointer_, _size_ ) )
++#define FT_QREALLOC_MULT( ptr, oldcnt, newcnt, itmsz )              \
++          FT_MEM_SET_ERROR( FT_MEM_QREALLOC_MULT( ptr, oldcnt,      \
++                                                  newcnt, itmsz ) )
+ 
+-#define FT_REALLOC( _pointer_, _current_, _size_ )                       \
+-          FT_SET_ERROR( FT_MEM_REALLOC( _pointer_, _current_, _size_ ) )
++#define FT_FREE( ptr )  FT_MEM_FREE( ptr )
+ 
+-#define FT_QALLOC( _pointer_, _size_ )                       \
+-          FT_SET_ERROR( FT_MEM_QALLOC( _pointer_, _size_ ) )
++#define FT_NEW( ptr )  FT_MEM_SET_ERROR( FT_MEM_NEW( ptr ) )
+ 
+-#define FT_QREALLOC( _pointer_, _current_, _size_ )                       \
+-          FT_SET_ERROR( FT_MEM_QREALLOC( _pointer_, _current_, _size_ ) )
++#define FT_NEW_ARRAY( ptr, count )                           \
++          FT_MEM_SET_ERROR( FT_MEM_NEW_ARRAY( ptr, count ) )
+ 
++#define FT_RENEW_ARRAY( ptr, curcnt, newcnt )                           \
++          FT_MEM_SET_ERROR( FT_MEM_RENEW_ARRAY( ptr, curcnt, newcnt ) )
+ 
+-#define FT_FREE( _pointer_ )       \
+-          FT_MEM_FREE( _pointer_ )
++#define FT_QNEW( ptr )                           \
++          FT_MEM_SET_ERROR( FT_MEM_QNEW( ptr ) )
+ 
++#define FT_QNEW_ARRAY( ptr, count )                          \
++          FT_MEM_SET_ERROR( FT_MEM_NEW_ARRAY( ptr, count ) )
+ 
+-#define FT_NEW( _pointer_ )                              \
+-          FT_ALLOC( _pointer_, sizeof ( *(_pointer_) ) )
++#define FT_QRENEW_ARRAY( ptr, curcnt, newcnt )                          \
++          FT_MEM_SET_ERROR( FT_MEM_RENEW_ARRAY( ptr, curcnt, newcnt ) )
+ 
+-#define FT_NEW_ARRAY( _pointer_, _count_ )                           \
+-          FT_ALLOC( _pointer_, sizeof ( *(_pointer_) ) * (_count_) )
+ 
+-#define FT_RENEW_ARRAY( _pointer_, _old_, _new_ )                    \
+-          FT_REALLOC( _pointer_, sizeof ( *(_pointer_) ) * (_old_),  \
+-                                 sizeof ( *(_pointer_) ) * (_new_) )
++#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
+ 
+-#define FT_QNEW( _pointer_ )                              \
+-          FT_QALLOC( _pointer_, sizeof ( *(_pointer_) ) )
++  FT_BASE( FT_Error )
++  FT_Alloc( FT_Memory  memory,
++            FT_Long    size,
++            void*     *P );
+ 
+-#define FT_QNEW_ARRAY( _pointer_, _count_ )                           \
+-          FT_QALLOC( _pointer_, sizeof ( *(_pointer_) ) * (_count_) )
++  FT_BASE( FT_Error )
++  FT_QAlloc( FT_Memory  memory,
++             FT_Long    size,
++             void*     *p );
+ 
+-#define FT_QRENEW_ARRAY( _pointer_, _old_, _new_ )                    \
+-          FT_QREALLOC( _pointer_, sizeof ( *(_pointer_) ) * (_old_),  \
+-                                  sizeof ( *(_pointer_) ) * (_new_) )
++  FT_BASE( FT_Error )
++  FT_Realloc( FT_Memory  memory,
++              FT_Long    current,
++              FT_Long    size,
++              void*     *P );
+ 
++  FT_BASE( FT_Error )
++  FT_QRealloc( FT_Memory  memory,
++               FT_Long    current,
++               FT_Long    size,
++               void*     *p );
+ 
+-#define FT_ALLOC_ARRAY( _pointer_, _count_, _type_ )           \
+-          FT_ALLOC( _pointer_, (_count_) * sizeof ( _type_ ) )
++  FT_BASE( void )
++  FT_Free( FT_Memory  memory,
++           void*     *P );
+ 
+-#define FT_REALLOC_ARRAY( _pointer_, _old_, _new_, _type_ )   \
+-          FT_REALLOC( _pointer, (_old_) * sizeof ( _type_ ),  \
+-                                (_new_) * sizeof ( _type_ ) )
++#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
+ 
+ 
+  /* */
+diff -urp -x '*~' /src/base/ftbitmap.c src/base/ftbitmap.c
+--- /src/base/ftbitmap.c	2005-05-30 06:53:09.000000000 -0700
++++ src/base/ftbitmap.c	2006-05-22 18:30:43.046248000 -0700
+@@ -5,7 +5,7 @@
+ /*    FreeType utility functions for converting 1bpp, 2bpp, 4bpp, and 8bpp */
+ /*    bitmaps into 8bpp format (body).                                     */
+ /*                                                                         */
+-/*  Copyright 2004, 2005 by                                                */
++/*  Copyright 2004, 2005, 2006 by                                          */
+ /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
+ /*                                                                         */
+ /*  This file is part of the FreeType project, and may only be used,       */
+@@ -165,7 +165,7 @@
+ 
+     new_pitch = ( bitmap->width + xpixels + ppb - 1 ) / ppb;
+ 
+-    if ( FT_ALLOC( buffer, new_pitch * ( bitmap->rows + ypixels ) ) )
++    if ( FT_QALLOC_MULT( buffer, new_pitch, bitmap->rows + ypixels ) )
+       return error;
+ 
+     if ( bitmap->pitch > 0 )
+@@ -310,12 +310,12 @@
+             {
+               if ( p[x] + p[x - i] > bitmap->num_grays - 1 )
+               {
+-                p[x] = bitmap->num_grays - 1;
++                p[x] = (unsigned char)(bitmap->num_grays - 1);
+                 break;
+               }
+               else
+               {
+-                p[x] += p[x - i];
++                p[x] = (unsigned char)(p[x] + p[x-i]);
+                 if ( p[x] == bitmap->num_grays - 1 )
+                   break;
+               }
+diff -urp -x '*~' /src/base/ftdbgmem.c src/base/ftdbgmem.c
+--- /src/base/ftdbgmem.c	2005-03-03 03:34:15.000000000 -0800
++++ src/base/ftdbgmem.c	2006-05-22 18:30:43.100213000 -0700
+@@ -4,7 +4,7 @@
+ /*                                                                         */
+ /*    Memory debugger (body).                                              */
+ /*                                                                         */
+-/*  Copyright 2001, 2002, 2003, 2004, 2005 by                              */
++/*  Copyright 2001, 2002, 2003, 2004, 2005, 2006 by                        */
+ /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
+ /*                                                                         */
+ /*  This file is part of the FreeType project, and may only be used,       */
+@@ -36,6 +36,8 @@
+ #include <stdio.h>
+ #include <stdlib.h>
+ 
++  FT_BASE_DEF( const char* )  _ft_debug_file   = 0;
++  FT_BASE_DEF( long )         _ft_debug_lineno = 0;
+ 
+   extern void
+   FT_DumpMemory( FT_Memory  memory );
+@@ -48,8 +50,12 @@
+ 
+ #define FT_MEM_VAL( addr )  ((FT_ULong)(FT_Pointer)( addr ))
+ 
+-
+-  typedef struct FT_MemSourceRec_
++  /*
++   *  This structure holds statistics for a single allocation/release
++   *  site.  This is useful to know where memory operations happen the
++   *  most.
++   */
++  typedef struct  FT_MemSourceRec_
+   {
+     const char*   file_name;
+     long          line_no;
+@@ -70,13 +76,19 @@
+   } FT_MemSourceRec;
+ 
+ 
+-/*
+- *  We don't need a resizable array for the memory sources, because
+- *  their number is pretty limited within FreeType.
+- */
++  /*
++   *  We don't need a resizable array for the memory sources, because
++   *  their number is pretty limited within FreeType.
++   */
+ #define FT_MEM_SOURCE_BUCKETS  128
+ 
+-
++  /*
++   *  This structure holds information related to a single allocated
++   *  memory block.  If KEEPALIVE is defined, blocks that are freed by
++   *  FreeType are never released to the system.  Instead, their `size'
++   *  field is set to -size.  This is mainly useful to detect double frees,
++   *  at the price of large memory footprint during execution.
++   */
+   typedef struct  FT_MemNodeRec_
+   {
+     FT_Byte*      address;
+@@ -94,6 +106,10 @@
+   } FT_MemNodeRec;
+ 
+ 
++  /*
++   *  The global structure, containing compound statistics and all hash
++   *  tables.
++   */
+   typedef struct  FT_MemTableRec_
+   {
+     FT_ULong         size;
+@@ -113,9 +129,6 @@
+ 
+     FT_MemSource     sources[FT_MEM_SOURCE_BUCKETS];
+ 
+-    const char*      file_name;
+-    FT_Long          line_no;
+-
+     FT_Bool          keep_alive;
+ 
+     FT_Memory        memory;
+@@ -446,8 +459,8 @@
+     FT_MemSource  node, *pnode;
+ 
+ 
+-    hash  = (FT_UInt32)(void*)table->file_name +
+-              (FT_UInt32)( 5 * table->line_no );
++    hash  = (FT_UInt32)(void*)_ft_debug_file +
++              (FT_UInt32)( 5 * _ft_debug_lineno );
+     pnode = &table->sources[hash % FT_MEM_SOURCE_BUCKETS];
+ 
+     for ( ;; )
+@@ -456,8 +469,8 @@
+       if ( node == NULL )
+         break;
+ 
+-      if ( node->file_name == table->file_name &&
+-           node->line_no   == table->line_no   )
++      if ( node->file_name == _ft_debug_file &&
++           node->line_no   == _ft_debug_lineno   )
+         goto Exit;
+ 
+       pnode = &node->link;
+@@ -468,8 +481,8 @@
+       ft_mem_debug_panic(
+         "not enough memory to perform memory debugging\n" );
+ 
+-    node->file_name = table->file_name;
+-    node->line_no   = table->line_no;
++    node->file_name = _ft_debug_file;
++    node->line_no   = _ft_debug_lineno;
+ 
+     node->cur_blocks = 0;
+     node->max_blocks = 0;
+@@ -493,7 +506,8 @@
+   static void
+   ft_mem_table_set( FT_MemTable  table,
+                     FT_Byte*     address,
+-                    FT_ULong     size )
++                    FT_ULong     size,
++                    FT_Long      delta )
+   {
+     FT_MemNode  *pnode, node;
+ 
+@@ -525,7 +539,7 @@
+             "org=%s:%d new=%s:%d\n",
+             node->address, node->size,
+             FT_FILENAME( node->source->file_name ), node->source->line_no,
+-            FT_FILENAME( table->file_name ), table->line_no );
++            FT_FILENAME( _ft_debug_file ), _ft_debug_lineno );
+         }
+       }
+ 
+@@ -536,19 +550,35 @@
+ 
+       node->address = address;
+       node->size    = size;
++      node->source  = source = ft_mem_table_get_source( table );
+ 
+-      node->source = source = ft_mem_table_get_source( table );
+-
+-      source->all_blocks++;
+-      source->cur_blocks++;
+-      if ( source->cur_blocks > source->max_blocks )
+-        source->max_blocks = source->cur_blocks;
++      if ( delta == 0 )
++      {
++        /* this is an allocation */
++        source->all_blocks++;
++        source->cur_blocks++;
++        if ( source->cur_blocks > source->max_blocks )
++          source->max_blocks = source->cur_blocks;
++      }
+ 
+       if ( size > (FT_ULong)source->cur_max )
+         source->cur_max = size;
+ 
++      if ( delta != 0 )
++      {
++        /* we are growing or shrinking a reallocated block */
++        source->cur_size     += delta;
++        table->alloc_current += delta;
++      }
++      else
++      {
++        /* we are allocating a new block */
++        source->cur_size     += size;
++        table->alloc_current += size;
++      }
++
+       source->all_size += size;
+-      source->cur_size += size;
++
+       if ( source->cur_size > source->max_size )
+         source->max_size = source->cur_size;
+ 
+@@ -560,8 +590,8 @@
+       pnode[0] = node;
+       table->nodes++;
+ 
+-      table->alloc_total   += size;
+-      table->alloc_current += size;
++      table->alloc_total += size;
++
+       if ( table->alloc_current > table->alloc_max )
+         table->alloc_max = table->alloc_current;
+ 
+@@ -574,7 +604,8 @@
+ 
+   static void
+   ft_mem_table_remove( FT_MemTable  table,
+-                       FT_Byte*     address )
++                       FT_Byte*     address,
++                       FT_Long      delta )
+   {
+     if ( table )
+     {
+@@ -593,26 +624,30 @@
+             "freeing memory block at %p more than once at (%s:%ld)\n"
+             "block allocated at (%s:%ld) and released at (%s:%ld)",
+             address,
+-            FT_FILENAME( table->file_name ), table->line_no,
++            FT_FILENAME( _ft_debug_file ), _ft_debug_lineno,
+             FT_FILENAME( node->source->file_name ), node->source->line_no,
+             FT_FILENAME( node->free_file_name ), node->free_line_no );
+ 
+         /* scramble the node's content for additional safety */
+         FT_MEM_SET( address, 0xF3, node->size );
+-        table->alloc_current -= node->size;
+ 
+-        source = node->source;
++        if ( delta == 0 )
++        {
++          source = node->source;
++
++          source->cur_blocks--;
++          source->cur_size -= node->size;
+ 
+-        source->cur_blocks--;
+-        source->cur_size -= node->size;
++          table->alloc_current -= node->size;
++        }
+ 
+         if ( table->keep_alive )
+         {
+           /* we simply invert the node's size to indicate that the node */
+           /* was freed.                                                 */
+           node->size           = -node->size;
+-          node->free_file_name = table->file_name;
+-          node->free_line_no   = table->line_no;
++          node->free_file_name = _ft_debug_file;
++          node->free_line_no   = _ft_debug_lineno;
+         }
+         else
+         {
+@@ -634,7 +669,7 @@
+         ft_mem_debug_panic(
+           "trying to free unknown block at %p in (%s:%ld)\n",
+           address,
+-          FT_FILENAME( table->file_name ), table->line_no );
++          FT_FILENAME( _ft_debug_file ), _ft_debug_lineno );
+     }
+   }
+ 
+@@ -657,17 +692,19 @@
+ 
+     /* return NULL if this allocation would overflow the maximum heap size */
+     if ( table->bound_total                                             &&
+-         table->alloc_current + (FT_ULong)size > table->alloc_total_max )
++         table->alloc_total_max - table->alloc_current > (FT_ULong)size )
+       return NULL;
+ 
+     block = (FT_Byte *)ft_mem_table_alloc( table, size );
+     if ( block )
+-      ft_mem_table_set( table, block, (FT_ULong)size );
++    {
++      ft_mem_table_set( table, block, (FT_ULong)size, 0 );
+ 
+-    table->alloc_count++;
++      table->alloc_count++;
++    }
+ 
+-    table->file_name = NULL;
+-    table->line_no   = 0;
++    _ft_debug_file   = "<unknown>";
++    _ft_debug_lineno = 0;
+ 
+     return (FT_Pointer)block;
+   }
+@@ -682,18 +719,18 @@
+ 
+     if ( block == NULL )
+       ft_mem_debug_panic( "trying to free NULL in (%s:%ld)",
+-                          FT_FILENAME( table->file_name ),
+-                          table->line_no );
++                          FT_FILENAME( _ft_debug_file ),
++                          _ft_debug_lineno );
+ 
+-    ft_mem_table_remove( table, (FT_Byte*)block );
++    ft_mem_table_remove( table, (FT_Byte*)block, 0 );
+ 
+     if ( !table->keep_alive )
+       ft_mem_table_free( table, block );
+ 
+     table->alloc_count--;
+ 
+-    table->file_name = NULL;
+-    table->line_no   = 0;
++    _ft_debug_file   = "<unknown>";
++    _ft_debug_lineno = 0;
+   }
+ 
+ 
+@@ -706,10 +743,15 @@
+     FT_MemTable  table = (FT_MemTable)memory->user;
+     FT_MemNode   node, *pnode;
+     FT_Pointer   new_block;
++    FT_Long      delta;
++
++    const char*  file_name = FT_FILENAME( _ft_debug_file );
++    FT_Long      line_no   = _ft_debug_lineno;
+ 
+-    const char*  file_name = FT_FILENAME( table->file_name );
+-    FT_Long      line_no   = table->line_no;
+ 
++    /* unlikely, but possible */
++    if ( new_size == cur_size )
++      return block;
+ 
+     /* the following is valid according to ANSI C */
+ #if 0
+@@ -743,16 +785,34 @@
+                           "%ld instead of %ld in (%s:%ld)",
+                           block, cur_size, node->size, file_name, line_no );
+ 
+-    new_block = ft_mem_debug_alloc( memory, new_size );
++    /* return NULL if the maximum number of allocations was reached */
++    if ( table->bound_count                           &&
++         table->alloc_count >= table->alloc_count_max )
++      return NULL;
++
++    delta = (FT_Long)( new_size - cur_size );
++
++    /* return NULL if this allocation would overflow the maximum heap size */
++    if ( delta > 0                                                       &&
++         table->bound_total                                              &&
++         table->alloc_current + (FT_ULong)delta > table->alloc_total_max )
++      return NULL;
++
++    new_block = (FT_Byte *)ft_mem_table_alloc( table, new_size );
+     if ( new_block == NULL )
+       return NULL;
+ 
++    ft_mem_table_set( table, (FT_Byte*)new_block, new_size, delta );
++
+     ft_memcpy( new_block, block, cur_size < new_size ? cur_size : new_size );
+ 
+-    table->file_name = file_name;
+-    table->line_no   = line_no;
++    ft_mem_table_remove( table, (FT_Byte*)block, delta );
++
++    _ft_debug_file   = "<unknown>";
++    _ft_debug_lineno = 0;
+ 
+-    ft_mem_debug_free( memory, (FT_Byte*)block );
++    if ( !table->keep_alive )
++      ft_mem_table_free( table, block );
+ 
+     return new_block;
+   }
+@@ -839,106 +899,6 @@
+   }
+ 
+ 
+-  FT_BASE_DEF( FT_Error )
+-  FT_Alloc_Debug( FT_Memory    memory,
+-                  FT_Long      size,
+-                  void*       *P,
+-                  const char*  file_name,
+-                  FT_Long      line_no )
+-  {
+-    FT_MemTable  table = (FT_MemTable)memory->user;
+-
+-
+-    if ( table )
+-    {
+-      table->file_name = file_name;
+-      table->line_no   = line_no;
+-    }
+-
+-    return FT_Alloc( memory, size, P );
+-  }
+-
+-
+-  FT_BASE_DEF( FT_Error )
+-  FT_Realloc_Debug( FT_Memory    memory,
+-                    FT_Long      current,
+-                    FT_Long      size,
+-                    void*       *P,
+-                    const char*  file_name,
+-                    FT_Long      line_no )
+-  {
+-    FT_MemTable  table = (FT_MemTable)memory->user;
+-
+-
+-    if ( table )
+-    {
+-      table->file_name = file_name;
+-      table->line_no   = line_no;
+-    }
+-
+-    return FT_Realloc( memory, current, size, P );
+-  }
+-
+-
+-  FT_BASE_DEF( FT_Error )
+-  FT_QAlloc_Debug( FT_Memory    memory,
+-                   FT_Long      size,
+-                   void*       *P,
+-                   const char*  file_name,
+-                   FT_Long      line_no )
+-  {
+-    FT_MemTable  table = (FT_MemTable)memory->user;
+-
+-
+-    if ( table )
+-    {
+-      table->file_name = file_name;
+-      table->line_no   = line_no;
+-    }
+-
+-    return FT_QAlloc( memory, size, P );
+-  }
+-
+-
+-  FT_BASE_DEF( FT_Error )
+-  FT_QRealloc_Debug( FT_Memory    memory,
+-                     FT_Long      current,
+-                     FT_Long      size,
+-                     void*       *P,
+-                     const char*  file_name,
+-                     FT_Long      line_no )
+-  {
+-    FT_MemTable  table = (FT_MemTable)memory->user;
+-
+-
+-    if ( table )
+-    {
+-      table->file_name = file_name;
+-      table->line_no   = line_no;
+-    }
+-
+-    return FT_QRealloc( memory, current, size, P );
+-  }
+-
+-
+-  FT_BASE_DEF( void )
+-  FT_Free_Debug( FT_Memory    memory,
+-                 FT_Pointer   block,
+-                 const char*  file_name,
+-                 FT_Long      line_no )
+-  {
+-    FT_MemTable  table = (FT_MemTable)memory->user;
+-
+-
+-    if ( table )
+-    {
+-      table->file_name = file_name;
+-      table->line_no   = line_no;
+-    }
+-
+-    FT_Free( memory, (void **)block );
+-  }
+-
+ 
+   static int
+   ft_mem_source_compare( const void*  p1,
+diff -urp -x '*~' /src/base/ftgloadr.c src/base/ftgloadr.c
+--- /src/base/ftgloadr.c	2004-05-13 05:59:59.000000000 -0700
++++ src/base/ftgloadr.c	2006-05-22 18:30:43.142424000 -0700
+@@ -4,7 +4,7 @@
+ /*                                                                         */
+ /*    The FreeType glyph loader (body).                                    */
+ /*                                                                         */
+-/*  Copyright 2002, 2003, 2004 by                                          */
++/*  Copyright 2002, 2003, 2004, 2005 by                                    */
+ /*  David Turner, Robert Wilhelm, and Werner Lemberg                       */
+ /*                                                                         */
+ /*  This file is part of the FreeType project, and may only be used,       */
+@@ -296,14 +296,23 @@
+   FT_BASE_DEF( void )
+   FT_GlyphLoader_Add( FT_GlyphLoader  loader )
+   {
+-    FT_GlyphLoad  base    = &loader->base;
+-    FT_GlyphLoad  current = &loader->current;
++    FT_GlyphLoad  base;
++    FT_GlyphLoad  current;
+ 
+-    FT_UInt       n_curr_contours = current->outline.n_contours;
+-    FT_UInt       n_base_points   = base->outline.n_points;
++    FT_UInt       n_curr_contours;
++    FT_UInt       n_base_points;
+     FT_UInt       n;
+ 
+ 
++    if ( !loader )
++      return;
++
++    base    = &loader->base;
++    current = &loader->current;
++
++    n_curr_contours = current->outline.n_contours;
++    n_base_points   = base->outline.n_points;
++
+     base->outline.n_points =
+       (short)( base->outline.n_points + current->outline.n_points );
+     base->outline.n_contours =
+diff -urp -x '*~' /src/base/ftmac.c src/base/ftmac.c
+--- /src/base/ftmac.c	2004-08-28 01:02:46.000000000 -0700
++++ src/base/ftmac.c	2006-05-22 18:30:43.192033000 -0700
+@@ -3,8 +3,9 @@
+ /*  ftmac.c                                                                */
+ /*                                                                         */
+ /*    Mac FOND support.  Written by [email protected].                    */
++/*  Heavily Fixed by mpsuzuki, George Williams and Sean McBride            */
+ /*                                                                         */
+-/*  Copyright 1996-2001, 2002, 2003, 2004 by                               */
++/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by                   */
+ /*  Just van Rossum, David Turner, Robert Wilhelm, and Werner Lemberg.     */
+ /*                                                                         */
+ /*  This file is part of the FreeType project, and may only be used,       */
+@@ -430,6 +431,7 @@
+     short          res_id;
+     unsigned char  *buffer, *p, *size_p = NULL;
+     FT_ULong       total_size = 0;
++    FT_ULong       old_total_size = 0;
+     FT_ULong       post_size, pfb_chunk_size;
+     Handle         post_data;
+     char           code, last_code;
+@@ -460,6 +462,15 @@
+ 
+       total_size += GetHandleSize( post_data ) - 2;
+       last_code = code;
++
++      /* detect integer overflows */
++      if ( total_size < old_total_size )
++      {
++        error = FT_Err_Array_Too_Large;
++        goto Error;
++      }
++
++      old_total_size = total_size;
+     }
+ 
+     if ( FT_ALLOC( buffer, (FT_Long)total_size ) )
+diff -urp -x '*~' /src/base/ftobjs.c src/base/ftobjs.c
+--- /src/base/ftobjs.c	2005-06-05 23:22:42.000000000 -0700
++++ src/base/ftobjs.c	2006-05-22 18:30:43.245363000 -0700
+@@ -4,7 +4,7 @@
+ /*                                                                         */
+ /*    The FreeType private base classes (body).                            */
+ /*                                                                         */
+-/*  Copyright 1996-2001, 2002, 2003, 2004, 2005 by                         */
++/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by                   */
+ /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
+ /*                                                                         */
+ /*  This file is part of the FreeType project, and may only be used,       */
+@@ -267,6 +267,7 @@
+                              FT_ULong      size )
+   {
+     FT_Memory  memory = FT_FACE_MEMORY( slot->face );
++    FT_Error   error;
+ 
+ 
+     if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )
+@@ -274,7 +275,8 @@
+     else
+       slot->internal->flags |= FT_GLYPH_OWN_BITMAP;
+ 
+-    return FT_MEM_ALLOC( slot->bitmap.buffer, size );
++    (void)FT_ALLOC( slot->bitmap.buffer, size );
++    return error;
+   }
+ 
+ 
+diff -urp -x '*~' /src/base/ftrfork.c src/base/ftrfork.c
+--- /src/base/ftrfork.c	2005-05-21 22:46:10.000000000 -0700
++++ src/base/ftrfork.c	2006-05-22 18:30:43.287568000 -0700
+@@ -4,7 +4,7 @@
+ /*                                                                         */
+ /*    Embedded resource forks accessor (body).                             */
+ /*                                                                         */
+-/*  Copyright 2004, 2005 by                                                */
++/*  Copyright 2004, 2005, 2006 by                                          */
+ /*  Masatake YAMATO and Redhat K.K.                                        */
+ /*                                                                         */
+ /*  FT_Raccess_Get_HeaderInfo() and raccess_guess_darwin_hfsplus() are     */
+@@ -179,7 +179,7 @@
+         if ( error )
+           return error;
+ 
+-        if ( FT_ALLOC( offsets_internal, *count * sizeof( FT_Long ) ) )
++        if ( FT_NEW_ARRAY( offsets_internal, *count ) )
+           return error;
+ 
+         for ( j = 0; j < *count; ++j )
+@@ -426,20 +426,25 @@
+     FT_Error   error;
+     char*      newpath;
+     FT_Memory  memory;
++    FT_Long    base_file_len = ft_strlen( base_file_name );
+ 
+     FT_UNUSED( stream );
+ 
+ 
+     memory = library->memory;
+ 
+-    if ( FT_ALLOC( newpath,
+-                   ft_strlen( base_file_name ) + ft_strlen( "/rsrc" ) + 1 ) )
++    if ( base_file_len > FT_INT_MAX )
++      return FT_Err_Array_Too_Large;
++
++    if ( FT_ALLOC( newpath, base_file_len + 6 ) )
+       return error;
+ 
+-    ft_strcpy( newpath, base_file_name );
+-    ft_strcat( newpath, "/rsrc" );
++    FT_MEM_COPY( newpath, base_file_name, base_file_len );
++    FT_MEM_COPY( newpath + base_file_len, "/rsrc", 6 );
++
+     *result_file_name = newpath;
+     *result_offset = 0;
++
+     return FT_Err_Ok;
+   }
+ 
+@@ -657,7 +662,7 @@
+     char*        tmp;
+     const char*  slash;
+     unsigned     new_length;
+-    FT_ULong     error = FT_Err_Ok;
++    FT_Error     error = FT_Err_Ok;
+ 
+     FT_UNUSED( error );
+ 
+diff -urp -x '*~' /src/base/ftstream.c src/base/ftstream.c
+--- /src/base/ftstream.c	2005-03-15 17:15:07.000000000 -0800
++++ src/base/ftstream.c	2006-05-22 18:30:43.335335000 -0700
+@@ -4,7 +4,7 @@
+ /*                                                                         */
+ /*    I/O stream support (body).                                           */
+ /*                                                                         */
+-/*  Copyright 2000-2001, 2002, 2004, 2005 by                               */
++/*  Copyright 2000-2001, 2002, 2004, 2005, 2006 by                         */
+ /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
+ /*                                                                         */
+ /*  This file is part of the FreeType project, and may only be used,       */
+@@ -212,8 +212,12 @@
+     {
+       FT_Memory  memory = stream->memory;
+ 
+-
++#ifdef FT_DEBUG_MEMORY
++      ft_mem_free( memory, *pbytes );
++      *pbytes = NULL;
++#else
+       FT_FREE( *pbytes );
++#endif
+     }
+     *pbytes = 0;
+   }
+@@ -235,10 +239,15 @@
+       /* allocate the frame in memory */
+       FT_Memory  memory = stream->memory;
+ 
+-
++#ifdef FT_DEBUG_MEMORY
++      /* assume _ft_debug_file and _ft_debug_lineno are already set */
++      stream->base = (unsigned char*)ft_mem_qalloc( memory, count, &error );
++      if ( error )
++        goto Exit;
++#else
+       if ( FT_QALLOC( stream->base, count ) )
+         goto Exit;
+-
++#endif
+       /* read it */
+       read_bytes = stream->read( stream, stream->pos,
+                                  stream->base, count );
+@@ -298,8 +307,12 @@
+     {
+       FT_Memory  memory = stream->memory;
+ 
+-
++#ifdef FT_DEBUG_MEMORY
++      ft_mem_free( memory, stream->base );
++      stream->base = NULL;
++#else
+       FT_FREE( stream->base );
++#endif
+     }
+     stream->cursor = 0;
+     stream->limit  = 0;
+diff -urp -x '*~' /src/base/ftutil.c src/base/ftutil.c
+--- /src/base/ftutil.c	2005-03-03 14:59:06.000000000 -0800
++++ src/base/ftutil.c	2006-05-22 18:30:43.387706000 -0700
+@@ -4,7 +4,7 @@
+ /*                                                                         */
+ /*    FreeType utility file for memory and list management (body).         */
+ /*                                                                         */
+-/*  Copyright 2002, 2004, 2005 by                                          */
++/*  Copyright 2002, 2004, 2005, 2006 by                                    */
+ /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
+ /*                                                                         */
+ /*  This file is part of the FreeType project, and may only be used,       */
+@@ -45,167 +45,126 @@
+   /*************************************************************************/
+   /*************************************************************************/
+ 
+-  /* documentation is in ftmemory.h */
+ 
+-  FT_BASE_DEF( FT_Error )
+-  FT_Alloc( FT_Memory  memory,
++  FT_BASE_DEF( FT_Pointer )
++  ft_mem_alloc( FT_Memory  memory,
+             FT_Long    size,
+-            void*     *P )
+-  {
+-    FT_ASSERT( P != 0 );
+-
+-    if ( size > 0 )
+-    {
+-      *P = memory->alloc( memory, size );
+-      if ( !*P )
++                FT_Error  *p_error )
+       {
+-        FT_ERROR(( "FT_Alloc:" ));
+-        FT_ERROR(( " Out of memory? (%ld requested)\n",
+-                   size ));
++    FT_Error    error;
++    FT_Pointer  block = ft_mem_qalloc( memory, size, &error );
+ 
+-        return FT_Err_Out_Of_Memory;
+-      }
+-      FT_MEM_ZERO( *P, size );
+-    }
+-    else
+-      *P = NULL;
++    if ( !error && size > 0 )
++      FT_MEM_ZERO( block, size );
+ 
+-    FT_TRACE7(( "FT_Alloc:" ));
+-    FT_TRACE7(( " size = %ld, block = 0x%08p, ref = 0x%08p\n",
+-                size, *P, P ));
+-
+-    return FT_Err_Ok;
++    *p_error = error;
++    return block;
+   }
+ 
+ 
+-  /* documentation is in ftmemory.h */
+-
+-  FT_BASE_DEF( FT_Error )
+-  FT_QAlloc( FT_Memory  memory,
++  FT_BASE_DEF( FT_Pointer )
++  ft_mem_qalloc( FT_Memory  memory,
+              FT_Long    size,
+-             void*     *P )
++                 FT_Error  *p_error )
+   {
+-    FT_ASSERT( P != 0 );
++    FT_Error    error = FT_Err_Ok;
++    FT_Pointer  block = NULL;
++
+ 
+     if ( size > 0 )
+     {
+-      *P = memory->alloc( memory, size );
+-      if ( !*P )
+-      {
+-        FT_ERROR(( "FT_QAlloc:" ));
+-        FT_ERROR(( " Out of memory? (%ld requested)\n",
+-                   size ));
+-
+-        return FT_Err_Out_Of_Memory;
++      block = memory->alloc( memory, size );
++      if ( block == NULL )
++        error = FT_Err_Out_Of_Memory;
+       }
++    else if ( size < 0 )
++    {
++      /* may help catch/prevent security issues */
++      error = FT_Err_Invalid_Argument;
+     }
+-    else
+-      *P = NULL;
+-
+-    FT_TRACE7(( "FT_QAlloc:" ));
+-    FT_TRACE7(( " size = %ld, block = 0x%08p, ref = 0x%08p\n",
+-                size, *P, P ));
+ 
+-    return FT_Err_Ok;
++    *p_error = error;
++    return block;
+   }
+ 
+ 
+-  /* documentation is in ftmemory.h */
+-
+-  FT_BASE_DEF( FT_Error )
+-  FT_Realloc( FT_Memory  memory,
+-              FT_Long    current,
+-              FT_Long    size,
+-              void**     P )
++  FT_BASE_DEF( FT_Pointer )
++  ft_mem_realloc( FT_Memory  memory,
++                  FT_Long    item_size,
++                  FT_Long    cur_count,
++                  FT_Long    new_count,
++                  void*      block,
++                  FT_Error  *p_error )
+   {
+-    void*  Q;
+-
++    FT_Error  error = FT_Err_Ok;
+ 
+-    FT_ASSERT( P != 0 );
++    block = ft_mem_qrealloc( memory, item_size,
++                             cur_count, new_count, block, &error );
++    if ( !error && new_count > cur_count )
++      FT_MEM_ZERO( (char*)block + cur_count * item_size,
++                   ( new_count - cur_count ) * item_size );
+ 
+-    /* if the original pointer is NULL, call FT_Alloc() */
+-    if ( !*P )
+-      return FT_Alloc( memory, size, P );
+-
+-    /* if the new block if zero-sized, clear the current one */
+-    if ( size <= 0 )
+-    {
+-      FT_Free( memory, P );
+-      return FT_Err_Ok;
++    *p_error = error;
++    return block;
+     }
+ 
+-    Q = memory->realloc( memory, current, size, *P );
+-    if ( !Q )
+-      goto Fail;
+ 
+-    if ( size > current )
+-      FT_MEM_ZERO( (char*)Q + current, size - current );
++  FT_BASE_DEF( FT_Pointer )
++  ft_mem_qrealloc( FT_Memory  memory,
++                   FT_Long    item_size,
++                   FT_Long    cur_count,
++                   FT_Long    new_count,
++                   void*      block,
++                   FT_Error  *p_error )
++  {
++    FT_Error  error = FT_Err_Ok;
+ 
+-    *P = Q;
+-    return FT_Err_Ok;
+ 
+-  Fail:
+-    FT_ERROR(( "FT_Realloc:" ));
+-    FT_ERROR(( " Failed (current %ld, requested %ld)\n",
+-               current, size ));
+-    return FT_Err_Out_Of_Memory;
++    if ( cur_count < 0 || new_count < 0 || item_size <= 0 )
++    {
++      /* may help catch/prevent nasty security issues */
++      error = FT_Err_Invalid_Argument;
+   }
+-
+-
+-  /* documentation is in ftmemory.h */
+-
+-  FT_BASE_DEF( FT_Error )
+-  FT_QRealloc( FT_Memory  memory,
+-               FT_Long    current,
+-               FT_Long    size,
+-               void**     P )
++    else if ( new_count == 0 )
+   {
+-    void*  Q;
+-
+-
+-    FT_ASSERT( P != 0 );
+-
+-    /* if the original pointer is NULL, call FT_QAlloc() */
+-    if ( !*P )
+-      return FT_QAlloc( memory, size, P );
+-
+-    /* if the new block if zero-sized, clear the current one */
+-    if ( size <= 0 )
++      ft_mem_free( memory, block );
++      block = NULL;
++    }
++    else if ( new_count > FT_INT_MAX/item_size )
+     {
+-      FT_Free( memory, P );
+-      return FT_Err_Ok;
++      error = FT_Err_Array_Too_Large;
+     }
++    else if ( cur_count == 0 )
++    {
++      FT_ASSERT( block == NULL );
+ 
+-    Q = memory->realloc( memory, current, size, *P );
+-    if ( !Q )
+-      goto Fail;
++      block = ft_mem_alloc( memory, new_count*item_size, &error );
++    }
++    else
++    {
++      FT_Pointer  block2;
++      FT_Long     cur_size = cur_count*item_size;
++      FT_Long     new_size = new_count*item_size;
+ 
+-    *P = Q;
+-    return FT_Err_Ok;
+ 
+-  Fail:
+-    FT_ERROR(( "FT_QRealloc:" ));
+-    FT_ERROR(( " Failed (current %ld, requested %ld)\n",
+-               current, size ));
+-    return FT_Err_Out_Of_Memory;
++      block2 = memory->realloc( memory, cur_size, new_size, block );
++      if ( block2 == NULL )
++        error = FT_Err_Out_Of_Memory;
++      else
++        block = block2;
+   }
+ 
++    *p_error = error;
++    return block;
++  }
+ 
+-  /* documentation is in ftmemory.h */
+ 
+   FT_BASE_DEF( void )
+-  FT_Free( FT_Memory  memory,
+-           void**     P )
++  ft_mem_free( FT_Memory   memory,
++               const void *P )
+   {
+-    FT_TRACE7(( "FT_Free:" ));
+-    FT_TRACE7(( " Freeing block 0x%08p, ref 0x%08p\n",
+-                P, P ? *P : (void*)0 ));
+-
+-    if ( P && *P )
+-    {
+-      memory->free( memory, *P );
+-      *P = 0;
+-    }
++    if ( P )
++      memory->free( memory, (void*)P );
+   }
+ 
+ 
+@@ -421,4 +380,70 @@
+   }
+ 
+ 
++#if 1 /* def FT_CONFIG_OPTION_OLD_INTERNALS */
++
++  FT_BASE_DEF( FT_Error )
++  FT_Alloc( FT_Memory  memory,
++            FT_Long    size,
++            void*     *P )
++  {
++    FT_Error  error;
++
++
++    (void)FT_ALLOC( *P, size );
++    return error;
++  }
++
++
++  FT_BASE_DEF( FT_Error )
++  FT_QAlloc( FT_Memory  memory,
++             FT_Long    size,
++             void*     *p )
++  {
++    FT_Error  error;
++
++
++    (void)FT_QALLOC( *p, size );
++    return error;
++  }
++
++
++  FT_BASE_DEF( FT_Error )
++  FT_Realloc( FT_Memory  memory,
++              FT_Long    current,
++              FT_Long    size,
++              void*     *P )
++  {
++    FT_Error  error;
++
++
++    (void)FT_REALLOC( *P, current, size );
++    return error;
++  }
++
++
++  FT_BASE_DEF( FT_Error )
++  FT_QRealloc( FT_Memory  memory,
++               FT_Long    current,
++               FT_Long    size,
++               void*     *p )
++  {
++    FT_Error  error;
++
++
++    (void)FT_QREALLOC( *p, current, size );
++    return error;
++  }
++
++
++  FT_BASE_DEF( void )
++  FT_Free( FT_Memory  memory,
++           void*     *P )
++  {
++    if ( *P )
++      FT_MEM_FREE( *P );
++  }
++
++#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
++
+ /* END */
+diff -urp -x '*~' /src/cache/ftccache.c src/cache/ftccache.c
+--- /src/cache/ftccache.c	2005-05-23 14:24:16.000000000 -0700
++++ src/cache/ftccache.c	2006-05-22 18:30:43.431155000 -0700
+@@ -4,7 +4,7 @@
+ /*                                                                         */
+ /*    The FreeType internal cache interface (body).                        */
+ /*                                                                         */
+-/*  Copyright 2000-2001, 2002, 2003, 2004, 2005 by                         */
++/*  Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006 by                   */
+ /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
+ /*                                                                         */
+ /*  This file is part of the FreeType project, and may only be used,       */
+@@ -100,10 +100,11 @@
+         if ( p >= mask )
+         {
+           FT_Memory  memory = cache->memory;
++          FT_Error   error;
+ 
+ 
+           /* if we can't expand the array, leave immediately */
+-          if ( FT_MEM_RENEW_ARRAY( cache->buckets, (mask+1)*2, (mask+1)*4 ) )
++          if ( FT_RENEW_ARRAY( cache->buckets, (mask+1)*2, (mask+1)*4 ) )
+             break;
+         }
+ 
+@@ -152,10 +153,11 @@
+         if ( p == 0 )
+         {
+           FT_Memory  memory = cache->memory;
++          FT_Error   error;
+ 
+ 
+           /* if we can't shrink the array, leave immediately */
+-          if ( FT_MEM_RENEW_ARRAY( cache->buckets,
++          if ( FT_RENEW_ARRAY( cache->buckets,
+                                    ( mask + 1 ) * 2, mask + 1 ) )
+             break;
+ 
+@@ -312,13 +314,15 @@
+   ftc_cache_init( FTC_Cache  cache )
+   {
+     FT_Memory  memory = cache->memory;
++    FT_Error   error;
+ 
+ 
+     cache->p     = 0;
+     cache->mask  = FTC_HASH_INITIAL_SIZE - 1;
+     cache->slack = FTC_HASH_INITIAL_SIZE * FTC_HASH_MAX_LOAD;
+ 
+-    return ( FT_MEM_NEW_ARRAY( cache->buckets, FTC_HASH_INITIAL_SIZE * 2 ) );
++    (void)FT_NEW_ARRAY( cache->buckets, FTC_HASH_INITIAL_SIZE * 2 );
++    return error;
+   }
+ 
+ 
+diff -urp -x '*~' /src/cff/cffgload.c src/cff/cffgload.c
+--- /src/cff/cffgload.c	2005-04-17 21:53:05.000000000 -0700
++++ src/cff/cffgload.c	2006-05-22 18:30:43.502600000 -0700
+@@ -4,7 +4,7 @@
+ /*                                                                         */
+ /*    OpenType Glyph Loader (body).                                        */
+ /*                                                                         */
+-/*  Copyright 1996-2001, 2002, 2003, 2004, 2005 by                         */
++/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by                   */
+ /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
+ /*                                                                         */
+ /*  This file is part of the FreeType project, and may only be used,       */
+@@ -508,6 +508,9 @@
+     FT_Outline*  outline = builder->current;
+ 
+ 
++    if ( !outline )
++      return;
++
+     /* XXXX: We must not include the last point in the path if it */
+     /*       is located on the first point.                       */
+     if ( outline->n_points > 1 )
+diff -urp -x '*~' /src/cff/cffload.c src/cff/cffload.c
+--- /src/cff/cffload.c	2005-05-05 22:49:46.000000000 -0700
++++ src/cff/cffload.c	2006-05-22 18:30:43.554153000 -0700
+@@ -4,7 +4,7 @@
+ /*                                                                         */
+ /*    OpenType and CFF data/program tables loader (body).                  */
+ /*                                                                         */
+-/*  Copyright 1996-2001, 2002, 2003, 2004, 2005 by                         */
++/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by                   */
+ /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
+ /*                                                                         */
+ /*  This file is part of the FreeType project, and may only be used,       */
+@@ -2293,8 +2293,6 @@
+     {
+       for ( idx = 0; idx < font->num_subfonts; idx++ )
+         cff_subfont_done( memory, font->subfonts[idx] );
+-
+-      FT_FREE( font->subfonts );
+     }
+ 
+     cff_encoding_done( &font->encoding );
+diff -urp -x '*~' /src/gzip/ftgzip.c src/gzip/ftgzip.c
+--- /src/gzip/ftgzip.c	2005-03-15 17:35:17.000000000 -0800
++++ src/gzip/ftgzip.c	2006-05-22 18:30:43.611558000 -0700
+@@ -8,7 +8,7 @@
+ /*  parse compressed PCF fonts, as found with many X11 server              */
+ /*  distributions.                                                         */
+ /*                                                                         */
+-/*  Copyright 2002, 2003, 2004, 2005 by                                    */
++/*  Copyright 2002, 2003, 2004, 2005, 2006 by                              */
+ /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
+ /*                                                                         */
+ /*  This file is part of the FreeType project, and may only be used,       */
+@@ -99,12 +99,12 @@
+                  uInt       size )
+   {
+     FT_ULong    sz = (FT_ULong)size * items;
++    FT_Error    error;
+     FT_Pointer  p;
+ 
+ 
+-    FT_MEM_ALLOC( p, sz );
+-
+-    return (voidpf) p;
++    (void)FT_ALLOC( p, sz );
++    return p;
+   }
+ 
+ 
+diff -urp -x '*~' /src/pcf/pcfdrivr.c src/pcf/pcfdrivr.c
+--- /src/pcf/pcfdrivr.c	2006-05-22 18:30:13.921990000 -0700
++++ src/pcf/pcfdrivr.c	2006-05-22 18:30:43.659876000 -0700
+@@ -2,7 +2,7 @@
+ 
+     FreeType font driver for pcf files
+ 
+-    Copyright (C) 2000, 2001, 2002, 2003, 2004 by
++    Copyright (C) 2000, 2001, 2002, 2003, 2004, 2006 by
+     Francesco Zappa Nardelli
+ 
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+@@ -213,7 +213,7 @@ THE SOFTWARE.
+ 
+         FT_FREE( prop->name );
+         if ( prop->isString )
+-          FT_FREE( prop->value );
++          FT_FREE( prop->value.atom );
+       }
+ 
+       FT_FREE( face->properties );
+diff -urp -x '*~' /src/psaux/psobjs.c src/psaux/psobjs.c
+--- /src/psaux/psobjs.c	2005-02-13 05:39:48.000000000 -0800
++++ src/psaux/psobjs.c	2006-05-22 18:30:43.721504000 -0700
+@@ -4,7 +4,7 @@
+ /*                                                                         */
+ /*    Auxiliary functions for PostScript fonts (body).                     */
+ /*                                                                         */
+-/*  Copyright 1996-2001, 2002, 2003, 2004, 2005 by                         */
++/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by                   */
+ /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
+ /*                                                                         */
+ /*  This file is part of the FreeType project, and may only be used,       */
+@@ -1735,6 +1735,9 @@
+     FT_Outline*  outline = builder->current;
+ 
+ 
++    if ( !outline )
++      return;
++
+     /* XXXX: We must not include the last point in the path if it */
+     /*       is located on the first point.                       */
+     if ( outline->n_points > 1 )
+diff -urp -x '*~' /src/raster/ftrend1.c src/raster/ftrend1.c
+--- /src/raster/ftrend1.c	2005-05-11 08:01:49.000000000 -0700
++++ src/raster/ftrend1.c	2006-05-22 18:30:43.767296000 -0700
+@@ -4,7 +4,7 @@
+ /*                                                                         */
+ /*    The FreeType glyph rasterizer interface (body).                      */
+ /*                                                                         */
+-/*  Copyright 1996-2001, 2002, 2003, 2005 by                               */
++/*  Copyright 1996-2001, 2002, 2003, 2005, 2006 by                         */
+ /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
+ /*                                                                         */
+ /*  This file is part of the FreeType project, and may only be used,       */
+@@ -175,7 +175,7 @@
+     bitmap->rows  = height;
+     bitmap->pitch = pitch;
+ 
+-    if ( FT_ALLOC( bitmap->buffer, (FT_ULong)pitch * height ) )
++    if ( FT_ALLOC_MULT( bitmap->buffer, pitch, height ) )
+       goto Exit;
+ 
+     slot->internal->flags |= FT_GLYPH_OWN_BITMAP;
+diff -urp -x '*~' /src/sfnt/sfobjs.c src/sfnt/sfobjs.c
+--- /src/sfnt/sfobjs.c	2005-05-21 10:22:28.000000000 -0700
++++ src/sfnt/sfobjs.c	2006-05-22 18:30:43.805487000 -0700
+@@ -4,7 +4,7 @@
+ /*                                                                         */
+ /*    SFNT object management (base).                                       */
+ /*                                                                         */
+-/*  Copyright 1996-2001, 2002, 2003, 2004, 2005 by                         */
++/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by                   */
+ /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
+ /*                                                                         */
+ /*  This file is part of the FreeType project, and may only be used,       */
+@@ -47,11 +47,12 @@
+     FT_String*  string;
+     FT_UInt     len, code, n;
+     FT_Byte*    read = (FT_Byte*)entry->string;
++    FT_Error    error;
+ 
+ 
+     len = (FT_UInt)entry->stringLength / 2;
+ 
+-    if ( FT_MEM_NEW_ARRAY( string, len + 1 ) )
++    if ( FT_NEW_ARRAY( string, len + 1 ) )
+       return NULL;
+ 
+     for ( n = 0; n < len; n++ )
+@@ -77,11 +78,12 @@
+     FT_String*  string;
+     FT_UInt     len, code, n;
+     FT_Byte*    read = (FT_Byte*)entry->string;
++    FT_Error    error;
+ 
+ 
+     len = (FT_UInt)entry->stringLength / 4;
+ 
+-    if ( FT_MEM_NEW_ARRAY( string, len + 1 ) )
++    if ( FT_NEW_ARRAY( string, len + 1 ) )
+       return NULL;
+ 
+     for ( n = 0; n < len; n++ )
+@@ -107,11 +109,12 @@
+     FT_String*  string;
+     FT_UInt     len, code, n;
+     FT_Byte*    read = (FT_Byte*)entry->string;
++    FT_Error    error;
+ 
+ 
+     len = (FT_UInt)entry->stringLength;
+ 
+-    if ( FT_MEM_NEW_ARRAY( string, len + 1 ) )
++    if ( FT_NEW_ARRAY( string, len + 1 ) )
+       return NULL;
+ 
+     for ( n = 0; n < len; n++ )
+diff -urp -x '*~' /src/sfnt/ttkern.c src/sfnt/ttkern.c
+--- /src/sfnt/ttkern.c	2005-03-03 03:18:15.000000000 -0800
++++ src/sfnt/ttkern.c	2006-05-22 18:30:43.852113000 -0700
+@@ -5,7 +5,7 @@
+ /*    Load the basic TrueType kerning table.  This doesn't handle          */
+ /*    kerning data within the GPOS table at the moment.                    */
+ /*                                                                         */
+-/*  Copyright 1996-2001, 2002, 2003, 2004, 2005 by                         */
++/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by                   */
+ /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
+ /*                                                                         */
+ /*  This file is part of the FreeType project, and may only be used,       */
+@@ -246,7 +246,10 @@
+           }
+           else /* linear search */
+           {
+-            for ( count = num_pairs; count > 0; count-- )
++            FT_UInt  count2;
++
++
++            for ( count2 = num_pairs; count2 > 0; count2-- )
+             {
+               FT_ULong  key = FT_NEXT_ULONG( p );
+ 
+diff -urp -x '*~' /src/sfnt/ttpost.c src/sfnt/ttpost.c
+--- /src/sfnt/ttpost.c	2003-10-29 13:43:51.000000000 -0800
++++ src/sfnt/ttpost.c	2006-05-22 18:30:43.900919000 -0700
+@@ -5,7 +5,7 @@
+ /*    Postcript name table processing for TrueType and OpenType fonts      */
+ /*    (body).                                                              */
+ /*                                                                         */
+-/*  Copyright 1996-2001, 2002, 2003 by                                     */
++/*  Copyright 1996-2001, 2002, 2003, 2006 by                               */
+ /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
+ /*                                                                         */
+ /*  This file is part of the FreeType project, and may only be used,       */
+@@ -292,7 +292,7 @@
+       goto Exit;
+     }
+ 
+-    if ( FT_ALLOC( offset_table, num_glyphs )       ||
++    if ( FT_NEW_ARRAY( offset_table, num_glyphs )   ||
+          FT_STREAM_READ( offset_table, num_glyphs ) )
+       goto Fail;
+ 
+diff -urp -x '*~' /src/truetype/ttgxvar.c src/truetype/ttgxvar.c
+--- /src/truetype/ttgxvar.c	2005-05-21 22:49:48.000000000 -0700
++++ src/truetype/ttgxvar.c	2006-05-22 18:30:43.946578000 -0700
+@@ -4,7 +4,7 @@
+ /*                                                                         */
+ /*    TrueType GX Font Variation loader                                    */
+ /*                                                                         */
+-/*  Copyright 2004, 2005 by                                                */
++/*  Copyright 2004, 2005, 2006 by                                          */
+ /*  David Turner, Robert Wilhelm, Werner Lemberg, and George Williams.     */
+ /*                                                                         */
+ /*  This file is part of the FreeType project, and may only be used,       */
+@@ -684,7 +684,7 @@
+         goto Exit;
+       }
+ 
+-      if ( FT_ALLOC( face->blend, sizeof ( GX_BlendRec ) ) )
++      if ( FT_NEW( face->blend ) )
+         goto Exit;
+ 
+       face->blend->mmvar_len =
+diff -urp -x '*~' /src/type42/t42parse.c src/type42/t42parse.c
+--- /src/type42/t42parse.c	2005-03-15 16:36:48.000000000 -0800
++++ src/type42/t42parse.c	2006-05-22 18:30:43.997872000 -0700
+@@ -4,7 +4,7 @@
+ /*                                                                         */
+ /*    Type 42 font parser (body).                                          */
+ /*                                                                         */
+-/*  Copyright 2002, 2003, 2004, 2005 by Roberto Alameda.                   */
++/*  Copyright 2002, 2003, 2004, 2005, 2006 by Roberto Alameda.             */
+ /*                                                                         */
+ /*  This file is part of the FreeType project, and may only be used,       */
+ /*  modified, and distributed under the terms of the FreeType project      */
+@@ -623,6 +623,7 @@
+             status         = OTHER_TABLES;
+             face->ttf_size = ttf_size;
+ 
++            /* there are no more than 256 tables, so no size check here */
+             if ( FT_REALLOC( face->ttf_data, 12 + 16 * num_tables,
+                              ttf_size + 1 ) )
+               goto Fail;
+diff -urp -x '*~' /src/winfonts/winfnt.c src/winfonts/winfnt.c
+--- /src/winfonts/winfnt.c	2004-06-15 07:13:10.000000000 -0700
++++ src/winfonts/winfnt.c	2006-05-22 18:30:44.052007000 -0700
+@@ -4,7 +4,7 @@
+ /*                                                                         */
+ /*    FreeType font driver for Windows FNT/FON files                       */
+ /*                                                                         */
+-/*  Copyright 1996-2001, 2002, 2003, 2004 by                               */
++/*  Copyright 1996-2001, 2002, 2003, 2004, 2006 by                         */
+ /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
+ /*                                                                         */
+ /*  This file is part of the FreeType project, and may only be used,       */
+@@ -633,7 +633,7 @@
+ 
+       /* note: since glyphs are stored in columns and not in rows we */
+       /*       can't use ft_glyphslot_set_bitmap                     */
+-      if ( FT_ALLOC( bitmap->buffer, pitch * bitmap->rows ) )
++      if ( FT_ALLOC_MULT( bitmap->buffer, pitch, bitmap->rows ) )
+         goto Exit;
+ 
+       column = (FT_Byte*)bitmap->buffer;
--- a/open-src/lib/freetype/Makefile	Fri May 26 17:51:21 2006 -0700
+++ b/open-src/lib/freetype/Makefile	Tue May 23 13:36:15 2006 -0700
@@ -30,7 +30,7 @@
 # or other dealings in this Software without prior written authorization
 # of the copyright holder.
 #
-# @(#)Makefile	1.60	05/11/21
+# @(#)Makefile	1.61	06/05/22
 #
 
 PWD:sh=pwd
@@ -49,7 +49,7 @@
 SOURCE_URL=http://savannah.nongnu.org/download/freetype/$(SOURCE_TARBALL_NAME)
 
 # Patches to apply to source after unpacking, in order
-SOURCE_PATCHES=freetype-$(FT_VERS).patch
+SOURCE_PATCHES=freetype-$(FT_VERS).patch 6425531.patch
 
 # Directory created by unpacking source
 SOURCE_DIR=$(BUILD_DIR)/freetype-$(FT_VERS)