Coverage Report

Created: 2021-08-22 09:07

/src/skia/third_party/externals/freetype/src/base/ftutil.c
Line
Count
Source (jump to first uncovered line)
1
/****************************************************************************
2
 *
3
 * ftutil.c
4
 *
5
 *   FreeType utility file for memory and list management (body).
6
 *
7
 * Copyright (C) 2002-2021 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
76.9k
  {
53
76.9k
    FT_Error    error;
54
76.9k
    FT_Pointer  block = ft_mem_qalloc( memory, size, &error );
55
56
76.9k
    if ( !error && block && size > 0 )
57
76.9k
      FT_MEM_ZERO( block, size );
58
59
76.9k
    *p_error = error;
60
76.9k
    return block;
61
76.9k
  }
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
87.7k
  {
69
87.7k
    FT_Error    error = FT_Err_Ok;
70
87.7k
    FT_Pointer  block = NULL;
71
72
73
87.7k
    if ( size > 0 )
74
87.7k
    {
75
87.7k
      block = memory->alloc( memory, size );
76
87.7k
      if ( !block )
77
0
        error = FT_THROW( Out_Of_Memory );
78
87.7k
    }
79
0
    else if ( size < 0 )
80
0
    {
81
      /* may help catch/prevent security issues */
82
0
      error = FT_THROW( Invalid_Argument );
83
0
    }
84
85
87.7k
    *p_error = error;
86
87.7k
    return block;
87
87.7k
  }
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
26.4k
  {
98
26.4k
    FT_Error  error = FT_Err_Ok;
99
100
101
26.4k
    block = ft_mem_qrealloc( memory, item_size,
102
26.4k
                             cur_count, new_count, block, &error );
103
26.4k
    if ( !error && block && new_count > cur_count )
104
26.4k
      FT_MEM_ZERO( (char*)block + cur_count * item_size,
105
26.4k
                   ( new_count - cur_count ) * item_size );
106
107
26.4k
    *p_error = error;
108
26.4k
    return block;
109
26.4k
  }
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
26.4k
  {
120
26.4k
    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
26.4k
    if ( cur_count < 0 || new_count < 0 || item_size < 0 )
128
0
    {
129
      /* may help catch/prevent nasty security issues */
130
0
      error = FT_THROW( Invalid_Argument );
131
0
    }
132
26.4k
    else if ( new_count == 0 || item_size == 0 )
133
1.10k
    {
134
1.10k
      ft_mem_free( memory, block );
135
1.10k
      block = NULL;
136
1.10k
    }
137
25.3k
    else if ( new_count > FT_INT_MAX / item_size )
138
0
    {
139
0
      error = FT_THROW( Array_Too_Large );
140
0
    }
141
25.3k
    else if ( cur_count == 0 )
142
23.4k
    {
143
23.4k
      FT_ASSERT( !block );
144
145
23.4k
      block = memory->alloc( memory, new_count * item_size );
146
23.4k
      if ( block == NULL )
147
0
        error = FT_THROW( Out_Of_Memory );
148
23.4k
    }
149
1.89k
    else
150
1.89k
    {
151
1.89k
      FT_Pointer  block2;
152
1.89k
      FT_Long     cur_size = cur_count * item_size;
153
1.89k
      FT_Long     new_size = new_count * item_size;
154
155
156
1.89k
      block2 = memory->realloc( memory, cur_size, new_size, block );
157
1.89k
      if ( !block2 )
158
0
        error = FT_THROW( Out_Of_Memory );
159
1.89k
      else
160
1.89k
        block = block2;
161
1.89k
    }
162
163
26.4k
    *p_error = error;
164
26.4k
    return block;
165
26.4k
  }
166
167
168
  FT_BASE_DEF( void )
169
  ft_mem_free( FT_Memory   memory,
170
               const void *P )
171
1.03M
  {
172
1.03M
    if ( P )
173
111k
      memory->free( memory, (void*)P );
174
1.03M
  }
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
554
  {
183
554
    FT_Error    error;
184
554
    FT_Pointer  p = ft_mem_qalloc( memory, (FT_Long)size, &error );
185
186
187
554
    if ( !error && address && size > 0 )
188
554
      ft_memcpy( p, address, size );
189
190
554
    *p_error = error;
191
554
    return p;
192
554
  }
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
554
  {
200
554
    FT_ULong  len = str ? (FT_ULong)ft_strlen( str ) + 1
201
0
                        : 0;
202
203
204
554
    return ft_mem_dup( memory, str, len, p_error );
205
554
  }
206
207
208
  FT_BASE_DEF( FT_Int )
209
  ft_mem_strcpyn( char*        dst,
210
                  const char*  src,
211
                  FT_ULong     size )
212
0
  {
213
0
    while ( size > 1 && *src != 0 )
214
0
    {
215
0
      *dst++ = *src++;
216
0
      size--;
217
0
    }
218
219
0
    *dst = 0;  /* always zero-terminate */
220
221
0
    return *src != 0;
222
0
  }
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
2.03k
  {
246
2.03k
    FT_ListNode  cur;
247
248
249
2.03k
    if ( !list )
250
0
      return NULL;
251
252
2.03k
    cur = list->head;
253
2.03k
    while ( cur )
254
2.03k
    {
255
2.03k
      if ( cur->data == data )
256
2.03k
        return cur;
257
258
5
      cur = cur->next;
259
5
    }
260
261
0
    return NULL;
262
2.03k
  }
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
4.05k
  {
271
4.05k
    FT_ListNode  before;
272
273
274
4.05k
    if ( !list || !node )
275
0
      return;
276
277
4.05k
    before = list->tail;
278
279
4.05k
    node->next = NULL;
280
4.05k
    node->prev = before;
281
282
4.05k
    if ( before )
283
5
      before->next = node;
284
4.04k
    else
285
4.04k
      list->head = node;
286
287
4.05k
    list->tail = node;
288
4.05k
  }
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
0
  {
297
0
    FT_ListNode  after;
298
299
300
0
    if ( !list || !node )
301
0
      return;
302
303
0
    after = list->head;
304
305
0
    node->next = after;
306
0
    node->prev = NULL;
307
308
0
    if ( !after )
309
0
      list->tail = node;
310
0
    else
311
0
      after->prev = node;
312
313
0
    list->head = node;
314
0
  }
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
2.03k
  {
323
2.03k
    FT_ListNode  before, after;
324
325
326
2.03k
    if ( !list || !node )
327
0
      return;
328
329
2.03k
    before = node->prev;
330
2.03k
    after  = node->next;
331
332
2.03k
    if ( before )
333
5
      before->next = after;
334
2.02k
    else
335
2.02k
      list->head = after;
336
337
2.03k
    if ( after )
338
0
      after->prev = before;
339
2.03k
    else
340
2.03k
      list->tail = before;
341
2.03k
  }
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
0
  {
350
0
    FT_ListNode  before, after;
351
352
353
0
    if ( !list || !node )
354
0
      return;
355
356
0
    before = node->prev;
357
0
    after  = node->next;
358
359
    /* check whether we are already on top of the list */
360
0
    if ( !before )
361
0
      return;
362
363
0
    before->next = after;
364
365
0
    if ( after )
366
0
      after->prev = before;
367
0
    else
368
0
      list->tail = before;
369
370
0
    node->prev       = NULL;
371
0
    node->next       = list->head;
372
0
    list->head->prev = node;
373
0
    list->head       = node;
374
0
  }
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
0
  {
384
0
    FT_ListNode  cur;
385
0
    FT_Error     error = FT_Err_Ok;
386
387
388
0
    if ( !list || !iterator )
389
0
      return FT_THROW( Invalid_Argument );
390
391
0
    cur = list->head;
392
393
0
    while ( cur )
394
0
    {
395
0
      FT_ListNode  next = cur->next;
396
397
398
0
      error = iterator( cur, user );
399
0
      if ( error )
400
0
        break;
401
402
0
      cur = next;
403
0
    }
404
405
0
    return error;
406
0
  }
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
2.04k
  {
417
2.04k
    FT_ListNode  cur;
418
419
420
2.04k
    if ( !list || !memory )
421
0
      return;
422
423
2.04k
    cur = list->head;
424
4.06k
    while ( cur )
425
2.02k
    {
426
2.02k
      FT_ListNode  next = cur->next;
427
2.02k
      void*        data = cur->data;
428
429
430
2.02k
      if ( destroy )
431
2.02k
        destroy( memory, data, user );
432
433
2.02k
      FT_FREE( cur );
434
2.02k
      cur = next;
435
2.02k
    }
436
437
2.04k
    list->head = NULL;
438
2.04k
    list->tail = NULL;
439
2.04k
  }
440
441
442
/* END */