Coverage Report

Created: 2025-07-07 10:01

/work/workdir/UnpackedTarball/fontconfig/src/ftglue.c
Line
Count
Source (jump to first uncovered line)
1
/* ftglue.c: Glue code for compiling the OpenType code from
2
 *           FreeType 1 using only the public API of FreeType 2
3
 *
4
 * By David Turner, The FreeType Project (www.freetype.org)
5
 *
6
 * This code is explicitely put in the public domain
7
 *
8
 * See ftglue.h for more information.
9
 */
10
11
#include "ftglue.h"
12
13
#if 0
14
#  include <stdio.h>
15
#  define LOG(x) ftglue_log x
16
17
static void
18
ftglue_log( const char*   format, ... )
19
{
20
  va_list  ap;
21
22
  va_start( ap, format );
23
  vfprintf( stderr, format, ap );
24
  va_end( ap );
25
}
26
27
#else
28
#  define LOG(x) \
29
1.59k
      do {       \
30
1.59k
      } while (0)
31
#endif
32
33
/* only used internally */
34
static FT_Pointer
35
ftglue_qalloc (FT_Memory memory,
36
               FT_ULong  size,
37
               FT_Error *perror)
38
0
{
39
0
    FT_Error   error = 0;
40
0
    FT_Pointer block = NULL;
41
42
0
    if (size > 0) {
43
0
  block = memory->alloc (memory, size);
44
0
  if (!block)
45
0
      error = FT_Err_Out_Of_Memory;
46
0
    }
47
48
0
    *perror = error;
49
0
    return block;
50
0
}
51
52
#undef QALLOC /* just in case */
53
0
#define QALLOC(ptr, size) ((ptr) = ftglue_qalloc (memory, (size), &error), error != 0)
54
#define FREE(_ptr)                      \
55
0
    do {                                \
56
0
  if ((_ptr)) {                   \
57
0
      ftglue_free (memory, _ptr); \
58
0
      _ptr = NULL;                \
59
0
  }                               \
60
0
    } while (0)
61
62
static void
63
ftglue_free (FT_Memory  memory,
64
             FT_Pointer block)
65
0
{
66
0
    if (block)
67
0
  memory->free (memory, block);
68
0
}
69
70
FTGLUE_APIDEF (FT_Long)
71
ftglue_stream_pos (FT_Stream stream)
72
240
{
73
240
    LOG (("ftglue:stream:pos() -> %ld\n", stream->pos));
74
240
    return stream->pos;
75
240
}
76
77
FTGLUE_APIDEF (FT_Error)
78
ftglue_stream_seek (FT_Stream stream,
79
                    FT_Long   pos)
80
538
{
81
538
    FT_Error error = 0;
82
83
538
    if (stream->read) {
84
0
  if (stream->read (stream, pos, 0, 0))
85
0
      error = FT_Err_Invalid_Stream_Operation;
86
538
    } else if (pos < 0 || (FT_ULong)pos > stream->size)
87
0
  error = FT_Err_Invalid_Stream_Operation;
88
89
538
    if (!error)
90
538
  stream->pos = pos;
91
538
    LOG (("ftglue:stream:seek(%ld) -> %d\n", pos, error));
92
538
    return error;
93
538
}
94
95
FTGLUE_APIDEF (FT_Error)
96
ftglue_stream_frame_enter (FT_Stream stream,
97
                           FT_ULong  count)
98
333
{
99
333
    FT_Error error = FT_Err_Ok;
100
333
    FT_ULong read_bytes;
101
102
333
    if (stream->read) {
103
  /* allocate the frame in memory */
104
0
  FT_Memory memory = stream->memory;
105
106
0
  if (QALLOC (stream->base, count))
107
0
      goto Exit;
108
109
  /* read it */
110
0
  read_bytes = stream->read (stream, stream->pos,
111
0
                             stream->base, count);
112
0
  if (read_bytes < count) {
113
0
      FREE (stream->base);
114
0
      error = FT_Err_Invalid_Stream_Operation;
115
0
  }
116
0
  stream->cursor = stream->base;
117
0
  stream->limit = stream->cursor + count;
118
0
  stream->pos += read_bytes;
119
333
    } else {
120
  /* check current and new position */
121
333
  if (stream->pos >= stream->size ||
122
333
      stream->pos + count > stream->size) {
123
0
      error = FT_Err_Invalid_Stream_Operation;
124
0
      goto Exit;
125
0
  }
126
127
  /* set cursor */
128
333
  stream->cursor = stream->base + stream->pos;
129
333
  stream->limit = stream->cursor + count;
130
333
  stream->pos += count;
131
333
    }
132
133
333
Exit:
134
333
    LOG (("ftglue:stream:frame_enter(%ld) -> %d\n", count, error));
135
333
    return error;
136
333
}
137
138
FTGLUE_APIDEF (void)
139
ftglue_stream_frame_exit (FT_Stream stream)
140
333
{
141
333
    if (stream->read) {
142
0
  FT_Memory memory = stream->memory;
143
144
0
  FREE (stream->base);
145
0
    }
146
333
    stream->cursor = 0;
147
333
    stream->limit = 0;
148
149
333
    LOG (("ftglue:stream:frame_exit()\n"));
150
333
}
151
152
FTGLUE_APIDEF (FT_Error)
153
ftglue_face_goto_table (FT_Face   face,
154
                        FT_ULong  the_tag,
155
                        FT_Stream stream,
156
                        FT_ULong *table_size)
157
39
{
158
39
    FT_Error error;
159
160
39
    LOG (("ftglue_face_goto_table( %p, %c%c%c%c, %p )\n",
161
39
          face,
162
39
          (int)((the_tag >> 24) & 0xFF),
163
39
          (int)((the_tag >> 16) & 0xFF),
164
39
          (int)((the_tag >> 8) & 0xFF),
165
39
          (int)(the_tag & 0xFF),
166
39
          stream));
167
168
39
    if (!FT_IS_SFNT (face)) {
169
0
  LOG (("not a SFNT face !!\n"));
170
0
  error = FT_Err_Invalid_Face_Handle;
171
39
    } else {
172
  /* parse the directory table directly, without using
173
   * FreeType's built-in data structures
174
   */
175
39
  FT_ULong offset = 0, sig;
176
39
  FT_UInt  count, nn;
177
178
39
  if (FILE_Seek (0) || ACCESS_Frame (4))
179
0
      goto Exit;
180
181
39
  sig = GET_Tag4();
182
183
39
  FORGET_Frame();
184
185
39
  if (sig == FT_MAKE_TAG ('t', 't', 'c', 'f')) {
186
      /* deal with TrueType collections */
187
188
0
      LOG ((">> This is a TrueType Collection\n"));
189
190
0
      if (FILE_Seek (12 + face->face_index * 4) ||
191
0
          ACCESS_Frame (4))
192
0
    goto Exit;
193
194
0
      offset = GET_ULong();
195
196
0
      FORGET_Frame();
197
0
  }
198
199
39
  LOG (("TrueType offset = %ld\n", offset));
200
201
39
  if (FILE_Seek (offset + 4) ||
202
39
      ACCESS_Frame (2))
203
0
      goto Exit;
204
205
39
  count = GET_UShort();
206
207
39
  FORGET_Frame();
208
209
39
  if (FILE_Seek (offset + 12) ||
210
39
      ACCESS_Frame (count * 16))
211
0
      goto Exit;
212
213
220
  for (nn = 0; nn < count; nn++) {
214
218
      FT_ULong tag = GET_ULong();
215
218
      FT_ULong checksum FC_UNUSED = GET_ULong();
216
218
      FT_ULong start = GET_ULong();
217
218
      FT_ULong size FC_UNUSED = GET_ULong();
218
219
218
      if (tag == the_tag) {
220
37
    LOG (("TrueType table (start: %ld) (size: %ld)\n", start, size));
221
37
    error = ftglue_stream_seek (stream, start);
222
37
    if (table_size)
223
0
        *table_size = size;
224
37
    goto FoundIt;
225
37
      }
226
218
  }
227
2
  error = FT_Err_Table_Missing;
228
229
39
    FoundIt:
230
39
  FORGET_Frame();
231
39
    }
232
233
39
Exit:
234
39
    LOG (("TrueType error=%d\n", error));
235
236
39
    return error;
237
39
}
238
239
#undef QALLOC
240
#include "fcaliastail.h"
241
#undef __ftglue__