tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

ftutil.c (10171B)


      1 /****************************************************************************
      2 *
      3 * ftutil.c
      4 *
      5 *   FreeType utility file for memory and list management (body).
      6 *
      7 * Copyright (C) 2002-2025 by
      8 * David Turner, Robert Wilhelm, and Werner Lemberg.
      9 *
     10 * This file is part of the FreeType project, and may only be used,
     11 * modified, and distributed under the terms of the FreeType project
     12 * license, LICENSE.TXT.  By continuing to use, modify, or distribute
     13 * this file you indicate that you have read the license and
     14 * understand and accept it fully.
     15 *
     16 */
     17 
     18 
     19 #include <freetype/internal/ftdebug.h>
     20 #include <freetype/internal/ftmemory.h>
     21 #include <freetype/internal/ftobjs.h>
     22 #include <freetype/ftlist.h>
     23 
     24 
     25  /**************************************************************************
     26   *
     27   * The macro FT_COMPONENT is used in trace mode.  It is an implicit
     28   * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
     29   * messages during execution.
     30   */
     31 #undef  FT_COMPONENT
     32 #define FT_COMPONENT  memory
     33 
     34 
     35  /*************************************************************************/
     36  /*************************************************************************/
     37  /*************************************************************************/
     38  /*****                                                               *****/
     39  /*****                                                               *****/
     40  /*****               M E M O R Y   M A N A G E M E N T               *****/
     41  /*****                                                               *****/
     42  /*****                                                               *****/
     43  /*************************************************************************/
     44  /*************************************************************************/
     45  /*************************************************************************/
     46 
     47 
     48  FT_BASE_DEF( FT_Pointer )
     49  ft_mem_alloc( FT_Memory  memory,
     50                FT_Long    size,
     51                FT_Error  *p_error )
     52  {
     53    FT_Error    error;
     54    FT_Pointer  block = ft_mem_qalloc( memory, size, &error );
     55 
     56    if ( !error && block && size > 0 )
     57      FT_MEM_ZERO( block, size );
     58 
     59    *p_error = error;
     60    return block;
     61  }
     62 
     63 
     64  FT_BASE_DEF( FT_Pointer )
     65  ft_mem_qalloc( FT_Memory  memory,
     66                 FT_Long    size,
     67                 FT_Error  *p_error )
     68  {
     69    FT_Error    error = FT_Err_Ok;
     70    FT_Pointer  block = NULL;
     71 
     72 
     73    if ( size > 0 )
     74    {
     75      block = memory->alloc( memory, size );
     76      if ( !block )
     77        error = FT_THROW( Out_Of_Memory );
     78    }
     79    else if ( size < 0 )
     80    {
     81      /* may help catch/prevent security issues */
     82      error = FT_THROW( Invalid_Argument );
     83    }
     84 
     85    *p_error = error;
     86    return block;
     87  }
     88 
     89 
     90  FT_BASE_DEF( FT_Pointer )
     91  ft_mem_realloc( FT_Memory  memory,
     92                  FT_Long    item_size,
     93                  FT_Long    cur_count,
     94                  FT_Long    new_count,
     95                  void*      block,
     96                  FT_Error  *p_error )
     97  {
     98    FT_Error  error = FT_Err_Ok;
     99 
    100 
    101    block = ft_mem_qrealloc( memory, item_size,
    102                             cur_count, new_count, block, &error );
    103    if ( !error && block && new_count > cur_count )
    104      FT_MEM_ZERO( (char*)block + cur_count * item_size,
    105                   ( new_count - cur_count ) * item_size );
    106 
    107    *p_error = error;
    108    return block;
    109  }
    110 
    111 
    112  FT_BASE_DEF( FT_Pointer )
    113  ft_mem_qrealloc( FT_Memory  memory,
    114                   FT_Long    item_size,
    115                   FT_Long    cur_count,
    116                   FT_Long    new_count,
    117                   void*      block,
    118                   FT_Error  *p_error )
    119  {
    120    FT_Error  error = FT_Err_Ok;
    121 
    122 
    123    /* Note that we now accept `item_size == 0' as a valid parameter, in
    124     * order to cover very weird cases where an ALLOC_MULT macro would be
    125     * called.
    126     */
    127    if ( cur_count < 0 || new_count < 0 || item_size < 0 )
    128    {
    129      /* may help catch/prevent nasty security issues */
    130      error = FT_THROW( Invalid_Argument );
    131    }
    132    else if ( new_count == 0 || item_size == 0 )
    133    {
    134      ft_mem_free( memory, block );
    135      block = NULL;
    136    }
    137    else if ( new_count > FT_INT_MAX / item_size )
    138    {
    139      error = FT_THROW( Array_Too_Large );
    140    }
    141    else if ( cur_count == 0 )
    142    {
    143      FT_ASSERT( !block );
    144 
    145      block = memory->alloc( memory, new_count * item_size );
    146      if ( block == NULL )
    147        error = FT_THROW( Out_Of_Memory );
    148    }
    149    else
    150    {
    151      FT_Pointer  block2;
    152      FT_Long     cur_size = cur_count * item_size;
    153      FT_Long     new_size = new_count * item_size;
    154 
    155 
    156      block2 = memory->realloc( memory, cur_size, new_size, block );
    157      if ( !block2 )
    158        error = FT_THROW( Out_Of_Memory );
    159      else
    160        block = block2;
    161    }
    162 
    163    *p_error = error;
    164    return block;
    165  }
    166 
    167 
    168  FT_BASE_DEF( void )
    169  ft_mem_free( FT_Memory   memory,
    170               const void *P )
    171  {
    172    if ( P )
    173      memory->free( memory, (void*)P );
    174  }
    175 
    176 
    177  FT_BASE_DEF( FT_Pointer )
    178  ft_mem_dup( FT_Memory    memory,
    179              const void*  address,
    180              FT_ULong     size,
    181              FT_Error    *p_error )
    182  {
    183    FT_Error    error;
    184    FT_Pointer  p = ft_mem_qalloc( memory, (FT_Long)size, &error );
    185 
    186 
    187    if ( !error && address && size > 0 )
    188      ft_memcpy( p, address, size );
    189 
    190    *p_error = error;
    191    return p;
    192  }
    193 
    194 
    195  FT_BASE_DEF( FT_Pointer )
    196  ft_mem_strdup( FT_Memory    memory,
    197                 const char*  str,
    198                 FT_Error    *p_error )
    199  {
    200    FT_ULong  len = str ? (FT_ULong)ft_strlen( str ) + 1
    201                        : 0;
    202 
    203 
    204    return ft_mem_dup( memory, str, len, p_error );
    205  }
    206 
    207 
    208  FT_BASE_DEF( FT_Int )
    209  ft_mem_strcpyn( char*        dst,
    210                  const char*  src,
    211                  FT_ULong     size )
    212  {
    213    while ( size > 1 && *src != 0 )
    214    {
    215      *dst++ = *src++;
    216      size--;
    217    }
    218 
    219    *dst = 0;  /* always zero-terminate */
    220 
    221    return *src != 0;
    222  }
    223 
    224 
    225  /*************************************************************************/
    226  /*************************************************************************/
    227  /*************************************************************************/
    228  /*****                                                               *****/
    229  /*****                                                               *****/
    230  /*****            D O U B L Y   L I N K E D   L I S T S              *****/
    231  /*****                                                               *****/
    232  /*****                                                               *****/
    233  /*************************************************************************/
    234  /*************************************************************************/
    235  /*************************************************************************/
    236 
    237 #undef  FT_COMPONENT
    238 #define FT_COMPONENT  list
    239 
    240  /* documentation is in ftlist.h */
    241 
    242  FT_EXPORT_DEF( FT_ListNode )
    243  FT_List_Find( FT_List  list,
    244                void*    data )
    245  {
    246    FT_ListNode  cur;
    247 
    248 
    249    if ( !list )
    250      return NULL;
    251 
    252    cur = list->head;
    253    while ( cur )
    254    {
    255      if ( cur->data == data )
    256        return cur;
    257 
    258      cur = cur->next;
    259    }
    260 
    261    return NULL;
    262  }
    263 
    264 
    265  /* documentation is in ftlist.h */
    266 
    267  FT_EXPORT_DEF( void )
    268  FT_List_Add( FT_List      list,
    269               FT_ListNode  node )
    270  {
    271    FT_ListNode  before;
    272 
    273 
    274    if ( !list || !node )
    275      return;
    276 
    277    before = list->tail;
    278 
    279    node->next = NULL;
    280    node->prev = before;
    281 
    282    if ( before )
    283      before->next = node;
    284    else
    285      list->head = node;
    286 
    287    list->tail = node;
    288  }
    289 
    290 
    291  /* documentation is in ftlist.h */
    292 
    293  FT_EXPORT_DEF( void )
    294  FT_List_Insert( FT_List      list,
    295                  FT_ListNode  node )
    296  {
    297    FT_ListNode  after;
    298 
    299 
    300    if ( !list || !node )
    301      return;
    302 
    303    after = list->head;
    304 
    305    node->next = after;
    306    node->prev = NULL;
    307 
    308    if ( !after )
    309      list->tail = node;
    310    else
    311      after->prev = node;
    312 
    313    list->head = node;
    314  }
    315 
    316 
    317  /* documentation is in ftlist.h */
    318 
    319  FT_EXPORT_DEF( void )
    320  FT_List_Remove( FT_List      list,
    321                  FT_ListNode  node )
    322  {
    323    FT_ListNode  before, after;
    324 
    325 
    326    if ( !list || !node )
    327      return;
    328 
    329    before = node->prev;
    330    after  = node->next;
    331 
    332    if ( before )
    333      before->next = after;
    334    else
    335      list->head = after;
    336 
    337    if ( after )
    338      after->prev = before;
    339    else
    340      list->tail = before;
    341  }
    342 
    343 
    344  /* documentation is in ftlist.h */
    345 
    346  FT_EXPORT_DEF( void )
    347  FT_List_Up( FT_List      list,
    348              FT_ListNode  node )
    349  {
    350    FT_ListNode  before, after;
    351 
    352 
    353    if ( !list || !node )
    354      return;
    355 
    356    before = node->prev;
    357    after  = node->next;
    358 
    359    /* check whether we are already on top of the list */
    360    if ( !before )
    361      return;
    362 
    363    before->next = after;
    364 
    365    if ( after )
    366      after->prev = before;
    367    else
    368      list->tail = before;
    369 
    370    node->prev       = NULL;
    371    node->next       = list->head;
    372    list->head->prev = node;
    373    list->head       = node;
    374  }
    375 
    376 
    377  /* documentation is in ftlist.h */
    378 
    379  FT_EXPORT_DEF( FT_Error )
    380  FT_List_Iterate( FT_List           list,
    381                   FT_List_Iterator  iterator,
    382                   void*             user )
    383  {
    384    FT_ListNode  cur;
    385    FT_Error     error = FT_Err_Ok;
    386 
    387 
    388    if ( !list || !iterator )
    389      return FT_THROW( Invalid_Argument );
    390 
    391    cur = list->head;
    392 
    393    while ( cur )
    394    {
    395      FT_ListNode  next = cur->next;
    396 
    397 
    398      error = iterator( cur, user );
    399      if ( error )
    400        break;
    401 
    402      cur = next;
    403    }
    404 
    405    return error;
    406  }
    407 
    408 
    409  /* documentation is in ftlist.h */
    410 
    411  FT_EXPORT_DEF( void )
    412  FT_List_Finalize( FT_List             list,
    413                    FT_List_Destructor  destroy,
    414                    FT_Memory           memory,
    415                    void*               user )
    416  {
    417    FT_ListNode  cur;
    418 
    419 
    420    if ( !list || !memory )
    421      return;
    422 
    423    cur = list->head;
    424    while ( cur )
    425    {
    426      FT_ListNode  next = cur->next;
    427      void*        data = cur->data;
    428 
    429 
    430      if ( destroy )
    431        destroy( memory, data, user );
    432 
    433      FT_FREE( cur );
    434      cur = next;
    435    }
    436 
    437    list->head = NULL;
    438    list->tail = NULL;
    439  }
    440 
    441 
    442 /* END */