2001-12-05 02:22:05 +01:00
|
|
|
/***************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* ftdbgmem.c */
|
|
|
|
/* */
|
|
|
|
/* Memory debugger (body). */
|
|
|
|
/* */
|
2009-01-06 07:59:36 +01:00
|
|
|
/* Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2009 by */
|
2001-12-05 02:22:05 +01:00
|
|
|
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
|
|
|
/* */
|
|
|
|
/* This file is part of the FreeType project, and may only be used, */
|
|
|
|
/* modified, and distributed under the terms of the FreeType project */
|
|
|
|
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
|
|
|
|
/* this file you indicate that you have read the license and */
|
|
|
|
/* understand and accept it fully. */
|
|
|
|
/* */
|
|
|
|
/***************************************************************************/
|
|
|
|
|
|
|
|
|
2001-10-22 10:32:21 +02:00
|
|
|
#include <ft2build.h>
|
|
|
|
#include FT_CONFIG_CONFIG_H
|
|
|
|
#include FT_INTERNAL_DEBUG_H
|
2001-10-26 18:58:27 +02:00
|
|
|
#include FT_INTERNAL_MEMORY_H
|
2001-10-22 10:32:21 +02:00
|
|
|
#include FT_SYSTEM_H
|
|
|
|
#include FT_ERRORS_H
|
|
|
|
#include FT_TYPES_H
|
|
|
|
|
2001-12-05 02:22:05 +01:00
|
|
|
|
2001-10-22 10:32:21 +02:00
|
|
|
#ifdef FT_DEBUG_MEMORY
|
|
|
|
|
2005-03-01 03:13:50 +01:00
|
|
|
#define KEEPALIVE /* `Keep alive' means that freed blocks aren't released
|
|
|
|
* to the heap. This is useful to detect double-frees
|
|
|
|
* or weird heap corruption, but it uses large amounts of
|
|
|
|
* memory, however.
|
2005-02-22 16:38:12 +01:00
|
|
|
*/
|
2001-10-22 10:32:21 +02:00
|
|
|
|
2009-01-13 18:34:48 +01:00
|
|
|
#include FT_CONFIG_STANDARD_LIBRARY_H
|
2001-10-22 10:32:21 +02:00
|
|
|
|
* include/freetype/fterrdef.h, include/freetype/config/ftconfig.h,
include/freetype/internal/ftmemory.h, src/base/ftdbgmem.c,
src/base/ftutil.c: udpating the memory management functions and
macros to safely deal with array size buffer overflows, this
corresponds to attemps to allocate arrays that are too large. For
an example, consider the following code:
count = read_uint32_from_file();
array = malloc( sizeof(Item) * count );
for ( nn = 0; nn < count; nn++ )
array[nn] = read_item_from_file();
if 'count' is larger than FT_UINT_MAX/sizeof(Item), the multiplication
will overflow and the array allocated will be smaller than the data
read from the file. In this case, the heap will be trashed, and this
can be used as a denial-of-service, or make the engine crash later.
the FT_ARRAY_NEW and FT_ARRAY_RENEW macro now check that the new
count is no more than FT_INT_MAX/item_size, otherwise, a new error,
named 'FT_Err_Array_Too_Large' will be returned.
note that the memory debugger now works again when FT_DEBUG_MEMORY
is defined, and FT_STRICT_ALIASING has disappeared, the corresponding
code being now the default.
2006-05-02 08:34:27 +02:00
|
|
|
FT_BASE_DEF( const char* ) _ft_debug_file = 0;
|
|
|
|
FT_BASE_DEF( long ) _ft_debug_lineno = 0;
|
2005-03-01 03:13:50 +01:00
|
|
|
|
2005-02-22 16:38:12 +01:00
|
|
|
extern void
|
|
|
|
FT_DumpMemory( FT_Memory memory );
|
2001-10-22 10:32:21 +02:00
|
|
|
|
2005-03-01 03:13:50 +01:00
|
|
|
|
2005-02-22 16:38:12 +01:00
|
|
|
typedef struct FT_MemSourceRec_* FT_MemSource;
|
|
|
|
typedef struct FT_MemNodeRec_* FT_MemNode;
|
|
|
|
typedef struct FT_MemTableRec_* FT_MemTable;
|
2001-10-22 10:32:21 +02:00
|
|
|
|
2005-03-01 03:13:50 +01:00
|
|
|
|
2001-12-05 02:22:05 +01:00
|
|
|
#define FT_MEM_VAL( addr ) ((FT_ULong)(FT_Pointer)( addr ))
|
2001-10-22 10:32:21 +02:00
|
|
|
|
2006-05-03 00:22:16 +02:00
|
|
|
/*
|
|
|
|
* This structure holds statistics for a single allocation/release
|
|
|
|
* site. This is useful to know where memory operations happen the
|
|
|
|
* most.
|
|
|
|
*/
|
2005-10-22 12:43:12 +02:00
|
|
|
typedef struct FT_MemSourceRec_
|
2005-02-22 16:38:12 +01:00
|
|
|
{
|
|
|
|
const char* file_name;
|
|
|
|
long line_no;
|
|
|
|
|
|
|
|
FT_Long cur_blocks; /* current number of allocated blocks */
|
|
|
|
FT_Long max_blocks; /* max. number of allocated blocks */
|
|
|
|
FT_Long all_blocks; /* total number of blocks allocated */
|
|
|
|
|
|
|
|
FT_Long cur_size; /* current cumulative allocated size */
|
|
|
|
FT_Long max_size; /* maximum cumulative allocated size */
|
|
|
|
FT_Long all_size; /* total cumulative allocated size */
|
|
|
|
|
|
|
|
FT_Long cur_max; /* current maximum allocated size */
|
|
|
|
|
|
|
|
FT_UInt32 hash;
|
|
|
|
FT_MemSource link;
|
|
|
|
|
|
|
|
} FT_MemSourceRec;
|
|
|
|
|
2005-03-01 03:13:50 +01:00
|
|
|
|
2005-10-22 12:43:12 +02:00
|
|
|
/*
|
|
|
|
* We don't need a resizable array for the memory sources, because
|
|
|
|
* their number is pretty limited within FreeType.
|
|
|
|
*/
|
2005-03-01 03:13:50 +01:00
|
|
|
#define FT_MEM_SOURCE_BUCKETS 128
|
2005-02-22 16:38:12 +01:00
|
|
|
|
2006-05-03 00:22:16 +02:00
|
|
|
/*
|
|
|
|
* 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.
|
|
|
|
*/
|
2001-12-05 02:22:05 +01:00
|
|
|
typedef struct FT_MemNodeRec_
|
2001-10-22 10:32:21 +02:00
|
|
|
{
|
2005-02-22 16:38:12 +01:00
|
|
|
FT_Byte* address;
|
|
|
|
FT_Long size; /* < 0 if the block was freed */
|
2001-12-05 02:22:05 +01:00
|
|
|
|
2005-02-22 16:38:12 +01:00
|
|
|
FT_MemSource source;
|
2001-12-05 02:22:05 +01:00
|
|
|
|
2005-02-22 16:38:12 +01:00
|
|
|
#ifdef KEEPALIVE
|
|
|
|
const char* free_file_name;
|
|
|
|
FT_Long free_line_no;
|
|
|
|
#endif
|
2001-10-22 16:50:41 +02:00
|
|
|
|
2005-02-22 16:38:12 +01:00
|
|
|
FT_MemNode link;
|
2001-10-22 10:32:21 +02:00
|
|
|
|
2002-03-30 14:16:35 +01:00
|
|
|
} FT_MemNodeRec;
|
2001-12-05 02:22:05 +01:00
|
|
|
|
|
|
|
|
2006-05-03 00:22:16 +02:00
|
|
|
/*
|
|
|
|
* The global structure, containing compound statistics and all hash
|
|
|
|
* tables.
|
|
|
|
*/
|
2001-12-05 02:22:05 +01:00
|
|
|
typedef struct FT_MemTableRec_
|
2001-10-22 10:32:21 +02:00
|
|
|
{
|
2001-12-05 02:22:05 +01:00
|
|
|
FT_ULong size;
|
|
|
|
FT_ULong nodes;
|
|
|
|
FT_MemNode* buckets;
|
2001-10-22 10:32:21 +02:00
|
|
|
|
2001-12-05 02:22:05 +01:00
|
|
|
FT_ULong alloc_total;
|
|
|
|
FT_ULong alloc_current;
|
|
|
|
FT_ULong alloc_max;
|
2003-03-13 22:07:51 +01:00
|
|
|
FT_ULong alloc_count;
|
|
|
|
|
2005-02-22 16:38:12 +01:00
|
|
|
FT_Bool bound_total;
|
2003-03-13 22:07:51 +01:00
|
|
|
FT_ULong alloc_total_max;
|
2005-02-22 16:38:12 +01:00
|
|
|
|
2003-03-13 22:07:51 +01:00
|
|
|
FT_Bool bound_count;
|
|
|
|
FT_ULong alloc_count_max;
|
2001-10-24 09:32:55 +02:00
|
|
|
|
2005-03-01 03:13:50 +01:00
|
|
|
FT_MemSource sources[FT_MEM_SOURCE_BUCKETS];
|
2005-02-22 16:38:12 +01:00
|
|
|
|
|
|
|
FT_Bool keep_alive;
|
|
|
|
|
2001-12-05 02:22:05 +01:00
|
|
|
FT_Memory memory;
|
2002-03-30 14:16:35 +01:00
|
|
|
FT_Pointer memory_user;
|
2001-10-24 09:32:55 +02:00
|
|
|
FT_Alloc_Func alloc;
|
|
|
|
FT_Free_Func free;
|
|
|
|
FT_Realloc_Func realloc;
|
2001-10-22 10:32:21 +02:00
|
|
|
|
2002-03-30 14:16:35 +01:00
|
|
|
} FT_MemTableRec;
|
2001-12-05 02:22:05 +01:00
|
|
|
|
|
|
|
|
|
|
|
#define FT_MEM_SIZE_MIN 7
|
|
|
|
#define FT_MEM_SIZE_MAX 13845163
|
|
|
|
|
|
|
|
#define FT_FILENAME( x ) ((x) ? (x) : "unknown file")
|
2001-10-22 10:32:21 +02:00
|
|
|
|
2001-10-24 10:04:00 +02:00
|
|
|
|
2005-10-22 12:43:12 +02:00
|
|
|
/*
|
|
|
|
* Prime numbers are ugly to handle. It would be better to implement
|
|
|
|
* L-Hashing, which is 10% faster and doesn't require divisions.
|
|
|
|
*/
|
2001-10-22 10:32:21 +02:00
|
|
|
static const FT_UInt ft_mem_primes[] =
|
|
|
|
{
|
|
|
|
7,
|
|
|
|
11,
|
|
|
|
19,
|
|
|
|
37,
|
|
|
|
73,
|
|
|
|
109,
|
|
|
|
163,
|
|
|
|
251,
|
|
|
|
367,
|
|
|
|
557,
|
|
|
|
823,
|
|
|
|
1237,
|
|
|
|
1861,
|
|
|
|
2777,
|
|
|
|
4177,
|
|
|
|
6247,
|
|
|
|
9371,
|
|
|
|
14057,
|
|
|
|
21089,
|
|
|
|
31627,
|
|
|
|
47431,
|
|
|
|
71143,
|
|
|
|
106721,
|
|
|
|
160073,
|
|
|
|
240101,
|
|
|
|
360163,
|
|
|
|
540217,
|
|
|
|
810343,
|
|
|
|
1215497,
|
|
|
|
1823231,
|
|
|
|
2734867,
|
|
|
|
4102283,
|
|
|
|
6153409,
|
|
|
|
9230113,
|
|
|
|
13845163,
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2005-02-22 16:38:12 +01:00
|
|
|
static FT_ULong
|
|
|
|
ft_mem_closest_prime( FT_ULong num )
|
|
|
|
{
|
|
|
|
FT_UInt i;
|
|
|
|
|
|
|
|
|
|
|
|
for ( i = 0;
|
|
|
|
i < sizeof ( ft_mem_primes ) / sizeof ( ft_mem_primes[0] ); i++ )
|
|
|
|
if ( ft_mem_primes[i] > num )
|
|
|
|
return ft_mem_primes[i];
|
|
|
|
|
|
|
|
return FT_MEM_SIZE_MAX;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-10-22 10:32:21 +02:00
|
|
|
extern void
|
2005-03-01 03:13:50 +01:00
|
|
|
ft_mem_debug_panic( const char* fmt,
|
|
|
|
... )
|
2001-10-22 10:32:21 +02:00
|
|
|
{
|
|
|
|
va_list ap;
|
|
|
|
|
|
|
|
|
2001-10-24 10:04:00 +02:00
|
|
|
printf( "FreeType.Debug: " );
|
2001-10-22 10:32:21 +02:00
|
|
|
|
|
|
|
va_start( ap, fmt );
|
|
|
|
vprintf( fmt, ap );
|
|
|
|
va_end( ap );
|
|
|
|
|
|
|
|
printf( "\n" );
|
|
|
|
exit( EXIT_FAILURE );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-10-24 09:32:55 +02:00
|
|
|
static FT_Pointer
|
|
|
|
ft_mem_table_alloc( FT_MemTable table,
|
|
|
|
FT_Long size )
|
|
|
|
{
|
|
|
|
FT_Memory memory = table->memory;
|
|
|
|
FT_Pointer block;
|
2001-12-14 15:52:58 +01:00
|
|
|
|
2001-12-05 02:22:05 +01:00
|
|
|
|
2001-10-24 09:32:55 +02:00
|
|
|
memory->user = table->memory_user;
|
|
|
|
block = table->alloc( memory, size );
|
|
|
|
memory->user = table;
|
2001-12-05 02:22:05 +01:00
|
|
|
|
2005-10-22 12:43:12 +02:00
|
|
|
return block;
|
2001-10-24 09:32:55 +02:00
|
|
|
}
|
|
|
|
|
2001-12-05 02:22:05 +01:00
|
|
|
|
2001-10-24 09:32:55 +02:00
|
|
|
static void
|
|
|
|
ft_mem_table_free( FT_MemTable table,
|
|
|
|
FT_Pointer block )
|
|
|
|
{
|
|
|
|
FT_Memory memory = table->memory;
|
2001-12-14 15:52:58 +01:00
|
|
|
|
2001-12-05 02:22:05 +01:00
|
|
|
|
2001-10-24 09:32:55 +02:00
|
|
|
memory->user = table->memory_user;
|
|
|
|
table->free( memory, block );
|
|
|
|
memory->user = table;
|
|
|
|
}
|
|
|
|
|
2001-10-22 10:32:21 +02:00
|
|
|
|
|
|
|
static void
|
|
|
|
ft_mem_table_resize( FT_MemTable table )
|
|
|
|
{
|
|
|
|
FT_ULong new_size;
|
|
|
|
|
2001-12-05 02:22:05 +01:00
|
|
|
|
2001-10-22 10:32:21 +02:00
|
|
|
new_size = ft_mem_closest_prime( table->nodes );
|
2001-12-05 02:22:05 +01:00
|
|
|
if ( new_size != table->size )
|
2001-10-22 10:32:21 +02:00
|
|
|
{
|
2005-03-01 03:13:50 +01:00
|
|
|
FT_MemNode* new_buckets;
|
2001-10-22 10:32:21 +02:00
|
|
|
FT_ULong i;
|
|
|
|
|
2001-12-05 02:22:05 +01:00
|
|
|
|
* src/base/ftdbgmem.c (ft_mem_table_resize, ft_mem_table_new,
ft_mem_table_set, ft_mem_debug_alloc, ft_mem_debug_free,
ft_mem_debug_realloc, ft_mem_debug_done, FT_Alloc_Debug,
FT_Realloc_Debug, FT_Free_Debug): Fix compiler warnings.
* src/base/ftcalc.c (FT_MulFix): Ditto.
* src/cff/cffdrivr.c (cff_get_name_index): Ditto.
* src/cff/cffobjs.c (CFF_Size_Get_Global_Funcs, CFF_Size_Init,
CFF_GlyphSlot_Init): Ditto.
* src/cid/cidobjs.c (CID_GlyphSlot_Init,
CID_Size_Get_Globals_Funcs): Ditto.
* src/type1/t1objs.c (T1_Size_Get_Globals_Funcs, T1_GlyphSlot_Init):
Ditto.
* src/pshinter/pshmod.c (pshinter_interface): Use `static const'.
* src/winfonts/winfnt.c (FNT_Get_Next_Char): Remove unused
variables.
* include/freetype/internal/psaux.h (T1_Builder_Funcs): Renamed
to...
(T1_Builder_FuncsRec): This.
(T1_Builder_Funcs): New typedef.
(PSAux_Interface): Remove compiler warnings.
* src/psaux/psauxmod.c (t1_builder_funcs), src/psaux/psobjs.h
(t1_builder_funcs): Updated.
* src/pshinter/pshglob.h (PSH_Blue_Align): Replaced with ...
(PSH_BLUE_ALIGN_{NONE,TOP,BOT}): New defines.
(PSH_AlignmentRec): Updated.
* include/freetype/internal/ftstream.h (GET_Char, GET_Byte): Fix
typo.
* include/freetype/internal/ftgloadr.h (FT_SubGlyph): Ditto.
* src/base/ftstream (FT_Get_Char): Rename to...
(FT_Stream_Get_Char): This.
* src/base/ftnames.c (FT_Get_Sfnt_Name): s/index/idx/ -- `index' is
a built-in function in gcc, causing warning messages with gcc 3.0.
* src/autohint/ahglyph.c (ah_outline_load): Ditto.
* src/autohint/ahglobal.c (ah_hinter_compute_blues): Ditto.
* src/cache/ftcmanag.c (ftc_family_table_alloc,
ftc_family_table_free, FTC_Manager_Done, FTC_Manager_Register_Cache):
Ditto.
* src/cff/cffload.c (cff_new_index, cff_done_index,
cff_explicit_index, CFF_Access_Element, CFF_Forget_Element,
CFF_Get_Name, CFF_Get_String, CFF_Load_SubFont, CFF_Load_Font,
CFF_Done_Font): Ditto.
* src/psaux/psobjs.c (PS_Table_Add, PS_Parser_LoadField): Ditto.
* src/psaux/t1decode.c (T1_Decoder_Parse_Charstrings): Ditto.
* src/pshinter/pshrec.c (ps_mask_test_bit, ps_mask_clear_bit,
ps_mask_set_bit, ps_dimension_add_t1stem, ps_hints_t1stem3,
* src/pshinter/pshalgo1.c (psh1_hint_table_record,
psh1_hint_table_record_mask, psh1_hint_table_activate_mask): Ditto.
* src/pshinter/pshalgo2.c (psh2_hint_table_record,
psh2_hint_table_record_mask, psh2_hint_table_activate_mask): Ditto.
* src/sfnt/ttpost.c (Load_Format_20, Load_Format_25,
TT_Get_PS_Name): Ditto.
* src/truetype/ttgload.c (TT_Get_Metrics, Get_HMetrics,
load_truetype_glyph): Ditto.
* src/type1/t1load.c (parse_subrs, T1_Open_Face): Ditto.
* src/type1/t1afm.c (T1_Get_Kerning): Ditto.
* include/freetype/cache/ftcmanag.h (ftc_family_table_free): Ditto.
2002-03-07 22:59:59 +01:00
|
|
|
new_buckets = (FT_MemNode *)
|
2005-03-01 03:13:50 +01:00
|
|
|
ft_mem_table_alloc( table,
|
|
|
|
new_size * sizeof ( FT_MemNode ) );
|
2001-10-22 10:32:21 +02:00
|
|
|
if ( new_buckets == NULL )
|
|
|
|
return;
|
2001-12-05 02:22:05 +01:00
|
|
|
|
2005-02-22 16:38:12 +01:00
|
|
|
FT_ARRAY_ZERO( new_buckets, new_size );
|
2001-12-05 02:22:05 +01:00
|
|
|
|
2001-10-22 10:32:21 +02:00
|
|
|
for ( i = 0; i < table->size; i++ )
|
|
|
|
{
|
|
|
|
FT_MemNode node, next, *pnode;
|
|
|
|
FT_ULong hash;
|
|
|
|
|
2001-12-05 02:22:05 +01:00
|
|
|
|
2001-10-22 10:32:21 +02:00
|
|
|
node = table->buckets[i];
|
2001-12-05 02:22:05 +01:00
|
|
|
while ( node )
|
2001-10-22 10:32:21 +02:00
|
|
|
{
|
|
|
|
next = node->link;
|
2001-12-05 02:22:05 +01:00
|
|
|
hash = FT_MEM_VAL( node->address ) % new_size;
|
2001-10-22 10:32:21 +02:00
|
|
|
pnode = new_buckets + hash;
|
|
|
|
|
|
|
|
node->link = pnode[0];
|
|
|
|
pnode[0] = node;
|
|
|
|
|
2001-12-05 02:22:05 +01:00
|
|
|
node = next;
|
2001-10-22 10:32:21 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( table->buckets )
|
2001-10-24 09:32:55 +02:00
|
|
|
ft_mem_table_free( table, table->buckets );
|
2001-12-05 02:22:05 +01:00
|
|
|
|
2001-10-22 10:32:21 +02:00
|
|
|
table->buckets = new_buckets;
|
|
|
|
table->size = new_size;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static FT_MemTable
|
2001-10-24 09:32:55 +02:00
|
|
|
ft_mem_table_new( FT_Memory memory )
|
2001-10-22 10:32:21 +02:00
|
|
|
{
|
|
|
|
FT_MemTable table;
|
|
|
|
|
2001-12-05 02:22:05 +01:00
|
|
|
|
* src/base/ftdbgmem.c (ft_mem_table_resize, ft_mem_table_new,
ft_mem_table_set, ft_mem_debug_alloc, ft_mem_debug_free,
ft_mem_debug_realloc, ft_mem_debug_done, FT_Alloc_Debug,
FT_Realloc_Debug, FT_Free_Debug): Fix compiler warnings.
* src/base/ftcalc.c (FT_MulFix): Ditto.
* src/cff/cffdrivr.c (cff_get_name_index): Ditto.
* src/cff/cffobjs.c (CFF_Size_Get_Global_Funcs, CFF_Size_Init,
CFF_GlyphSlot_Init): Ditto.
* src/cid/cidobjs.c (CID_GlyphSlot_Init,
CID_Size_Get_Globals_Funcs): Ditto.
* src/type1/t1objs.c (T1_Size_Get_Globals_Funcs, T1_GlyphSlot_Init):
Ditto.
* src/pshinter/pshmod.c (pshinter_interface): Use `static const'.
* src/winfonts/winfnt.c (FNT_Get_Next_Char): Remove unused
variables.
* include/freetype/internal/psaux.h (T1_Builder_Funcs): Renamed
to...
(T1_Builder_FuncsRec): This.
(T1_Builder_Funcs): New typedef.
(PSAux_Interface): Remove compiler warnings.
* src/psaux/psauxmod.c (t1_builder_funcs), src/psaux/psobjs.h
(t1_builder_funcs): Updated.
* src/pshinter/pshglob.h (PSH_Blue_Align): Replaced with ...
(PSH_BLUE_ALIGN_{NONE,TOP,BOT}): New defines.
(PSH_AlignmentRec): Updated.
* include/freetype/internal/ftstream.h (GET_Char, GET_Byte): Fix
typo.
* include/freetype/internal/ftgloadr.h (FT_SubGlyph): Ditto.
* src/base/ftstream (FT_Get_Char): Rename to...
(FT_Stream_Get_Char): This.
* src/base/ftnames.c (FT_Get_Sfnt_Name): s/index/idx/ -- `index' is
a built-in function in gcc, causing warning messages with gcc 3.0.
* src/autohint/ahglyph.c (ah_outline_load): Ditto.
* src/autohint/ahglobal.c (ah_hinter_compute_blues): Ditto.
* src/cache/ftcmanag.c (ftc_family_table_alloc,
ftc_family_table_free, FTC_Manager_Done, FTC_Manager_Register_Cache):
Ditto.
* src/cff/cffload.c (cff_new_index, cff_done_index,
cff_explicit_index, CFF_Access_Element, CFF_Forget_Element,
CFF_Get_Name, CFF_Get_String, CFF_Load_SubFont, CFF_Load_Font,
CFF_Done_Font): Ditto.
* src/psaux/psobjs.c (PS_Table_Add, PS_Parser_LoadField): Ditto.
* src/psaux/t1decode.c (T1_Decoder_Parse_Charstrings): Ditto.
* src/pshinter/pshrec.c (ps_mask_test_bit, ps_mask_clear_bit,
ps_mask_set_bit, ps_dimension_add_t1stem, ps_hints_t1stem3,
* src/pshinter/pshalgo1.c (psh1_hint_table_record,
psh1_hint_table_record_mask, psh1_hint_table_activate_mask): Ditto.
* src/pshinter/pshalgo2.c (psh2_hint_table_record,
psh2_hint_table_record_mask, psh2_hint_table_activate_mask): Ditto.
* src/sfnt/ttpost.c (Load_Format_20, Load_Format_25,
TT_Get_PS_Name): Ditto.
* src/truetype/ttgload.c (TT_Get_Metrics, Get_HMetrics,
load_truetype_glyph): Ditto.
* src/type1/t1load.c (parse_subrs, T1_Open_Face): Ditto.
* src/type1/t1afm.c (T1_Get_Kerning): Ditto.
* include/freetype/cache/ftcmanag.h (ftc_family_table_free): Ditto.
2002-03-07 22:59:59 +01:00
|
|
|
table = (FT_MemTable)memory->alloc( memory, sizeof ( *table ) );
|
2001-12-05 02:22:05 +01:00
|
|
|
if ( table == NULL )
|
|
|
|
goto Exit;
|
|
|
|
|
2005-02-22 16:38:12 +01:00
|
|
|
FT_ZERO( table );
|
2001-10-22 10:32:21 +02:00
|
|
|
|
|
|
|
table->size = FT_MEM_SIZE_MIN;
|
|
|
|
table->nodes = 0;
|
2001-12-05 02:22:05 +01:00
|
|
|
|
|
|
|
table->memory = memory;
|
2001-10-22 10:32:21 +02:00
|
|
|
|
2001-10-24 09:32:55 +02:00
|
|
|
table->memory_user = memory->user;
|
2001-12-05 02:22:05 +01:00
|
|
|
|
2001-10-24 09:32:55 +02:00
|
|
|
table->alloc = memory->alloc;
|
|
|
|
table->realloc = memory->realloc;
|
|
|
|
table->free = memory->free;
|
|
|
|
|
* src/base/ftdbgmem.c (ft_mem_table_resize, ft_mem_table_new,
ft_mem_table_set, ft_mem_debug_alloc, ft_mem_debug_free,
ft_mem_debug_realloc, ft_mem_debug_done, FT_Alloc_Debug,
FT_Realloc_Debug, FT_Free_Debug): Fix compiler warnings.
* src/base/ftcalc.c (FT_MulFix): Ditto.
* src/cff/cffdrivr.c (cff_get_name_index): Ditto.
* src/cff/cffobjs.c (CFF_Size_Get_Global_Funcs, CFF_Size_Init,
CFF_GlyphSlot_Init): Ditto.
* src/cid/cidobjs.c (CID_GlyphSlot_Init,
CID_Size_Get_Globals_Funcs): Ditto.
* src/type1/t1objs.c (T1_Size_Get_Globals_Funcs, T1_GlyphSlot_Init):
Ditto.
* src/pshinter/pshmod.c (pshinter_interface): Use `static const'.
* src/winfonts/winfnt.c (FNT_Get_Next_Char): Remove unused
variables.
* include/freetype/internal/psaux.h (T1_Builder_Funcs): Renamed
to...
(T1_Builder_FuncsRec): This.
(T1_Builder_Funcs): New typedef.
(PSAux_Interface): Remove compiler warnings.
* src/psaux/psauxmod.c (t1_builder_funcs), src/psaux/psobjs.h
(t1_builder_funcs): Updated.
* src/pshinter/pshglob.h (PSH_Blue_Align): Replaced with ...
(PSH_BLUE_ALIGN_{NONE,TOP,BOT}): New defines.
(PSH_AlignmentRec): Updated.
* include/freetype/internal/ftstream.h (GET_Char, GET_Byte): Fix
typo.
* include/freetype/internal/ftgloadr.h (FT_SubGlyph): Ditto.
* src/base/ftstream (FT_Get_Char): Rename to...
(FT_Stream_Get_Char): This.
* src/base/ftnames.c (FT_Get_Sfnt_Name): s/index/idx/ -- `index' is
a built-in function in gcc, causing warning messages with gcc 3.0.
* src/autohint/ahglyph.c (ah_outline_load): Ditto.
* src/autohint/ahglobal.c (ah_hinter_compute_blues): Ditto.
* src/cache/ftcmanag.c (ftc_family_table_alloc,
ftc_family_table_free, FTC_Manager_Done, FTC_Manager_Register_Cache):
Ditto.
* src/cff/cffload.c (cff_new_index, cff_done_index,
cff_explicit_index, CFF_Access_Element, CFF_Forget_Element,
CFF_Get_Name, CFF_Get_String, CFF_Load_SubFont, CFF_Load_Font,
CFF_Done_Font): Ditto.
* src/psaux/psobjs.c (PS_Table_Add, PS_Parser_LoadField): Ditto.
* src/psaux/t1decode.c (T1_Decoder_Parse_Charstrings): Ditto.
* src/pshinter/pshrec.c (ps_mask_test_bit, ps_mask_clear_bit,
ps_mask_set_bit, ps_dimension_add_t1stem, ps_hints_t1stem3,
* src/pshinter/pshalgo1.c (psh1_hint_table_record,
psh1_hint_table_record_mask, psh1_hint_table_activate_mask): Ditto.
* src/pshinter/pshalgo2.c (psh2_hint_table_record,
psh2_hint_table_record_mask, psh2_hint_table_activate_mask): Ditto.
* src/sfnt/ttpost.c (Load_Format_20, Load_Format_25,
TT_Get_PS_Name): Ditto.
* src/truetype/ttgload.c (TT_Get_Metrics, Get_HMetrics,
load_truetype_glyph): Ditto.
* src/type1/t1load.c (parse_subrs, T1_Open_Face): Ditto.
* src/type1/t1afm.c (T1_Get_Kerning): Ditto.
* include/freetype/cache/ftcmanag.h (ftc_family_table_free): Ditto.
2002-03-07 22:59:59 +01:00
|
|
|
table->buckets = (FT_MemNode *)
|
2005-03-01 03:13:50 +01:00
|
|
|
memory->alloc( memory,
|
|
|
|
table->size * sizeof ( FT_MemNode ) );
|
2001-10-22 10:32:21 +02:00
|
|
|
if ( table->buckets )
|
2005-02-22 16:38:12 +01:00
|
|
|
FT_ARRAY_ZERO( table->buckets, table->size );
|
2001-10-22 10:32:21 +02:00
|
|
|
else
|
|
|
|
{
|
2001-10-24 09:32:55 +02:00
|
|
|
memory->free( memory, table );
|
2001-10-22 10:32:21 +02:00
|
|
|
table = NULL;
|
|
|
|
}
|
2001-12-05 02:22:05 +01:00
|
|
|
|
2002-03-30 14:16:35 +01:00
|
|
|
Exit:
|
2001-10-22 10:32:21 +02:00
|
|
|
return table;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
ft_mem_table_destroy( FT_MemTable table )
|
|
|
|
{
|
2001-12-05 02:22:05 +01:00
|
|
|
FT_ULong i;
|
|
|
|
|
2005-03-01 03:13:50 +01:00
|
|
|
|
2005-02-22 16:38:12 +01:00
|
|
|
FT_DumpMemory( table->memory );
|
2001-10-22 10:32:21 +02:00
|
|
|
|
|
|
|
if ( table )
|
|
|
|
{
|
2005-10-22 12:43:12 +02:00
|
|
|
FT_Long leak_count = 0;
|
|
|
|
FT_ULong leaks = 0;
|
|
|
|
|
2001-12-05 02:22:05 +01:00
|
|
|
|
2005-03-01 03:13:50 +01:00
|
|
|
/* remove all blocks from the table, revealing leaked ones */
|
2001-10-22 10:32:21 +02:00
|
|
|
for ( i = 0; i < table->size; i++ )
|
|
|
|
{
|
|
|
|
FT_MemNode *pnode = table->buckets + i, next, node = *pnode;
|
|
|
|
|
2001-12-05 02:22:05 +01:00
|
|
|
|
|
|
|
while ( node )
|
2001-10-22 10:32:21 +02:00
|
|
|
{
|
2001-12-05 02:22:05 +01:00
|
|
|
next = node->link;
|
|
|
|
node->link = 0;
|
|
|
|
|
2001-10-22 10:32:21 +02:00
|
|
|
if ( node->size > 0 )
|
|
|
|
{
|
2001-12-14 15:52:58 +01:00
|
|
|
printf(
|
2001-12-05 02:22:05 +01:00
|
|
|
"leaked memory block at address %p, size %8ld in (%s:%ld)\n",
|
|
|
|
node->address, node->size,
|
2005-02-22 16:38:12 +01:00
|
|
|
FT_FILENAME( node->source->file_name ),
|
|
|
|
node->source->line_no );
|
2001-12-05 02:22:05 +01:00
|
|
|
|
2001-10-22 10:32:21 +02:00
|
|
|
leak_count++;
|
|
|
|
leaks += node->size;
|
2001-12-05 02:22:05 +01:00
|
|
|
|
2001-10-24 09:32:55 +02:00
|
|
|
ft_mem_table_free( table, node->address );
|
2001-10-22 10:32:21 +02:00
|
|
|
}
|
2001-12-05 02:22:05 +01:00
|
|
|
|
2001-10-22 10:32:21 +02:00
|
|
|
node->address = NULL;
|
|
|
|
node->size = 0;
|
2001-12-05 02:22:05 +01:00
|
|
|
|
2005-02-22 16:38:12 +01:00
|
|
|
ft_mem_table_free( table, node );
|
2001-10-22 10:32:21 +02:00
|
|
|
node = next;
|
|
|
|
}
|
|
|
|
table->buckets[i] = 0;
|
|
|
|
}
|
2005-03-01 03:13:50 +01:00
|
|
|
|
2001-10-24 09:32:55 +02:00
|
|
|
ft_mem_table_free( table, table->buckets );
|
2001-10-22 10:32:21 +02:00
|
|
|
table->buckets = NULL;
|
|
|
|
|
2005-10-22 12:43:12 +02:00
|
|
|
table->size = 0;
|
|
|
|
table->nodes = 0;
|
2001-10-22 22:15:29 +02:00
|
|
|
|
2005-03-01 03:13:50 +01:00
|
|
|
/* remove all sources */
|
2005-02-22 16:38:12 +01:00
|
|
|
for ( i = 0; i < FT_MEM_SOURCE_BUCKETS; i++ )
|
|
|
|
{
|
|
|
|
FT_MemSource source, next;
|
|
|
|
|
2005-03-01 03:13:50 +01:00
|
|
|
|
2005-02-22 16:38:12 +01:00
|
|
|
for ( source = table->sources[i]; source != NULL; source = next )
|
|
|
|
{
|
|
|
|
next = source->link;
|
|
|
|
ft_mem_table_free( table, source );
|
|
|
|
}
|
|
|
|
|
|
|
|
table->sources[i] = NULL;
|
|
|
|
}
|
|
|
|
|
2001-12-05 02:22:05 +01:00
|
|
|
printf(
|
|
|
|
"FreeType: total memory allocations = %ld\n", table->alloc_total );
|
|
|
|
printf(
|
|
|
|
"FreeType: maximum memory footprint = %ld\n", table->alloc_max );
|
|
|
|
|
2005-02-22 16:38:12 +01:00
|
|
|
ft_mem_table_free( table, table );
|
2002-03-20 16:37:12 +01:00
|
|
|
|
2001-10-22 10:32:21 +02:00
|
|
|
if ( leak_count > 0 )
|
2001-12-05 02:22:05 +01:00
|
|
|
ft_mem_debug_panic(
|
|
|
|
"FreeType: %ld bytes of memory leaked in %ld blocks\n",
|
|
|
|
leaks, leak_count );
|
2005-02-22 16:38:12 +01:00
|
|
|
|
2009-06-26 06:15:41 +02:00
|
|
|
printf( "FreeType: no memory leaks detected\n" );
|
2001-10-22 10:32:21 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static FT_MemNode*
|
|
|
|
ft_mem_table_get_nodep( FT_MemTable table,
|
2001-12-05 02:22:05 +01:00
|
|
|
FT_Byte* address )
|
2001-10-22 10:32:21 +02:00
|
|
|
{
|
2001-12-05 02:22:05 +01:00
|
|
|
FT_ULong hash;
|
|
|
|
FT_MemNode *pnode, node;
|
2001-10-22 10:32:21 +02:00
|
|
|
|
2001-12-05 02:22:05 +01:00
|
|
|
|
|
|
|
hash = FT_MEM_VAL( address );
|
|
|
|
pnode = table->buckets + ( hash % table->size );
|
2001-10-22 10:32:21 +02:00
|
|
|
|
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
node = pnode[0];
|
2001-12-05 02:22:05 +01:00
|
|
|
if ( !node )
|
2001-10-22 10:32:21 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
if ( node->address == address )
|
|
|
|
break;
|
|
|
|
|
|
|
|
pnode = &node->link;
|
|
|
|
}
|
|
|
|
return pnode;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-02-22 16:38:12 +01:00
|
|
|
static FT_MemSource
|
|
|
|
ft_mem_table_get_source( FT_MemTable table )
|
|
|
|
{
|
|
|
|
FT_UInt32 hash;
|
|
|
|
FT_MemSource node, *pnode;
|
|
|
|
|
2005-03-01 03:13:50 +01:00
|
|
|
|
2006-08-27 13:26:18 +02:00
|
|
|
/* cast to FT_PtrDist first since void* can be larger */
|
|
|
|
/* than FT_UInt32 and GCC 4.1.1 emits a warning */
|
|
|
|
hash = (FT_UInt32)(FT_PtrDist)(void*)_ft_debug_file +
|
* include/freetype/fterrdef.h, include/freetype/config/ftconfig.h,
include/freetype/internal/ftmemory.h, src/base/ftdbgmem.c,
src/base/ftutil.c: udpating the memory management functions and
macros to safely deal with array size buffer overflows, this
corresponds to attemps to allocate arrays that are too large. For
an example, consider the following code:
count = read_uint32_from_file();
array = malloc( sizeof(Item) * count );
for ( nn = 0; nn < count; nn++ )
array[nn] = read_item_from_file();
if 'count' is larger than FT_UINT_MAX/sizeof(Item), the multiplication
will overflow and the array allocated will be smaller than the data
read from the file. In this case, the heap will be trashed, and this
can be used as a denial-of-service, or make the engine crash later.
the FT_ARRAY_NEW and FT_ARRAY_RENEW macro now check that the new
count is no more than FT_INT_MAX/item_size, otherwise, a new error,
named 'FT_Err_Array_Too_Large' will be returned.
note that the memory debugger now works again when FT_DEBUG_MEMORY
is defined, and FT_STRICT_ALIASING has disappeared, the corresponding
code being now the default.
2006-05-02 08:34:27 +02:00
|
|
|
(FT_UInt32)( 5 * _ft_debug_lineno );
|
2005-03-01 03:13:50 +01:00
|
|
|
pnode = &table->sources[hash % FT_MEM_SOURCE_BUCKETS];
|
|
|
|
|
2005-02-22 16:38:12 +01:00
|
|
|
for ( ;; )
|
|
|
|
{
|
|
|
|
node = *pnode;
|
|
|
|
if ( node == NULL )
|
|
|
|
break;
|
|
|
|
|
* include/freetype/fterrdef.h, include/freetype/config/ftconfig.h,
include/freetype/internal/ftmemory.h, src/base/ftdbgmem.c,
src/base/ftutil.c: udpating the memory management functions and
macros to safely deal with array size buffer overflows, this
corresponds to attemps to allocate arrays that are too large. For
an example, consider the following code:
count = read_uint32_from_file();
array = malloc( sizeof(Item) * count );
for ( nn = 0; nn < count; nn++ )
array[nn] = read_item_from_file();
if 'count' is larger than FT_UINT_MAX/sizeof(Item), the multiplication
will overflow and the array allocated will be smaller than the data
read from the file. In this case, the heap will be trashed, and this
can be used as a denial-of-service, or make the engine crash later.
the FT_ARRAY_NEW and FT_ARRAY_RENEW macro now check that the new
count is no more than FT_INT_MAX/item_size, otherwise, a new error,
named 'FT_Err_Array_Too_Large' will be returned.
note that the memory debugger now works again when FT_DEBUG_MEMORY
is defined, and FT_STRICT_ALIASING has disappeared, the corresponding
code being now the default.
2006-05-02 08:34:27 +02:00
|
|
|
if ( node->file_name == _ft_debug_file &&
|
|
|
|
node->line_no == _ft_debug_lineno )
|
2005-02-22 16:38:12 +01:00
|
|
|
goto Exit;
|
|
|
|
|
|
|
|
pnode = &node->link;
|
|
|
|
}
|
|
|
|
|
2005-03-03 18:09:08 +01:00
|
|
|
node = (FT_MemSource)ft_mem_table_alloc( table, sizeof ( *node ) );
|
2005-02-22 16:38:12 +01:00
|
|
|
if ( node == NULL )
|
|
|
|
ft_mem_debug_panic(
|
|
|
|
"not enough memory to perform memory debugging\n" );
|
|
|
|
|
* include/freetype/fterrdef.h, include/freetype/config/ftconfig.h,
include/freetype/internal/ftmemory.h, src/base/ftdbgmem.c,
src/base/ftutil.c: udpating the memory management functions and
macros to safely deal with array size buffer overflows, this
corresponds to attemps to allocate arrays that are too large. For
an example, consider the following code:
count = read_uint32_from_file();
array = malloc( sizeof(Item) * count );
for ( nn = 0; nn < count; nn++ )
array[nn] = read_item_from_file();
if 'count' is larger than FT_UINT_MAX/sizeof(Item), the multiplication
will overflow and the array allocated will be smaller than the data
read from the file. In this case, the heap will be trashed, and this
can be used as a denial-of-service, or make the engine crash later.
the FT_ARRAY_NEW and FT_ARRAY_RENEW macro now check that the new
count is no more than FT_INT_MAX/item_size, otherwise, a new error,
named 'FT_Err_Array_Too_Large' will be returned.
note that the memory debugger now works again when FT_DEBUG_MEMORY
is defined, and FT_STRICT_ALIASING has disappeared, the corresponding
code being now the default.
2006-05-02 08:34:27 +02:00
|
|
|
node->file_name = _ft_debug_file;
|
|
|
|
node->line_no = _ft_debug_lineno;
|
2005-02-22 16:38:12 +01:00
|
|
|
|
|
|
|
node->cur_blocks = 0;
|
|
|
|
node->max_blocks = 0;
|
|
|
|
node->all_blocks = 0;
|
|
|
|
|
|
|
|
node->cur_size = 0;
|
|
|
|
node->max_size = 0;
|
|
|
|
node->all_size = 0;
|
|
|
|
|
|
|
|
node->cur_max = 0;
|
|
|
|
|
|
|
|
node->link = NULL;
|
|
|
|
node->hash = hash;
|
|
|
|
*pnode = node;
|
|
|
|
|
|
|
|
Exit:
|
|
|
|
return node;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-10-22 10:32:21 +02:00
|
|
|
static void
|
|
|
|
ft_mem_table_set( FT_MemTable table,
|
|
|
|
FT_Byte* address,
|
2005-10-20 17:33:34 +02:00
|
|
|
FT_ULong size,
|
|
|
|
FT_Long delta )
|
2001-10-22 10:32:21 +02:00
|
|
|
{
|
|
|
|
FT_MemNode *pnode, node;
|
|
|
|
|
2001-12-05 02:22:05 +01:00
|
|
|
|
|
|
|
if ( table )
|
2001-10-22 10:32:21 +02:00
|
|
|
{
|
2005-02-22 16:38:12 +01:00
|
|
|
FT_MemSource source;
|
|
|
|
|
2005-03-01 03:13:50 +01:00
|
|
|
|
2001-10-22 10:32:21 +02:00
|
|
|
pnode = ft_mem_table_get_nodep( table, address );
|
|
|
|
node = *pnode;
|
2001-12-05 02:22:05 +01:00
|
|
|
if ( node )
|
2001-10-22 10:32:21 +02:00
|
|
|
{
|
|
|
|
if ( node->size < 0 )
|
|
|
|
{
|
2005-03-01 03:13:50 +01:00
|
|
|
/* This block was already freed. Our memory is now completely */
|
|
|
|
/* corrupted! */
|
|
|
|
/* This can only happen in keep-alive mode. */
|
2001-12-05 02:22:05 +01:00
|
|
|
ft_mem_debug_panic(
|
|
|
|
"memory heap corrupted (allocating freed block)" );
|
2001-10-22 10:32:21 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2005-03-01 03:13:50 +01:00
|
|
|
/* This block was already allocated. This means that our memory */
|
2001-12-05 02:22:05 +01:00
|
|
|
/* is also corrupted! */
|
|
|
|
ft_mem_debug_panic(
|
2005-02-22 16:38:12 +01:00
|
|
|
"memory heap corrupted (re-allocating allocated block at"
|
|
|
|
" %p, of size %ld)\n"
|
|
|
|
"org=%s:%d new=%s:%d\n",
|
|
|
|
node->address, node->size,
|
|
|
|
FT_FILENAME( node->source->file_name ), node->source->line_no,
|
* include/freetype/fterrdef.h, include/freetype/config/ftconfig.h,
include/freetype/internal/ftmemory.h, src/base/ftdbgmem.c,
src/base/ftutil.c: udpating the memory management functions and
macros to safely deal with array size buffer overflows, this
corresponds to attemps to allocate arrays that are too large. For
an example, consider the following code:
count = read_uint32_from_file();
array = malloc( sizeof(Item) * count );
for ( nn = 0; nn < count; nn++ )
array[nn] = read_item_from_file();
if 'count' is larger than FT_UINT_MAX/sizeof(Item), the multiplication
will overflow and the array allocated will be smaller than the data
read from the file. In this case, the heap will be trashed, and this
can be used as a denial-of-service, or make the engine crash later.
the FT_ARRAY_NEW and FT_ARRAY_RENEW macro now check that the new
count is no more than FT_INT_MAX/item_size, otherwise, a new error,
named 'FT_Err_Array_Too_Large' will be returned.
note that the memory debugger now works again when FT_DEBUG_MEMORY
is defined, and FT_STRICT_ALIASING has disappeared, the corresponding
code being now the default.
2006-05-02 08:34:27 +02:00
|
|
|
FT_FILENAME( _ft_debug_file ), _ft_debug_lineno );
|
2001-10-22 10:32:21 +02:00
|
|
|
}
|
|
|
|
}
|
2001-12-05 02:22:05 +01:00
|
|
|
|
2001-10-22 10:32:21 +02:00
|
|
|
/* we need to create a new node in this table */
|
* src/base/ftdbgmem.c (ft_mem_table_resize, ft_mem_table_new,
ft_mem_table_set, ft_mem_debug_alloc, ft_mem_debug_free,
ft_mem_debug_realloc, ft_mem_debug_done, FT_Alloc_Debug,
FT_Realloc_Debug, FT_Free_Debug): Fix compiler warnings.
* src/base/ftcalc.c (FT_MulFix): Ditto.
* src/cff/cffdrivr.c (cff_get_name_index): Ditto.
* src/cff/cffobjs.c (CFF_Size_Get_Global_Funcs, CFF_Size_Init,
CFF_GlyphSlot_Init): Ditto.
* src/cid/cidobjs.c (CID_GlyphSlot_Init,
CID_Size_Get_Globals_Funcs): Ditto.
* src/type1/t1objs.c (T1_Size_Get_Globals_Funcs, T1_GlyphSlot_Init):
Ditto.
* src/pshinter/pshmod.c (pshinter_interface): Use `static const'.
* src/winfonts/winfnt.c (FNT_Get_Next_Char): Remove unused
variables.
* include/freetype/internal/psaux.h (T1_Builder_Funcs): Renamed
to...
(T1_Builder_FuncsRec): This.
(T1_Builder_Funcs): New typedef.
(PSAux_Interface): Remove compiler warnings.
* src/psaux/psauxmod.c (t1_builder_funcs), src/psaux/psobjs.h
(t1_builder_funcs): Updated.
* src/pshinter/pshglob.h (PSH_Blue_Align): Replaced with ...
(PSH_BLUE_ALIGN_{NONE,TOP,BOT}): New defines.
(PSH_AlignmentRec): Updated.
* include/freetype/internal/ftstream.h (GET_Char, GET_Byte): Fix
typo.
* include/freetype/internal/ftgloadr.h (FT_SubGlyph): Ditto.
* src/base/ftstream (FT_Get_Char): Rename to...
(FT_Stream_Get_Char): This.
* src/base/ftnames.c (FT_Get_Sfnt_Name): s/index/idx/ -- `index' is
a built-in function in gcc, causing warning messages with gcc 3.0.
* src/autohint/ahglyph.c (ah_outline_load): Ditto.
* src/autohint/ahglobal.c (ah_hinter_compute_blues): Ditto.
* src/cache/ftcmanag.c (ftc_family_table_alloc,
ftc_family_table_free, FTC_Manager_Done, FTC_Manager_Register_Cache):
Ditto.
* src/cff/cffload.c (cff_new_index, cff_done_index,
cff_explicit_index, CFF_Access_Element, CFF_Forget_Element,
CFF_Get_Name, CFF_Get_String, CFF_Load_SubFont, CFF_Load_Font,
CFF_Done_Font): Ditto.
* src/psaux/psobjs.c (PS_Table_Add, PS_Parser_LoadField): Ditto.
* src/psaux/t1decode.c (T1_Decoder_Parse_Charstrings): Ditto.
* src/pshinter/pshrec.c (ps_mask_test_bit, ps_mask_clear_bit,
ps_mask_set_bit, ps_dimension_add_t1stem, ps_hints_t1stem3,
* src/pshinter/pshalgo1.c (psh1_hint_table_record,
psh1_hint_table_record_mask, psh1_hint_table_activate_mask): Ditto.
* src/pshinter/pshalgo2.c (psh2_hint_table_record,
psh2_hint_table_record_mask, psh2_hint_table_activate_mask): Ditto.
* src/sfnt/ttpost.c (Load_Format_20, Load_Format_25,
TT_Get_PS_Name): Ditto.
* src/truetype/ttgload.c (TT_Get_Metrics, Get_HMetrics,
load_truetype_glyph): Ditto.
* src/type1/t1load.c (parse_subrs, T1_Open_Face): Ditto.
* src/type1/t1afm.c (T1_Get_Kerning): Ditto.
* include/freetype/cache/ftcmanag.h (ftc_family_table_free): Ditto.
2002-03-07 22:59:59 +01:00
|
|
|
node = (FT_MemNode)ft_mem_table_alloc( table, sizeof ( *node ) );
|
2001-10-22 10:32:21 +02:00
|
|
|
if ( node == NULL )
|
|
|
|
ft_mem_debug_panic( "not enough memory to run memory tests" );
|
|
|
|
|
2001-12-05 02:22:05 +01:00
|
|
|
node->address = address;
|
|
|
|
node->size = size;
|
2005-10-20 17:33:34 +02:00
|
|
|
node->source = source = ft_mem_table_get_source( table );
|
2001-10-22 16:50:41 +02:00
|
|
|
|
2005-10-20 17:33:34 +02:00
|
|
|
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;
|
|
|
|
}
|
2005-02-22 16:38:12 +01:00
|
|
|
|
2005-02-26 01:12:04 +01:00
|
|
|
if ( size > (FT_ULong)source->cur_max )
|
2005-02-22 16:38:12 +01:00
|
|
|
source->cur_max = size;
|
|
|
|
|
2005-10-20 17:33:34 +02:00
|
|
|
if ( delta != 0 )
|
|
|
|
{
|
2005-10-22 12:43:12 +02:00
|
|
|
/* we are growing or shrinking a reallocated block */
|
2005-10-21 12:01:25 +02:00
|
|
|
source->cur_size += delta;
|
|
|
|
table->alloc_current += delta;
|
2005-10-20 17:33:34 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2005-10-22 12:43:12 +02:00
|
|
|
/* we are allocating a new block */
|
2005-10-21 12:01:25 +02:00
|
|
|
source->cur_size += size;
|
|
|
|
table->alloc_current += size;
|
2005-10-20 17:33:34 +02:00
|
|
|
}
|
|
|
|
|
2005-02-22 16:38:12 +01:00
|
|
|
source->all_size += size;
|
2005-10-20 17:33:34 +02:00
|
|
|
|
2005-02-22 16:38:12 +01:00
|
|
|
if ( source->cur_size > source->max_size )
|
|
|
|
source->max_size = source->cur_size;
|
2001-10-24 10:04:00 +02:00
|
|
|
|
2001-12-05 02:22:05 +01:00
|
|
|
node->free_file_name = NULL;
|
|
|
|
node->free_line_no = 0;
|
2001-10-22 16:50:41 +02:00
|
|
|
|
2001-12-05 02:22:05 +01:00
|
|
|
node->link = pnode[0];
|
2001-10-22 10:32:21 +02:00
|
|
|
|
|
|
|
pnode[0] = node;
|
|
|
|
table->nodes++;
|
|
|
|
|
2005-10-21 12:01:25 +02:00
|
|
|
table->alloc_total += size;
|
|
|
|
|
2001-10-22 22:15:29 +02:00
|
|
|
if ( table->alloc_current > table->alloc_max )
|
|
|
|
table->alloc_max = table->alloc_current;
|
2001-10-22 10:32:21 +02:00
|
|
|
|
2001-12-05 02:22:05 +01:00
|
|
|
if ( table->nodes * 3 < table->size ||
|
|
|
|
table->size * 3 < table->nodes )
|
2001-10-22 10:32:21 +02:00
|
|
|
ft_mem_table_resize( table );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
ft_mem_table_remove( FT_MemTable table,
|
2005-10-20 17:33:34 +02:00
|
|
|
FT_Byte* address,
|
|
|
|
FT_Long delta )
|
2001-10-22 10:32:21 +02:00
|
|
|
{
|
2001-12-05 02:22:05 +01:00
|
|
|
if ( table )
|
2001-10-22 10:32:21 +02:00
|
|
|
{
|
|
|
|
FT_MemNode *pnode, node;
|
|
|
|
|
2001-12-05 02:22:05 +01:00
|
|
|
|
2001-10-22 10:32:21 +02:00
|
|
|
pnode = ft_mem_table_get_nodep( table, address );
|
|
|
|
node = *pnode;
|
2001-12-05 02:22:05 +01:00
|
|
|
if ( node )
|
2001-10-22 10:32:21 +02:00
|
|
|
{
|
2005-02-22 16:38:12 +01:00
|
|
|
FT_MemSource source;
|
|
|
|
|
2005-03-01 03:13:50 +01:00
|
|
|
|
2001-10-22 10:32:21 +02:00
|
|
|
if ( node->size < 0 )
|
2001-12-05 02:22:05 +01:00
|
|
|
ft_mem_debug_panic(
|
|
|
|
"freeing memory block at %p more than once at (%s:%ld)\n"
|
|
|
|
"block allocated at (%s:%ld) and released at (%s:%ld)",
|
|
|
|
address,
|
* include/freetype/fterrdef.h, include/freetype/config/ftconfig.h,
include/freetype/internal/ftmemory.h, src/base/ftdbgmem.c,
src/base/ftutil.c: udpating the memory management functions and
macros to safely deal with array size buffer overflows, this
corresponds to attemps to allocate arrays that are too large. For
an example, consider the following code:
count = read_uint32_from_file();
array = malloc( sizeof(Item) * count );
for ( nn = 0; nn < count; nn++ )
array[nn] = read_item_from_file();
if 'count' is larger than FT_UINT_MAX/sizeof(Item), the multiplication
will overflow and the array allocated will be smaller than the data
read from the file. In this case, the heap will be trashed, and this
can be used as a denial-of-service, or make the engine crash later.
the FT_ARRAY_NEW and FT_ARRAY_RENEW macro now check that the new
count is no more than FT_INT_MAX/item_size, otherwise, a new error,
named 'FT_Err_Array_Too_Large' will be returned.
note that the memory debugger now works again when FT_DEBUG_MEMORY
is defined, and FT_STRICT_ALIASING has disappeared, the corresponding
code being now the default.
2006-05-02 08:34:27 +02:00
|
|
|
FT_FILENAME( _ft_debug_file ), _ft_debug_lineno,
|
2005-02-22 16:38:12 +01:00
|
|
|
FT_FILENAME( node->source->file_name ), node->source->line_no,
|
2001-12-05 02:22:05 +01:00
|
|
|
FT_FILENAME( node->free_file_name ), node->free_line_no );
|
|
|
|
|
2005-03-01 03:13:50 +01:00
|
|
|
/* scramble the node's content for additional safety */
|
2002-03-22 14:52:37 +01:00
|
|
|
FT_MEM_SET( address, 0xF3, node->size );
|
2005-02-22 16:38:12 +01:00
|
|
|
|
2005-10-20 17:33:34 +02:00
|
|
|
if ( delta == 0 )
|
|
|
|
{
|
|
|
|
source = node->source;
|
|
|
|
|
|
|
|
source->cur_blocks--;
|
|
|
|
source->cur_size -= node->size;
|
2005-02-22 16:38:12 +01:00
|
|
|
|
2005-10-20 17:33:34 +02:00
|
|
|
table->alloc_current -= node->size;
|
|
|
|
}
|
2005-02-22 16:38:12 +01:00
|
|
|
|
|
|
|
if ( table->keep_alive )
|
|
|
|
{
|
|
|
|
/* we simply invert the node's size to indicate that the node */
|
|
|
|
/* was freed. */
|
2005-03-01 03:13:50 +01:00
|
|
|
node->size = -node->size;
|
* include/freetype/fterrdef.h, include/freetype/config/ftconfig.h,
include/freetype/internal/ftmemory.h, src/base/ftdbgmem.c,
src/base/ftutil.c: udpating the memory management functions and
macros to safely deal with array size buffer overflows, this
corresponds to attemps to allocate arrays that are too large. For
an example, consider the following code:
count = read_uint32_from_file();
array = malloc( sizeof(Item) * count );
for ( nn = 0; nn < count; nn++ )
array[nn] = read_item_from_file();
if 'count' is larger than FT_UINT_MAX/sizeof(Item), the multiplication
will overflow and the array allocated will be smaller than the data
read from the file. In this case, the heap will be trashed, and this
can be used as a denial-of-service, or make the engine crash later.
the FT_ARRAY_NEW and FT_ARRAY_RENEW macro now check that the new
count is no more than FT_INT_MAX/item_size, otherwise, a new error,
named 'FT_Err_Array_Too_Large' will be returned.
note that the memory debugger now works again when FT_DEBUG_MEMORY
is defined, and FT_STRICT_ALIASING has disappeared, the corresponding
code being now the default.
2006-05-02 08:34:27 +02:00
|
|
|
node->free_file_name = _ft_debug_file;
|
|
|
|
node->free_line_no = _ft_debug_lineno;
|
2005-02-22 16:38:12 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2005-03-01 03:13:50 +01:00
|
|
|
table->nodes--;
|
2005-02-22 16:38:12 +01:00
|
|
|
|
|
|
|
*pnode = node->link;
|
|
|
|
|
|
|
|
node->size = 0;
|
|
|
|
node->source = NULL;
|
|
|
|
|
|
|
|
ft_mem_table_free( table, node );
|
|
|
|
|
|
|
|
if ( table->nodes * 3 < table->size ||
|
|
|
|
table->size * 3 < table->nodes )
|
|
|
|
ft_mem_table_resize( table );
|
|
|
|
}
|
2001-10-22 10:32:21 +02:00
|
|
|
}
|
|
|
|
else
|
2001-12-05 02:22:05 +01:00
|
|
|
ft_mem_debug_panic(
|
|
|
|
"trying to free unknown block at %p in (%s:%ld)\n",
|
|
|
|
address,
|
* include/freetype/fterrdef.h, include/freetype/config/ftconfig.h,
include/freetype/internal/ftmemory.h, src/base/ftdbgmem.c,
src/base/ftutil.c: udpating the memory management functions and
macros to safely deal with array size buffer overflows, this
corresponds to attemps to allocate arrays that are too large. For
an example, consider the following code:
count = read_uint32_from_file();
array = malloc( sizeof(Item) * count );
for ( nn = 0; nn < count; nn++ )
array[nn] = read_item_from_file();
if 'count' is larger than FT_UINT_MAX/sizeof(Item), the multiplication
will overflow and the array allocated will be smaller than the data
read from the file. In this case, the heap will be trashed, and this
can be used as a denial-of-service, or make the engine crash later.
the FT_ARRAY_NEW and FT_ARRAY_RENEW macro now check that the new
count is no more than FT_INT_MAX/item_size, otherwise, a new error,
named 'FT_Err_Array_Too_Large' will be returned.
note that the memory debugger now works again when FT_DEBUG_MEMORY
is defined, and FT_STRICT_ALIASING has disappeared, the corresponding
code being now the default.
2006-05-02 08:34:27 +02:00
|
|
|
FT_FILENAME( _ft_debug_file ), _ft_debug_lineno );
|
2001-10-22 10:32:21 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
extern FT_Pointer
|
|
|
|
ft_mem_debug_alloc( FT_Memory memory,
|
|
|
|
FT_Long size )
|
|
|
|
{
|
* src/base/ftdbgmem.c (ft_mem_table_resize, ft_mem_table_new,
ft_mem_table_set, ft_mem_debug_alloc, ft_mem_debug_free,
ft_mem_debug_realloc, ft_mem_debug_done, FT_Alloc_Debug,
FT_Realloc_Debug, FT_Free_Debug): Fix compiler warnings.
* src/base/ftcalc.c (FT_MulFix): Ditto.
* src/cff/cffdrivr.c (cff_get_name_index): Ditto.
* src/cff/cffobjs.c (CFF_Size_Get_Global_Funcs, CFF_Size_Init,
CFF_GlyphSlot_Init): Ditto.
* src/cid/cidobjs.c (CID_GlyphSlot_Init,
CID_Size_Get_Globals_Funcs): Ditto.
* src/type1/t1objs.c (T1_Size_Get_Globals_Funcs, T1_GlyphSlot_Init):
Ditto.
* src/pshinter/pshmod.c (pshinter_interface): Use `static const'.
* src/winfonts/winfnt.c (FNT_Get_Next_Char): Remove unused
variables.
* include/freetype/internal/psaux.h (T1_Builder_Funcs): Renamed
to...
(T1_Builder_FuncsRec): This.
(T1_Builder_Funcs): New typedef.
(PSAux_Interface): Remove compiler warnings.
* src/psaux/psauxmod.c (t1_builder_funcs), src/psaux/psobjs.h
(t1_builder_funcs): Updated.
* src/pshinter/pshglob.h (PSH_Blue_Align): Replaced with ...
(PSH_BLUE_ALIGN_{NONE,TOP,BOT}): New defines.
(PSH_AlignmentRec): Updated.
* include/freetype/internal/ftstream.h (GET_Char, GET_Byte): Fix
typo.
* include/freetype/internal/ftgloadr.h (FT_SubGlyph): Ditto.
* src/base/ftstream (FT_Get_Char): Rename to...
(FT_Stream_Get_Char): This.
* src/base/ftnames.c (FT_Get_Sfnt_Name): s/index/idx/ -- `index' is
a built-in function in gcc, causing warning messages with gcc 3.0.
* src/autohint/ahglyph.c (ah_outline_load): Ditto.
* src/autohint/ahglobal.c (ah_hinter_compute_blues): Ditto.
* src/cache/ftcmanag.c (ftc_family_table_alloc,
ftc_family_table_free, FTC_Manager_Done, FTC_Manager_Register_Cache):
Ditto.
* src/cff/cffload.c (cff_new_index, cff_done_index,
cff_explicit_index, CFF_Access_Element, CFF_Forget_Element,
CFF_Get_Name, CFF_Get_String, CFF_Load_SubFont, CFF_Load_Font,
CFF_Done_Font): Ditto.
* src/psaux/psobjs.c (PS_Table_Add, PS_Parser_LoadField): Ditto.
* src/psaux/t1decode.c (T1_Decoder_Parse_Charstrings): Ditto.
* src/pshinter/pshrec.c (ps_mask_test_bit, ps_mask_clear_bit,
ps_mask_set_bit, ps_dimension_add_t1stem, ps_hints_t1stem3,
* src/pshinter/pshalgo1.c (psh1_hint_table_record,
psh1_hint_table_record_mask, psh1_hint_table_activate_mask): Ditto.
* src/pshinter/pshalgo2.c (psh2_hint_table_record,
psh2_hint_table_record_mask, psh2_hint_table_activate_mask): Ditto.
* src/sfnt/ttpost.c (Load_Format_20, Load_Format_25,
TT_Get_PS_Name): Ditto.
* src/truetype/ttgload.c (TT_Get_Metrics, Get_HMetrics,
load_truetype_glyph): Ditto.
* src/type1/t1load.c (parse_subrs, T1_Open_Face): Ditto.
* src/type1/t1afm.c (T1_Get_Kerning): Ditto.
* include/freetype/cache/ftcmanag.h (ftc_family_table_free): Ditto.
2002-03-07 22:59:59 +01:00
|
|
|
FT_MemTable table = (FT_MemTable)memory->user;
|
2001-10-22 10:32:21 +02:00
|
|
|
FT_Byte* block;
|
|
|
|
|
2001-12-05 02:22:05 +01:00
|
|
|
|
2001-10-22 10:32:21 +02:00
|
|
|
if ( size <= 0 )
|
|
|
|
ft_mem_debug_panic( "negative block size allocation (%ld)", size );
|
2001-12-05 02:22:05 +01:00
|
|
|
|
2003-03-13 22:07:51 +01:00
|
|
|
/* return NULL if the maximum number of allocations was reached */
|
2005-03-01 03:13:50 +01:00
|
|
|
if ( table->bound_count &&
|
2003-03-13 22:07:51 +01:00
|
|
|
table->alloc_count >= table->alloc_count_max )
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
/* return NULL if this allocation would overflow the maximum heap size */
|
2005-03-01 03:13:50 +01:00
|
|
|
if ( table->bound_total &&
|
* include/freetype/fterrdef.h, include/freetype/config/ftconfig.h,
include/freetype/internal/ftmemory.h, src/base/ftdbgmem.c,
src/base/ftutil.c: udpating the memory management functions and
macros to safely deal with array size buffer overflows, this
corresponds to attemps to allocate arrays that are too large. For
an example, consider the following code:
count = read_uint32_from_file();
array = malloc( sizeof(Item) * count );
for ( nn = 0; nn < count; nn++ )
array[nn] = read_item_from_file();
if 'count' is larger than FT_UINT_MAX/sizeof(Item), the multiplication
will overflow and the array allocated will be smaller than the data
read from the file. In this case, the heap will be trashed, and this
can be used as a denial-of-service, or make the engine crash later.
the FT_ARRAY_NEW and FT_ARRAY_RENEW macro now check that the new
count is no more than FT_INT_MAX/item_size, otherwise, a new error,
named 'FT_Err_Array_Too_Large' will be returned.
note that the memory debugger now works again when FT_DEBUG_MEMORY
is defined, and FT_STRICT_ALIASING has disappeared, the corresponding
code being now the default.
2006-05-02 08:34:27 +02:00
|
|
|
table->alloc_total_max - table->alloc_current > (FT_ULong)size )
|
2005-02-22 16:38:12 +01:00
|
|
|
return NULL;
|
2003-03-13 22:07:51 +01:00
|
|
|
|
* src/base/ftdbgmem.c (ft_mem_table_resize, ft_mem_table_new,
ft_mem_table_set, ft_mem_debug_alloc, ft_mem_debug_free,
ft_mem_debug_realloc, ft_mem_debug_done, FT_Alloc_Debug,
FT_Realloc_Debug, FT_Free_Debug): Fix compiler warnings.
* src/base/ftcalc.c (FT_MulFix): Ditto.
* src/cff/cffdrivr.c (cff_get_name_index): Ditto.
* src/cff/cffobjs.c (CFF_Size_Get_Global_Funcs, CFF_Size_Init,
CFF_GlyphSlot_Init): Ditto.
* src/cid/cidobjs.c (CID_GlyphSlot_Init,
CID_Size_Get_Globals_Funcs): Ditto.
* src/type1/t1objs.c (T1_Size_Get_Globals_Funcs, T1_GlyphSlot_Init):
Ditto.
* src/pshinter/pshmod.c (pshinter_interface): Use `static const'.
* src/winfonts/winfnt.c (FNT_Get_Next_Char): Remove unused
variables.
* include/freetype/internal/psaux.h (T1_Builder_Funcs): Renamed
to...
(T1_Builder_FuncsRec): This.
(T1_Builder_Funcs): New typedef.
(PSAux_Interface): Remove compiler warnings.
* src/psaux/psauxmod.c (t1_builder_funcs), src/psaux/psobjs.h
(t1_builder_funcs): Updated.
* src/pshinter/pshglob.h (PSH_Blue_Align): Replaced with ...
(PSH_BLUE_ALIGN_{NONE,TOP,BOT}): New defines.
(PSH_AlignmentRec): Updated.
* include/freetype/internal/ftstream.h (GET_Char, GET_Byte): Fix
typo.
* include/freetype/internal/ftgloadr.h (FT_SubGlyph): Ditto.
* src/base/ftstream (FT_Get_Char): Rename to...
(FT_Stream_Get_Char): This.
* src/base/ftnames.c (FT_Get_Sfnt_Name): s/index/idx/ -- `index' is
a built-in function in gcc, causing warning messages with gcc 3.0.
* src/autohint/ahglyph.c (ah_outline_load): Ditto.
* src/autohint/ahglobal.c (ah_hinter_compute_blues): Ditto.
* src/cache/ftcmanag.c (ftc_family_table_alloc,
ftc_family_table_free, FTC_Manager_Done, FTC_Manager_Register_Cache):
Ditto.
* src/cff/cffload.c (cff_new_index, cff_done_index,
cff_explicit_index, CFF_Access_Element, CFF_Forget_Element,
CFF_Get_Name, CFF_Get_String, CFF_Load_SubFont, CFF_Load_Font,
CFF_Done_Font): Ditto.
* src/psaux/psobjs.c (PS_Table_Add, PS_Parser_LoadField): Ditto.
* src/psaux/t1decode.c (T1_Decoder_Parse_Charstrings): Ditto.
* src/pshinter/pshrec.c (ps_mask_test_bit, ps_mask_clear_bit,
ps_mask_set_bit, ps_dimension_add_t1stem, ps_hints_t1stem3,
* src/pshinter/pshalgo1.c (psh1_hint_table_record,
psh1_hint_table_record_mask, psh1_hint_table_activate_mask): Ditto.
* src/pshinter/pshalgo2.c (psh2_hint_table_record,
psh2_hint_table_record_mask, psh2_hint_table_activate_mask): Ditto.
* src/sfnt/ttpost.c (Load_Format_20, Load_Format_25,
TT_Get_PS_Name): Ditto.
* src/truetype/ttgload.c (TT_Get_Metrics, Get_HMetrics,
load_truetype_glyph): Ditto.
* src/type1/t1load.c (parse_subrs, T1_Open_Face): Ditto.
* src/type1/t1afm.c (T1_Get_Kerning): Ditto.
* include/freetype/cache/ftcmanag.h (ftc_family_table_free): Ditto.
2002-03-07 22:59:59 +01:00
|
|
|
block = (FT_Byte *)ft_mem_table_alloc( table, size );
|
2001-10-22 10:32:21 +02:00
|
|
|
if ( block )
|
2005-10-20 17:33:34 +02:00
|
|
|
{
|
|
|
|
ft_mem_table_set( table, block, (FT_ULong)size, 0 );
|
2001-10-24 10:04:00 +02:00
|
|
|
|
2005-10-20 17:33:34 +02:00
|
|
|
table->alloc_count++;
|
|
|
|
}
|
2003-03-13 22:07:51 +01:00
|
|
|
|
* include/freetype/fterrdef.h, include/freetype/config/ftconfig.h,
include/freetype/internal/ftmemory.h, src/base/ftdbgmem.c,
src/base/ftutil.c: udpating the memory management functions and
macros to safely deal with array size buffer overflows, this
corresponds to attemps to allocate arrays that are too large. For
an example, consider the following code:
count = read_uint32_from_file();
array = malloc( sizeof(Item) * count );
for ( nn = 0; nn < count; nn++ )
array[nn] = read_item_from_file();
if 'count' is larger than FT_UINT_MAX/sizeof(Item), the multiplication
will overflow and the array allocated will be smaller than the data
read from the file. In this case, the heap will be trashed, and this
can be used as a denial-of-service, or make the engine crash later.
the FT_ARRAY_NEW and FT_ARRAY_RENEW macro now check that the new
count is no more than FT_INT_MAX/item_size, otherwise, a new error,
named 'FT_Err_Array_Too_Large' will be returned.
note that the memory debugger now works again when FT_DEBUG_MEMORY
is defined, and FT_STRICT_ALIASING has disappeared, the corresponding
code being now the default.
2006-05-02 08:34:27 +02:00
|
|
|
_ft_debug_file = "<unknown>";
|
|
|
|
_ft_debug_lineno = 0;
|
2001-12-05 02:22:05 +01:00
|
|
|
|
2005-03-01 03:13:50 +01:00
|
|
|
return (FT_Pointer)block;
|
2001-10-22 10:32:21 +02:00
|
|
|
}
|
2001-12-14 15:52:58 +01:00
|
|
|
|
2001-10-22 10:32:21 +02:00
|
|
|
|
|
|
|
extern void
|
|
|
|
ft_mem_debug_free( FT_Memory memory,
|
|
|
|
FT_Pointer block )
|
|
|
|
{
|
* src/base/ftdbgmem.c (ft_mem_table_resize, ft_mem_table_new,
ft_mem_table_set, ft_mem_debug_alloc, ft_mem_debug_free,
ft_mem_debug_realloc, ft_mem_debug_done, FT_Alloc_Debug,
FT_Realloc_Debug, FT_Free_Debug): Fix compiler warnings.
* src/base/ftcalc.c (FT_MulFix): Ditto.
* src/cff/cffdrivr.c (cff_get_name_index): Ditto.
* src/cff/cffobjs.c (CFF_Size_Get_Global_Funcs, CFF_Size_Init,
CFF_GlyphSlot_Init): Ditto.
* src/cid/cidobjs.c (CID_GlyphSlot_Init,
CID_Size_Get_Globals_Funcs): Ditto.
* src/type1/t1objs.c (T1_Size_Get_Globals_Funcs, T1_GlyphSlot_Init):
Ditto.
* src/pshinter/pshmod.c (pshinter_interface): Use `static const'.
* src/winfonts/winfnt.c (FNT_Get_Next_Char): Remove unused
variables.
* include/freetype/internal/psaux.h (T1_Builder_Funcs): Renamed
to...
(T1_Builder_FuncsRec): This.
(T1_Builder_Funcs): New typedef.
(PSAux_Interface): Remove compiler warnings.
* src/psaux/psauxmod.c (t1_builder_funcs), src/psaux/psobjs.h
(t1_builder_funcs): Updated.
* src/pshinter/pshglob.h (PSH_Blue_Align): Replaced with ...
(PSH_BLUE_ALIGN_{NONE,TOP,BOT}): New defines.
(PSH_AlignmentRec): Updated.
* include/freetype/internal/ftstream.h (GET_Char, GET_Byte): Fix
typo.
* include/freetype/internal/ftgloadr.h (FT_SubGlyph): Ditto.
* src/base/ftstream (FT_Get_Char): Rename to...
(FT_Stream_Get_Char): This.
* src/base/ftnames.c (FT_Get_Sfnt_Name): s/index/idx/ -- `index' is
a built-in function in gcc, causing warning messages with gcc 3.0.
* src/autohint/ahglyph.c (ah_outline_load): Ditto.
* src/autohint/ahglobal.c (ah_hinter_compute_blues): Ditto.
* src/cache/ftcmanag.c (ftc_family_table_alloc,
ftc_family_table_free, FTC_Manager_Done, FTC_Manager_Register_Cache):
Ditto.
* src/cff/cffload.c (cff_new_index, cff_done_index,
cff_explicit_index, CFF_Access_Element, CFF_Forget_Element,
CFF_Get_Name, CFF_Get_String, CFF_Load_SubFont, CFF_Load_Font,
CFF_Done_Font): Ditto.
* src/psaux/psobjs.c (PS_Table_Add, PS_Parser_LoadField): Ditto.
* src/psaux/t1decode.c (T1_Decoder_Parse_Charstrings): Ditto.
* src/pshinter/pshrec.c (ps_mask_test_bit, ps_mask_clear_bit,
ps_mask_set_bit, ps_dimension_add_t1stem, ps_hints_t1stem3,
* src/pshinter/pshalgo1.c (psh1_hint_table_record,
psh1_hint_table_record_mask, psh1_hint_table_activate_mask): Ditto.
* src/pshinter/pshalgo2.c (psh2_hint_table_record,
psh2_hint_table_record_mask, psh2_hint_table_activate_mask): Ditto.
* src/sfnt/ttpost.c (Load_Format_20, Load_Format_25,
TT_Get_PS_Name): Ditto.
* src/truetype/ttgload.c (TT_Get_Metrics, Get_HMetrics,
load_truetype_glyph): Ditto.
* src/type1/t1load.c (parse_subrs, T1_Open_Face): Ditto.
* src/type1/t1afm.c (T1_Get_Kerning): Ditto.
* include/freetype/cache/ftcmanag.h (ftc_family_table_free): Ditto.
2002-03-07 22:59:59 +01:00
|
|
|
FT_MemTable table = (FT_MemTable)memory->user;
|
2001-12-05 02:22:05 +01:00
|
|
|
|
|
|
|
|
2001-10-22 10:32:21 +02:00
|
|
|
if ( block == NULL )
|
2001-10-24 10:04:00 +02:00
|
|
|
ft_mem_debug_panic( "trying to free NULL in (%s:%ld)",
|
* include/freetype/fterrdef.h, include/freetype/config/ftconfig.h,
include/freetype/internal/ftmemory.h, src/base/ftdbgmem.c,
src/base/ftutil.c: udpating the memory management functions and
macros to safely deal with array size buffer overflows, this
corresponds to attemps to allocate arrays that are too large. For
an example, consider the following code:
count = read_uint32_from_file();
array = malloc( sizeof(Item) * count );
for ( nn = 0; nn < count; nn++ )
array[nn] = read_item_from_file();
if 'count' is larger than FT_UINT_MAX/sizeof(Item), the multiplication
will overflow and the array allocated will be smaller than the data
read from the file. In this case, the heap will be trashed, and this
can be used as a denial-of-service, or make the engine crash later.
the FT_ARRAY_NEW and FT_ARRAY_RENEW macro now check that the new
count is no more than FT_INT_MAX/item_size, otherwise, a new error,
named 'FT_Err_Array_Too_Large' will be returned.
note that the memory debugger now works again when FT_DEBUG_MEMORY
is defined, and FT_STRICT_ALIASING has disappeared, the corresponding
code being now the default.
2006-05-02 08:34:27 +02:00
|
|
|
FT_FILENAME( _ft_debug_file ),
|
|
|
|
_ft_debug_lineno );
|
2001-12-05 02:22:05 +01:00
|
|
|
|
2005-10-20 17:33:34 +02:00
|
|
|
ft_mem_table_remove( table, (FT_Byte*)block, 0 );
|
2001-12-05 02:22:05 +01:00
|
|
|
|
2005-02-22 16:38:12 +01:00
|
|
|
if ( !table->keep_alive )
|
|
|
|
ft_mem_table_free( table, block );
|
|
|
|
|
|
|
|
table->alloc_count--;
|
|
|
|
|
* include/freetype/fterrdef.h, include/freetype/config/ftconfig.h,
include/freetype/internal/ftmemory.h, src/base/ftdbgmem.c,
src/base/ftutil.c: udpating the memory management functions and
macros to safely deal with array size buffer overflows, this
corresponds to attemps to allocate arrays that are too large. For
an example, consider the following code:
count = read_uint32_from_file();
array = malloc( sizeof(Item) * count );
for ( nn = 0; nn < count; nn++ )
array[nn] = read_item_from_file();
if 'count' is larger than FT_UINT_MAX/sizeof(Item), the multiplication
will overflow and the array allocated will be smaller than the data
read from the file. In this case, the heap will be trashed, and this
can be used as a denial-of-service, or make the engine crash later.
the FT_ARRAY_NEW and FT_ARRAY_RENEW macro now check that the new
count is no more than FT_INT_MAX/item_size, otherwise, a new error,
named 'FT_Err_Array_Too_Large' will be returned.
note that the memory debugger now works again when FT_DEBUG_MEMORY
is defined, and FT_STRICT_ALIASING has disappeared, the corresponding
code being now the default.
2006-05-02 08:34:27 +02:00
|
|
|
_ft_debug_file = "<unknown>";
|
|
|
|
_ft_debug_lineno = 0;
|
2001-10-22 10:32:21 +02:00
|
|
|
}
|
2001-12-14 15:52:58 +01:00
|
|
|
|
2001-10-22 10:32:21 +02:00
|
|
|
|
|
|
|
extern FT_Pointer
|
|
|
|
ft_mem_debug_realloc( FT_Memory memory,
|
|
|
|
FT_Long cur_size,
|
|
|
|
FT_Long new_size,
|
|
|
|
FT_Pointer block )
|
|
|
|
{
|
* src/base/ftdbgmem.c (ft_mem_table_resize, ft_mem_table_new,
ft_mem_table_set, ft_mem_debug_alloc, ft_mem_debug_free,
ft_mem_debug_realloc, ft_mem_debug_done, FT_Alloc_Debug,
FT_Realloc_Debug, FT_Free_Debug): Fix compiler warnings.
* src/base/ftcalc.c (FT_MulFix): Ditto.
* src/cff/cffdrivr.c (cff_get_name_index): Ditto.
* src/cff/cffobjs.c (CFF_Size_Get_Global_Funcs, CFF_Size_Init,
CFF_GlyphSlot_Init): Ditto.
* src/cid/cidobjs.c (CID_GlyphSlot_Init,
CID_Size_Get_Globals_Funcs): Ditto.
* src/type1/t1objs.c (T1_Size_Get_Globals_Funcs, T1_GlyphSlot_Init):
Ditto.
* src/pshinter/pshmod.c (pshinter_interface): Use `static const'.
* src/winfonts/winfnt.c (FNT_Get_Next_Char): Remove unused
variables.
* include/freetype/internal/psaux.h (T1_Builder_Funcs): Renamed
to...
(T1_Builder_FuncsRec): This.
(T1_Builder_Funcs): New typedef.
(PSAux_Interface): Remove compiler warnings.
* src/psaux/psauxmod.c (t1_builder_funcs), src/psaux/psobjs.h
(t1_builder_funcs): Updated.
* src/pshinter/pshglob.h (PSH_Blue_Align): Replaced with ...
(PSH_BLUE_ALIGN_{NONE,TOP,BOT}): New defines.
(PSH_AlignmentRec): Updated.
* include/freetype/internal/ftstream.h (GET_Char, GET_Byte): Fix
typo.
* include/freetype/internal/ftgloadr.h (FT_SubGlyph): Ditto.
* src/base/ftstream (FT_Get_Char): Rename to...
(FT_Stream_Get_Char): This.
* src/base/ftnames.c (FT_Get_Sfnt_Name): s/index/idx/ -- `index' is
a built-in function in gcc, causing warning messages with gcc 3.0.
* src/autohint/ahglyph.c (ah_outline_load): Ditto.
* src/autohint/ahglobal.c (ah_hinter_compute_blues): Ditto.
* src/cache/ftcmanag.c (ftc_family_table_alloc,
ftc_family_table_free, FTC_Manager_Done, FTC_Manager_Register_Cache):
Ditto.
* src/cff/cffload.c (cff_new_index, cff_done_index,
cff_explicit_index, CFF_Access_Element, CFF_Forget_Element,
CFF_Get_Name, CFF_Get_String, CFF_Load_SubFont, CFF_Load_Font,
CFF_Done_Font): Ditto.
* src/psaux/psobjs.c (PS_Table_Add, PS_Parser_LoadField): Ditto.
* src/psaux/t1decode.c (T1_Decoder_Parse_Charstrings): Ditto.
* src/pshinter/pshrec.c (ps_mask_test_bit, ps_mask_clear_bit,
ps_mask_set_bit, ps_dimension_add_t1stem, ps_hints_t1stem3,
* src/pshinter/pshalgo1.c (psh1_hint_table_record,
psh1_hint_table_record_mask, psh1_hint_table_activate_mask): Ditto.
* src/pshinter/pshalgo2.c (psh2_hint_table_record,
psh2_hint_table_record_mask, psh2_hint_table_activate_mask): Ditto.
* src/sfnt/ttpost.c (Load_Format_20, Load_Format_25,
TT_Get_PS_Name): Ditto.
* src/truetype/ttgload.c (TT_Get_Metrics, Get_HMetrics,
load_truetype_glyph): Ditto.
* src/type1/t1load.c (parse_subrs, T1_Open_Face): Ditto.
* src/type1/t1afm.c (T1_Get_Kerning): Ditto.
* include/freetype/cache/ftcmanag.h (ftc_family_table_free): Ditto.
2002-03-07 22:59:59 +01:00
|
|
|
FT_MemTable table = (FT_MemTable)memory->user;
|
2001-10-22 10:32:21 +02:00
|
|
|
FT_MemNode node, *pnode;
|
|
|
|
FT_Pointer new_block;
|
2005-10-20 17:33:34 +02:00
|
|
|
FT_Long delta;
|
2001-10-22 10:32:21 +02:00
|
|
|
|
* include/freetype/fterrdef.h, include/freetype/config/ftconfig.h,
include/freetype/internal/ftmemory.h, src/base/ftdbgmem.c,
src/base/ftutil.c: udpating the memory management functions and
macros to safely deal with array size buffer overflows, this
corresponds to attemps to allocate arrays that are too large. For
an example, consider the following code:
count = read_uint32_from_file();
array = malloc( sizeof(Item) * count );
for ( nn = 0; nn < count; nn++ )
array[nn] = read_item_from_file();
if 'count' is larger than FT_UINT_MAX/sizeof(Item), the multiplication
will overflow and the array allocated will be smaller than the data
read from the file. In this case, the heap will be trashed, and this
can be used as a denial-of-service, or make the engine crash later.
the FT_ARRAY_NEW and FT_ARRAY_RENEW macro now check that the new
count is no more than FT_INT_MAX/item_size, otherwise, a new error,
named 'FT_Err_Array_Too_Large' will be returned.
note that the memory debugger now works again when FT_DEBUG_MEMORY
is defined, and FT_STRICT_ALIASING has disappeared, the corresponding
code being now the default.
2006-05-02 08:34:27 +02:00
|
|
|
const char* file_name = FT_FILENAME( _ft_debug_file );
|
|
|
|
FT_Long line_no = _ft_debug_lineno;
|
2001-10-24 10:04:00 +02:00
|
|
|
|
2001-12-14 15:52:58 +01:00
|
|
|
|
2005-10-21 12:01:25 +02:00
|
|
|
/* unlikely, but possible */
|
|
|
|
if ( new_size == cur_size )
|
|
|
|
return block;
|
|
|
|
|
* src/truetype/ttobjs.c (tt_driver_done): Fix typo.
* src/bdf/bdfdrivr.c (BDF_Face_Done, BDF_Face_Init,
BDF_Set_Pixel_Size): Don't use BDF_XXX but FT_XXX arguments which
are typecast to the proper BDF_XXX types within the function.
Update code accordingly.
Use FT_CALLBACK_DEF throughout.
(BDF_Set_Point_Size): New wrapper function.
(bdf_driver_class): Remove casts.
* src/cff/cffdrivr.c (Get_Kerning, Load_Glyph, cff_get_interface):
Don't use CFF_XXX but FT_XXX arguments which are typecast to the
proper CFF_XXX types within the function.
Update code accordingly.
Use FT_CALLBACK_DEF throughout.
(cff_driver_class): Remove casts.
* src/cff/cffobjs.h, src/cff/cffobjs.c (cff_size_done,
cff_size_init, cff_size_reset, cff_slot_done, cff_slot_init,
cff_face_init, cff_face_done, cff_driver_init, cff_driver_done):
Don't use CFF_XXX but FT_XXX arguments which are typecast to the
proper CFF_XXX types within the function.
Update code accordingly.
(cff_point_size_reset): New wrapper function.
* src/cid/cidobjs.h, src/cid/cidobjs.c (cid_slot_done,
cid_slot_init, cid_size_done, cid_size_init, cid_size_reset,
cid_face_done, cid_face_init, cid_driver_init, cid_driver_done):
Don't use CID_XXX but FT_XXX arguments which are typecast to the
proper CID_XXX types within the function.
Update code accordingly.
(cid_point_size_reset): New wrapper function.
* src/cid/cidgload.c, src/cid/cidgload.h (cid_slot_load_glyph):
Don't use CID_XXX but FT_XXX arguments which are typecast to the
proper CID_XXX types within the function.
Update code accordingly.
* src/cid/cidriver.c (cid_get_interface):
Don't use CID_XXX but FT_XXX arguments which are typecast to the
proper CID_XXX types within the function.
Update code accordingly.
Use FT_CALLBACK_DEF.
(t1cid_driver_class): Remove casts.
* src/truetype/ttdriver.c (tt_get_interface): Use FT_CALLBACK_DEF.
* src/truetype/ttgxvar.c (ft_var_load_avar): Don't free non-local
variables (this is done later).
(ft_var_load_avar): Fix call to FT_FRAME_ENTER.
(TT_Get_MM_Var): Fix size for `fvar_fields'.
(TT_Vary_Get_Glyph_Deltas): Handle deallocation of local variables
correctly.
* src/base/ftdbgmem.c (ft_mem_debug_realloc): Don't abort if
current size is zero.
2004-05-06 13:48:35 +02:00
|
|
|
/* the following is valid according to ANSI C */
|
|
|
|
#if 0
|
2001-10-22 10:32:21 +02:00
|
|
|
if ( block == NULL || cur_size == 0 )
|
2001-10-24 10:04:00 +02:00
|
|
|
ft_mem_debug_panic( "trying to reallocate NULL in (%s:%ld)",
|
* src/truetype/ttobjs.c (tt_driver_done): Fix typo.
* src/bdf/bdfdrivr.c (BDF_Face_Done, BDF_Face_Init,
BDF_Set_Pixel_Size): Don't use BDF_XXX but FT_XXX arguments which
are typecast to the proper BDF_XXX types within the function.
Update code accordingly.
Use FT_CALLBACK_DEF throughout.
(BDF_Set_Point_Size): New wrapper function.
(bdf_driver_class): Remove casts.
* src/cff/cffdrivr.c (Get_Kerning, Load_Glyph, cff_get_interface):
Don't use CFF_XXX but FT_XXX arguments which are typecast to the
proper CFF_XXX types within the function.
Update code accordingly.
Use FT_CALLBACK_DEF throughout.
(cff_driver_class): Remove casts.
* src/cff/cffobjs.h, src/cff/cffobjs.c (cff_size_done,
cff_size_init, cff_size_reset, cff_slot_done, cff_slot_init,
cff_face_init, cff_face_done, cff_driver_init, cff_driver_done):
Don't use CFF_XXX but FT_XXX arguments which are typecast to the
proper CFF_XXX types within the function.
Update code accordingly.
(cff_point_size_reset): New wrapper function.
* src/cid/cidobjs.h, src/cid/cidobjs.c (cid_slot_done,
cid_slot_init, cid_size_done, cid_size_init, cid_size_reset,
cid_face_done, cid_face_init, cid_driver_init, cid_driver_done):
Don't use CID_XXX but FT_XXX arguments which are typecast to the
proper CID_XXX types within the function.
Update code accordingly.
(cid_point_size_reset): New wrapper function.
* src/cid/cidgload.c, src/cid/cidgload.h (cid_slot_load_glyph):
Don't use CID_XXX but FT_XXX arguments which are typecast to the
proper CID_XXX types within the function.
Update code accordingly.
* src/cid/cidriver.c (cid_get_interface):
Don't use CID_XXX but FT_XXX arguments which are typecast to the
proper CID_XXX types within the function.
Update code accordingly.
Use FT_CALLBACK_DEF.
(t1cid_driver_class): Remove casts.
* src/truetype/ttdriver.c (tt_get_interface): Use FT_CALLBACK_DEF.
* src/truetype/ttgxvar.c (ft_var_load_avar): Don't free non-local
variables (this is done later).
(ft_var_load_avar): Fix call to FT_FRAME_ENTER.
(TT_Get_MM_Var): Fix size for `fvar_fields'.
(TT_Vary_Get_Glyph_Deltas): Handle deallocation of local variables
correctly.
* src/base/ftdbgmem.c (ft_mem_debug_realloc): Don't abort if
current size is zero.
2004-05-06 13:48:35 +02:00
|
|
|
file_name, line_no );
|
|
|
|
#endif
|
2001-12-05 02:22:05 +01:00
|
|
|
|
* src/truetype/ttobjs.c (tt_driver_done): Fix typo.
* src/bdf/bdfdrivr.c (BDF_Face_Done, BDF_Face_Init,
BDF_Set_Pixel_Size): Don't use BDF_XXX but FT_XXX arguments which
are typecast to the proper BDF_XXX types within the function.
Update code accordingly.
Use FT_CALLBACK_DEF throughout.
(BDF_Set_Point_Size): New wrapper function.
(bdf_driver_class): Remove casts.
* src/cff/cffdrivr.c (Get_Kerning, Load_Glyph, cff_get_interface):
Don't use CFF_XXX but FT_XXX arguments which are typecast to the
proper CFF_XXX types within the function.
Update code accordingly.
Use FT_CALLBACK_DEF throughout.
(cff_driver_class): Remove casts.
* src/cff/cffobjs.h, src/cff/cffobjs.c (cff_size_done,
cff_size_init, cff_size_reset, cff_slot_done, cff_slot_init,
cff_face_init, cff_face_done, cff_driver_init, cff_driver_done):
Don't use CFF_XXX but FT_XXX arguments which are typecast to the
proper CFF_XXX types within the function.
Update code accordingly.
(cff_point_size_reset): New wrapper function.
* src/cid/cidobjs.h, src/cid/cidobjs.c (cid_slot_done,
cid_slot_init, cid_size_done, cid_size_init, cid_size_reset,
cid_face_done, cid_face_init, cid_driver_init, cid_driver_done):
Don't use CID_XXX but FT_XXX arguments which are typecast to the
proper CID_XXX types within the function.
Update code accordingly.
(cid_point_size_reset): New wrapper function.
* src/cid/cidgload.c, src/cid/cidgload.h (cid_slot_load_glyph):
Don't use CID_XXX but FT_XXX arguments which are typecast to the
proper CID_XXX types within the function.
Update code accordingly.
* src/cid/cidriver.c (cid_get_interface):
Don't use CID_XXX but FT_XXX arguments which are typecast to the
proper CID_XXX types within the function.
Update code accordingly.
Use FT_CALLBACK_DEF.
(t1cid_driver_class): Remove casts.
* src/truetype/ttdriver.c (tt_get_interface): Use FT_CALLBACK_DEF.
* src/truetype/ttgxvar.c (ft_var_load_avar): Don't free non-local
variables (this is done later).
(ft_var_load_avar): Fix call to FT_FRAME_ENTER.
(TT_Get_MM_Var): Fix size for `fvar_fields'.
(TT_Vary_Get_Glyph_Deltas): Handle deallocation of local variables
correctly.
* src/base/ftdbgmem.c (ft_mem_debug_realloc): Don't abort if
current size is zero.
2004-05-06 13:48:35 +02:00
|
|
|
/* while the following is allowed in ANSI C also, we abort since */
|
2005-02-22 16:38:12 +01:00
|
|
|
/* such case should be handled by FreeType. */
|
2001-10-22 10:32:21 +02:00
|
|
|
if ( new_size <= 0 )
|
2001-12-05 02:22:05 +01:00
|
|
|
ft_mem_debug_panic(
|
|
|
|
"trying to reallocate %p to size 0 (current is %ld) in (%s:%ld)",
|
|
|
|
block, cur_size, file_name, line_no );
|
|
|
|
|
2005-03-01 03:13:50 +01:00
|
|
|
/* check `cur_size' value */
|
2001-10-22 10:32:21 +02:00
|
|
|
pnode = ft_mem_table_get_nodep( table, (FT_Byte*)block );
|
|
|
|
node = *pnode;
|
2001-12-05 02:22:05 +01:00
|
|
|
if ( !node )
|
|
|
|
ft_mem_debug_panic(
|
|
|
|
"trying to reallocate unknown block at %p in (%s:%ld)",
|
|
|
|
block, file_name, line_no );
|
|
|
|
|
2001-10-22 10:32:21 +02:00
|
|
|
if ( node->size <= 0 )
|
2001-12-05 02:22:05 +01:00
|
|
|
ft_mem_debug_panic(
|
|
|
|
"trying to reallocate freed block at %p in (%s:%ld)",
|
|
|
|
block, file_name, line_no );
|
|
|
|
|
2001-10-22 10:32:21 +02:00
|
|
|
if ( node->size != cur_size )
|
* README.UNX: updated the Unix-specific quick-compilation guide to
warn about the GNU Make requirement at compile time..
* include/freetype/config/ftstdlib.h,
include/freetype/config/ftconfig.h,
include/freetype/config/ftheader.h,
include/freetype/internal/ftmemory.h,
include/freetype/internal/ftobjs.h,
src/autohint/ahoptim.c,
src/base/ftdbgmem.c, src/base/ftdebug.c,
src/base/ftmac.c, src/base/ftobjs.c,
src/base/ftsystem.c,
src/cache/ftcimage.c, src/cache/ftcsbits.c,
src/cff/cffdriver.c, src/cff/cffload.c, src/cff/cffobjs.c,
src/cid/cidload.c, src/cid/cidparse.c, src/cid/cidriver.c,
src/pcf/pcfdriver.c, src/pcf/pcfread.c,
src/psaux/t1cmap.c, src/psaux/t1decode.c,
src/pshinter/pshalgo1.c, src/pshinter/pshalgo2.c,
src/pshinter/pshrec.c,
src/psnames/psmodule.c,
src/raster/ftraster.c,
src/sfnt/sfdriver.c, src/sfnt/ttload.c, src/sfnt/ttpost.c,
src/smooth/ftgrays.c,
src/type1/t1afm.c, src/type1/t1driver.c, src/type1/t1gload.c,
src/type1/t1load.c, src/type1/t1objs.c, src/type1/t1parse.c:
added the new configuration file "ftstdlib.h" used to define
aliases for all ISO C library functions used by the engine
(e.g. strlen, qsort, setjmp, etc...)
this eases the porting of FreeType 2 to exotic environments like
XFree86 modules/extensions..
also removed many #include <string.h>, #include <stdlib.h>, etc...
from the engine's sources where they're not needed..
2002-04-12 11:31:48 +02:00
|
|
|
ft_mem_debug_panic( "invalid ft_realloc request for %p. cur_size is "
|
2001-10-24 10:04:00 +02:00
|
|
|
"%ld instead of %ld in (%s:%ld)",
|
|
|
|
block, cur_size, node->size, file_name, line_no );
|
2001-12-05 02:22:05 +01:00
|
|
|
|
2005-10-20 17:33:34 +02:00
|
|
|
/* 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;
|
|
|
|
|
2005-10-23 21:31:01 +02:00
|
|
|
ft_mem_table_set( table, (FT_Byte*)new_block, new_size, delta );
|
2005-10-20 17:33:34 +02:00
|
|
|
|
|
|
|
ft_memcpy( new_block, block, cur_size < new_size ? cur_size : new_size );
|
|
|
|
|
|
|
|
ft_mem_table_remove( table, (FT_Byte*)block, delta );
|
|
|
|
|
* include/freetype/fterrdef.h, include/freetype/config/ftconfig.h,
include/freetype/internal/ftmemory.h, src/base/ftdbgmem.c,
src/base/ftutil.c: udpating the memory management functions and
macros to safely deal with array size buffer overflows, this
corresponds to attemps to allocate arrays that are too large. For
an example, consider the following code:
count = read_uint32_from_file();
array = malloc( sizeof(Item) * count );
for ( nn = 0; nn < count; nn++ )
array[nn] = read_item_from_file();
if 'count' is larger than FT_UINT_MAX/sizeof(Item), the multiplication
will overflow and the array allocated will be smaller than the data
read from the file. In this case, the heap will be trashed, and this
can be used as a denial-of-service, or make the engine crash later.
the FT_ARRAY_NEW and FT_ARRAY_RENEW macro now check that the new
count is no more than FT_INT_MAX/item_size, otherwise, a new error,
named 'FT_Err_Array_Too_Large' will be returned.
note that the memory debugger now works again when FT_DEBUG_MEMORY
is defined, and FT_STRICT_ALIASING has disappeared, the corresponding
code being now the default.
2006-05-02 08:34:27 +02:00
|
|
|
_ft_debug_file = "<unknown>";
|
|
|
|
_ft_debug_lineno = 0;
|
2005-10-21 12:01:25 +02:00
|
|
|
|
2005-10-20 17:33:34 +02:00
|
|
|
if ( !table->keep_alive )
|
|
|
|
ft_mem_table_free( table, block );
|
|
|
|
|
2001-10-22 10:32:21 +02:00
|
|
|
return new_block;
|
|
|
|
}
|
2001-12-05 02:22:05 +01:00
|
|
|
|
|
|
|
|
2001-10-22 10:32:21 +02:00
|
|
|
extern FT_Int
|
|
|
|
ft_mem_debug_init( FT_Memory memory )
|
|
|
|
{
|
|
|
|
FT_MemTable table;
|
|
|
|
FT_Int result = 0;
|
2001-10-22 22:15:29 +02:00
|
|
|
|
2001-12-05 02:22:05 +01:00
|
|
|
|
2003-03-13 22:07:51 +01:00
|
|
|
if ( getenv( "FT2_DEBUG_MEMORY" ) )
|
2001-12-05 02:22:05 +01:00
|
|
|
{
|
2001-10-24 09:32:55 +02:00
|
|
|
table = ft_mem_table_new( memory );
|
2001-10-22 22:15:29 +02:00
|
|
|
if ( table )
|
|
|
|
{
|
2003-03-13 22:07:51 +01:00
|
|
|
const char* p;
|
2005-02-22 16:38:12 +01:00
|
|
|
|
2005-03-01 03:13:50 +01:00
|
|
|
|
2001-10-22 22:15:29 +02:00
|
|
|
memory->user = table;
|
|
|
|
memory->alloc = ft_mem_debug_alloc;
|
|
|
|
memory->realloc = ft_mem_debug_realloc;
|
|
|
|
memory->free = ft_mem_debug_free;
|
2005-02-22 16:38:12 +01:00
|
|
|
|
2003-03-13 22:07:51 +01:00
|
|
|
p = getenv( "FT2_ALLOC_TOTAL_MAX" );
|
|
|
|
if ( p != NULL )
|
|
|
|
{
|
2005-03-01 03:13:50 +01:00
|
|
|
FT_Long total_max = ft_atol( p );
|
|
|
|
|
2005-02-22 16:38:12 +01:00
|
|
|
|
2003-03-13 22:07:51 +01:00
|
|
|
if ( total_max > 0 )
|
|
|
|
{
|
|
|
|
table->bound_total = 1;
|
2005-03-01 03:13:50 +01:00
|
|
|
table->alloc_total_max = (FT_ULong)total_max;
|
2003-03-13 22:07:51 +01:00
|
|
|
}
|
|
|
|
}
|
2005-02-22 16:38:12 +01:00
|
|
|
|
2003-03-13 22:07:51 +01:00
|
|
|
p = getenv( "FT2_ALLOC_COUNT_MAX" );
|
|
|
|
if ( p != NULL )
|
|
|
|
{
|
2005-03-01 03:13:50 +01:00
|
|
|
FT_Long total_count = ft_atol( p );
|
|
|
|
|
2005-02-22 16:38:12 +01:00
|
|
|
|
2003-03-13 22:07:51 +01:00
|
|
|
if ( total_count > 0 )
|
|
|
|
{
|
|
|
|
table->bound_count = 1;
|
2005-03-01 03:13:50 +01:00
|
|
|
table->alloc_count_max = (FT_ULong)total_count;
|
2003-03-13 22:07:51 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-02-22 16:38:12 +01:00
|
|
|
p = getenv( "FT2_KEEP_ALIVE" );
|
|
|
|
if ( p != NULL )
|
|
|
|
{
|
2005-03-01 03:13:50 +01:00
|
|
|
FT_Long keep_alive = ft_atol( p );
|
|
|
|
|
2005-02-22 16:38:12 +01:00
|
|
|
|
|
|
|
if ( keep_alive > 0 )
|
|
|
|
table->keep_alive = 1;
|
|
|
|
}
|
|
|
|
|
2001-10-22 22:15:29 +02:00
|
|
|
result = 1;
|
|
|
|
}
|
2001-10-22 10:32:21 +02:00
|
|
|
}
|
|
|
|
return result;
|
2001-12-05 02:22:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-10-22 10:32:21 +02:00
|
|
|
extern void
|
|
|
|
ft_mem_debug_done( FT_Memory memory )
|
|
|
|
{
|
* src/base/ftdbgmem.c (ft_mem_table_resize, ft_mem_table_new,
ft_mem_table_set, ft_mem_debug_alloc, ft_mem_debug_free,
ft_mem_debug_realloc, ft_mem_debug_done, FT_Alloc_Debug,
FT_Realloc_Debug, FT_Free_Debug): Fix compiler warnings.
* src/base/ftcalc.c (FT_MulFix): Ditto.
* src/cff/cffdrivr.c (cff_get_name_index): Ditto.
* src/cff/cffobjs.c (CFF_Size_Get_Global_Funcs, CFF_Size_Init,
CFF_GlyphSlot_Init): Ditto.
* src/cid/cidobjs.c (CID_GlyphSlot_Init,
CID_Size_Get_Globals_Funcs): Ditto.
* src/type1/t1objs.c (T1_Size_Get_Globals_Funcs, T1_GlyphSlot_Init):
Ditto.
* src/pshinter/pshmod.c (pshinter_interface): Use `static const'.
* src/winfonts/winfnt.c (FNT_Get_Next_Char): Remove unused
variables.
* include/freetype/internal/psaux.h (T1_Builder_Funcs): Renamed
to...
(T1_Builder_FuncsRec): This.
(T1_Builder_Funcs): New typedef.
(PSAux_Interface): Remove compiler warnings.
* src/psaux/psauxmod.c (t1_builder_funcs), src/psaux/psobjs.h
(t1_builder_funcs): Updated.
* src/pshinter/pshglob.h (PSH_Blue_Align): Replaced with ...
(PSH_BLUE_ALIGN_{NONE,TOP,BOT}): New defines.
(PSH_AlignmentRec): Updated.
* include/freetype/internal/ftstream.h (GET_Char, GET_Byte): Fix
typo.
* include/freetype/internal/ftgloadr.h (FT_SubGlyph): Ditto.
* src/base/ftstream (FT_Get_Char): Rename to...
(FT_Stream_Get_Char): This.
* src/base/ftnames.c (FT_Get_Sfnt_Name): s/index/idx/ -- `index' is
a built-in function in gcc, causing warning messages with gcc 3.0.
* src/autohint/ahglyph.c (ah_outline_load): Ditto.
* src/autohint/ahglobal.c (ah_hinter_compute_blues): Ditto.
* src/cache/ftcmanag.c (ftc_family_table_alloc,
ftc_family_table_free, FTC_Manager_Done, FTC_Manager_Register_Cache):
Ditto.
* src/cff/cffload.c (cff_new_index, cff_done_index,
cff_explicit_index, CFF_Access_Element, CFF_Forget_Element,
CFF_Get_Name, CFF_Get_String, CFF_Load_SubFont, CFF_Load_Font,
CFF_Done_Font): Ditto.
* src/psaux/psobjs.c (PS_Table_Add, PS_Parser_LoadField): Ditto.
* src/psaux/t1decode.c (T1_Decoder_Parse_Charstrings): Ditto.
* src/pshinter/pshrec.c (ps_mask_test_bit, ps_mask_clear_bit,
ps_mask_set_bit, ps_dimension_add_t1stem, ps_hints_t1stem3,
* src/pshinter/pshalgo1.c (psh1_hint_table_record,
psh1_hint_table_record_mask, psh1_hint_table_activate_mask): Ditto.
* src/pshinter/pshalgo2.c (psh2_hint_table_record,
psh2_hint_table_record_mask, psh2_hint_table_activate_mask): Ditto.
* src/sfnt/ttpost.c (Load_Format_20, Load_Format_25,
TT_Get_PS_Name): Ditto.
* src/truetype/ttgload.c (TT_Get_Metrics, Get_HMetrics,
load_truetype_glyph): Ditto.
* src/type1/t1load.c (parse_subrs, T1_Open_Face): Ditto.
* src/type1/t1afm.c (T1_Get_Kerning): Ditto.
* include/freetype/cache/ftcmanag.h (ftc_family_table_free): Ditto.
2002-03-07 22:59:59 +01:00
|
|
|
FT_MemTable table = (FT_MemTable)memory->user;
|
2001-12-05 02:22:05 +01:00
|
|
|
|
|
|
|
|
2001-10-22 10:32:21 +02:00
|
|
|
if ( table )
|
|
|
|
{
|
2001-10-24 09:32:55 +02:00
|
|
|
memory->free = table->free;
|
|
|
|
memory->realloc = table->realloc;
|
|
|
|
memory->alloc = table->alloc;
|
2001-12-05 02:22:05 +01:00
|
|
|
|
2001-10-22 10:32:21 +02:00
|
|
|
ft_mem_table_destroy( table );
|
|
|
|
memory->user = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-10-22 16:50:41 +02:00
|
|
|
|
Implement new, simplified module selection. With GNU make it is now
sufficient to modify a single file, `modules.cfg', to control the
inclusion of modules and base extension files.
This change also fixes the creation of ftmodule.h; it now depends on
`modules.cfg' and thus is rebuilt only if necessary.
Finally, a version of `ftoption.h' in OBJ_DIR is preferred over the
default location.
* modules.cfg: New file.
* builds/freetype.mk: Don't include `modules.mk'.
Include all `rules.mk' files as specified in `modules.cfg'.
(FTOPTION_FLAG, FTOPTION_H): New variables.
(FT_CFLAGS): Add macro definition for FT_CONFIG_MODULES_H.
Add FTOPTION_FLAG.
($(FT_INIT_OBJ)): Don't use FT_MODULE_LIST.
(CONFIG_H): Add FTMODULE_H and FTOPTION_H.
(INCLUDES): Add DEVEL_DIR.
(INCLUDE_FLAGS, FTSYS_SRC, FTSYS_OBJ, FTDEBUG_SRC, FTDEBUG_OBJ,
OBJ_M, OBJ_S): Use `:=', not `='.
(remove_ftmodule_h): New phony target to delete `ftmodule.h'.
(distclean): Add remove_ftmodule_h.
* builds/modules.mk: (MODULE_LIST): Removed.
(make_module_list, clean_module_list): Replace targets
with...
(FTMODULE_H_INIT, FTMODULE_H_CREATE, FTMODULE_H_DONE): New
variables. Reason for the change is that it is not possible to have
a phony prerequisite which is run only if the target file must be
rebuilt (phony prerequisites act like subroutines and are *always*
executed). We only want to rebuild `ftmodule.h' if `module.cfg' is
changed.
Update all callers.
($FTMODULE_H)): Rule to create `ftmodule.h', depending on
`modules.cfg'.
* builds/toplevel.mk: Rewrite and simplify module handling.
(MODULES_CFG, FTMODULE_H): New variables.
Include MODULES_CFG.
(MODULES): New variable to include all `module.mk' and `rules.mk'
files. We no longer use make's `wildcard' function for this.
* Makefile (USE_MODULES): Remove. Update all users.
(OBJ_DIR): Define it here.
* src/*/module.mk: Change
make_module_list: foo
foo: ...
to
FTMODULE_H_COMMANDS += FOO
define FOO
...
endef
in all files. `FTMODULE_H_COMMANDS' is used in `FTMODULE_H_CREATE'.
* src/base/rules.mk (BASE_EXT_SRC): Use BASE_EXTENSIONS.
* builds/unix/detect.mk (setup): Always execute `configure' script.
(have_mk): Rename to...
(have_Makefile): This.
Don't use `strip' function.
* builds/unix/unix.mk: Include `install.mk' only if BUILD_PROJECT is
defined.
(have_mk): Don't use `strip' function.
Test for unix-def.mk in OBJ_DIR, not BUILD_DIR (and invert the test
accordingly).
* builds/unix/install.mk (install, uninstall): Handle `ftmodule.h'.
* builds/os2/os2-dev.mk, builds/unix/unix-dev.mk,
builds/win32/w32-bccd.mk, builds/win32/w32-dev.mk: Don't define
BUILD_DIR but DEVEL_DIR for development header files.
* builds/ansi/ansi-def.mk (TOP_DIR, OBJ_DIR),
builds/beos/beos-def.mk (TOP_DIR, OBJ_DIR), builds/unix/unix-def.in
(TOP_DIR, OBJ_DIR): Removed. Defined elsewhere.
* builds/dos/dos-def.mk (OBJ_DIR), builds/os2/os2-def.mk (OBJ_DIR),
builds/win32/win32-def.mk (OBJ_DIR): Removed. Defined elsewhere.
* builds/unix/unixddef.mk: Don't define BUILD_DIR but DEVEL_DIR for
development header files.
Don't define PLATFORM.
* configure: Copy `modules.cfg' to builddir if builddir != srcdir.
Update snippet taken from autoconf's m4sh.m4 to current CVS version.
Be more verbose.
* include/freetype/config/ftmodule.h: Add comments -- this file is
no longer used if FreeType is built with GNU make.
* docs/CHANGES, docs/CUSTOMIZE, docs/INSTALL, docs/INSTALL.ANY,
docs/INSTALL.GNU, docs/INSTALL.UNX: Document new build mechanism.
Other minor updates.
* modules.txt: Removed. Contents included in `modules.cfg'.
* include/freetype/internal/ftmemory.h (FT_QAlloc_Debug,
FT_Free_Debug) [FT_STRICT_ALIASING]: Fix typos.
* src/base/ftdbgmem.c (FT_Alloc_Debug, FT_Realloc_Debug,
FT_QAlloc_Debug, FT_QRealloc_Debug, FT_Free_Debug)
[FT_STRICT_ALIASING]: Implement.
2006-01-31 21:17:42 +01:00
|
|
|
|
2005-02-28 23:09:07 +01:00
|
|
|
static int
|
|
|
|
ft_mem_source_compare( const void* p1,
|
|
|
|
const void* p2 )
|
|
|
|
{
|
|
|
|
FT_MemSource s1 = *(FT_MemSource*)p1;
|
|
|
|
FT_MemSource s2 = *(FT_MemSource*)p2;
|
|
|
|
|
2005-03-01 03:13:50 +01:00
|
|
|
|
2005-02-28 23:09:07 +01:00
|
|
|
if ( s2->max_size > s1->max_size )
|
|
|
|
return 1;
|
|
|
|
else if ( s2->max_size < s1->max_size )
|
|
|
|
return -1;
|
|
|
|
else
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-02-22 16:38:12 +01:00
|
|
|
extern void
|
|
|
|
FT_DumpMemory( FT_Memory memory )
|
|
|
|
{
|
|
|
|
FT_MemTable table = (FT_MemTable)memory->user;
|
|
|
|
|
|
|
|
|
|
|
|
if ( table )
|
|
|
|
{
|
2005-03-01 03:13:50 +01:00
|
|
|
FT_MemSource* bucket = table->sources;
|
|
|
|
FT_MemSource* limit = bucket + FT_MEM_SOURCE_BUCKETS;
|
|
|
|
FT_MemSource* sources;
|
|
|
|
FT_UInt nn, count;
|
|
|
|
const char* fmt;
|
|
|
|
|
2005-02-22 16:38:12 +01:00
|
|
|
|
2005-02-28 23:09:07 +01:00
|
|
|
count = 0;
|
|
|
|
for ( ; bucket < limit; bucket++ )
|
|
|
|
{
|
|
|
|
FT_MemSource source = *bucket;
|
|
|
|
|
2005-03-01 03:13:50 +01:00
|
|
|
|
2005-02-28 23:09:07 +01:00
|
|
|
for ( ; source; source = source->link )
|
|
|
|
count++;
|
|
|
|
}
|
|
|
|
|
2005-03-03 18:09:08 +01:00
|
|
|
sources = (FT_MemSource*)ft_mem_table_alloc(
|
|
|
|
table, sizeof ( *sources ) * count );
|
2005-02-28 23:09:07 +01:00
|
|
|
|
|
|
|
count = 0;
|
|
|
|
for ( bucket = table->sources; bucket < limit; bucket++ )
|
|
|
|
{
|
|
|
|
FT_MemSource source = *bucket;
|
|
|
|
|
2005-03-01 03:13:50 +01:00
|
|
|
|
2005-02-28 23:09:07 +01:00
|
|
|
for ( ; source; source = source->link )
|
|
|
|
sources[count++] = source;
|
|
|
|
}
|
|
|
|
|
2005-03-01 03:13:50 +01:00
|
|
|
ft_qsort( sources, count, sizeof ( *sources ), ft_mem_source_compare );
|
2005-02-28 23:09:07 +01:00
|
|
|
|
2005-03-01 03:13:50 +01:00
|
|
|
printf( "FreeType Memory Dump: "
|
|
|
|
"current=%ld max=%ld total=%ld count=%ld\n",
|
|
|
|
table->alloc_current, table->alloc_max,
|
|
|
|
table->alloc_total, table->alloc_count );
|
2005-02-26 01:12:04 +01:00
|
|
|
printf( " block block sizes sizes sizes source\n" );
|
|
|
|
printf( " count high sum highsum max location\n" );
|
2005-02-22 16:38:12 +01:00
|
|
|
printf( "-------------------------------------------------\n" );
|
2005-03-01 03:13:50 +01:00
|
|
|
|
2005-02-26 01:12:04 +01:00
|
|
|
fmt = "%6ld %6ld %8ld %8ld %8ld %s:%d\n";
|
2005-02-22 16:38:12 +01:00
|
|
|
|
2005-02-28 23:09:07 +01:00
|
|
|
for ( nn = 0; nn < count; nn++ )
|
2005-02-22 16:38:12 +01:00
|
|
|
{
|
2005-02-28 23:09:07 +01:00
|
|
|
FT_MemSource source = sources[nn];
|
2005-02-22 16:38:12 +01:00
|
|
|
|
2005-03-01 03:13:50 +01:00
|
|
|
|
2005-02-28 23:09:07 +01:00
|
|
|
printf( fmt,
|
|
|
|
source->cur_blocks, source->max_blocks,
|
2005-03-01 03:13:50 +01:00
|
|
|
source->cur_size, source->max_size, source->cur_max,
|
2005-02-28 23:09:07 +01:00
|
|
|
FT_FILENAME( source->file_name ),
|
|
|
|
source->line_no );
|
2005-02-22 16:38:12 +01:00
|
|
|
}
|
|
|
|
printf( "------------------------------------------------\n" );
|
2005-02-28 23:09:07 +01:00
|
|
|
|
|
|
|
ft_mem_table_free( table, sources );
|
2005-02-22 16:38:12 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-10-22 10:32:21 +02:00
|
|
|
#else /* !FT_DEBUG_MEMORY */
|
2001-12-14 15:52:58 +01:00
|
|
|
|
2001-12-07 22:56:32 +01:00
|
|
|
/* ANSI C doesn't like empty source files */
|
2009-01-06 07:59:36 +01:00
|
|
|
static const FT_Byte _debug_mem_dummy = 0;
|
2001-10-22 10:32:21 +02:00
|
|
|
|
|
|
|
#endif /* !FT_DEBUG_MEMORY */
|
2001-12-05 02:22:05 +01:00
|
|
|
|
|
|
|
|
|
|
|
/* END */
|