Coverage Report

Created: 2026-06-30 11:14

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/work/workdir/UnpackedTarball/fontconfig/src/fccompat.c
Line
Count
Source
1
/*
2
 * fontconfig/src/fccompat.c
3
 *
4
 * Copyright © 2012 Red Hat, Inc.
5
 *
6
 * Author(s):
7
 *  Akira TAGOH
8
 *
9
 * Permission to use, copy, modify, distribute, and sell this software and its
10
 * documentation for any purpose is hereby granted without fee, provided that
11
 * the above copyright notice appear in all copies and that both that
12
 * copyright notice and this permission notice appear in supporting
13
 * documentation, and that the name of the author(s) not be used in
14
 * advertising or publicity pertaining to distribution of the software without
15
 * specific, written prior permission.  The authors make no
16
 * representations about the suitability of this software for any purpose.  It
17
 * is provided "as is" without express or implied warranty.
18
 *
19
 * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
20
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
21
 * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR
22
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
23
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
24
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
25
 * PERFORMANCE OF THIS SOFTWARE.
26
 */
27
28
#include "fcint.h"
29
30
#include <errno.h>
31
#if HAVE_SYS_TYPES_H
32
#  include <sys/types.h>
33
#endif
34
#if HAVE_SYS_STAT_H
35
#  include <sys/stat.h>
36
#endif
37
#if HAVE_FCNTL_H
38
#  include <fcntl.h>
39
#endif
40
#if HAVE_UNISTD_H
41
#  include <unistd.h>
42
#endif
43
#include <locale.h>
44
#include <stdarg.h>
45
#include <stdlib.h>
46
#include <string.h>
47
#include <time.h>
48
49
#ifdef O_CLOEXEC
50
340
#  define FC_O_CLOEXEC O_CLOEXEC
51
#else
52
#  define FC_O_CLOEXEC 0
53
#endif
54
#ifdef O_LARGEFILE
55
338
#  define FC_O_LARGEFILE O_LARGEFILE
56
#else
57
#  define FC_O_LARGEFILE 0
58
#endif
59
#ifdef O_BINARY
60
#  define FC_O_BINARY O_BINARY
61
#else
62
#  define FC_O_BINARY 0
63
#endif
64
#ifdef O_TEMPORARY
65
#  define FC_O_TEMPORARY O_TEMPORARY
66
#else
67
#  define FC_O_TEMPORARY 0
68
#endif
69
#ifdef O_NOINHERIT
70
#  define FC_O_NOINHERIT O_NOINHERIT
71
#else
72
#  define FC_O_NOINHERIT 0
73
#endif
74
75
#ifndef HAVE_UNISTD_H
76
/* Values for the second argument to access. These may be OR'd together. */
77
#  ifndef R_OK
78
#    define R_OK 4 /* Test for read permission.  */
79
#  endif
80
#  ifndef W_OK
81
#    define W_OK 2 /* Test for write permission.  */
82
#  endif
83
#  ifndef F_OK
84
#    define F_OK 0 /* Test for existence.  */
85
#  endif
86
87
typedef int mode_t;
88
#endif /* !HAVE_UNISTD_H */
89
90
#if !defined(HAVE_MKOSTEMP) && !defined(HAVE_MKSTEMP) && !defined(HAVE__MKTEMP_S)
91
static int
92
mkstemp (char *template)
93
{
94
    static const char s[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
95
    int               fd, i;
96
    size_t            l;
97
98
    if (template == NULL) {
99
  errno = EINVAL;
100
  return -1;
101
    }
102
    l = strlen (template);
103
    if (l < 6 || strcmp (&template[l - 6], "XXXXXX") != 0) {
104
  errno = EINVAL;
105
  return -1;
106
    }
107
    do {
108
  errno = 0;
109
  for (i = l - 6; i < l; i++) {
110
      int r = FcRandom();
111
      template[i] = s[r % 62];
112
  }
113
  fd = FcOpen (template, FC_O_BINARY | O_CREAT | O_EXCL | FC_O_TEMPORARY | FC_O_NOINHERIT | O_RDWR, 0600);
114
    } while (fd < 0 && errno == EEXIST);
115
    if (fd >= 0)
116
  errno = 0;
117
118
    return fd;
119
}
120
#  define HAVE_MKSTEMP 1
121
#endif
122
123
int
124
FcOpen (const char *pathname, int flags, ...)
125
338
{
126
338
    int fd = -1;
127
128
338
    if (flags & O_CREAT) {
129
2
  va_list ap;
130
2
  mode_t  mode;
131
132
2
  va_start (ap, flags);
133
2
  mode = (mode_t)va_arg (ap, int);
134
2
  va_end (ap);
135
136
2
  fd = open (pathname, flags | FC_O_CLOEXEC | FC_O_LARGEFILE, mode);
137
336
    } else {
138
336
  fd = open (pathname, flags | FC_O_CLOEXEC | FC_O_LARGEFILE);
139
336
    }
140
141
338
    return fd;
142
338
}
143
144
int
145
FcMakeTempfile (char *template)
146
2
{
147
2
    int fd = -1;
148
149
2
#if HAVE_MKOSTEMP
150
2
    fd = mkostemp (template, FC_O_CLOEXEC);
151
#elif HAVE_MKSTEMP
152
    fd = mkstemp (template);
153
#  ifdef F_DUPFD_CLOEXEC
154
    if (fd != -1) {
155
  int newfd = fcntl (fd, F_DUPFD_CLOEXEC, STDIN_FILENO);
156
157
  close (fd);
158
  fd = newfd;
159
    }
160
#  elif defined(FD_CLOEXEC)
161
    if (fd != -1) {
162
  fcntl (fd, F_SETFD, fcntl (fd, F_GETFD) | FD_CLOEXEC);
163
    }
164
#  endif
165
#elif HAVE__MKTEMP_S
166
    if (_mktemp_s (template, strlen (template) + 1) != 0)
167
  return -1;
168
    fd = FcOpen (template, O_RDWR | O_EXCL | O_CREAT, 0600);
169
#endif
170
171
2
    return fd;
172
2
}
173
174
int32_t
175
FcRandom (void)
176
320
{
177
320
    int32_t result;
178
179
320
#if HAVE_RANDOM_R
180
320
    static struct random_data fcrandbuf;
181
320
    static char               statebuf[256];
182
320
    static FcBool             initialized = FcFalse;
183
#  ifdef _AIX
184
    static char *retval;
185
    long         res;
186
#  endif
187
188
320
    if (initialized != FcTrue) {
189
#  ifdef _AIX
190
  initstate_r (time (NULL), statebuf, 256, &retval, &fcrandbuf);
191
#  else
192
106
  initstate_r (time (NULL), statebuf, 256, &fcrandbuf);
193
106
#  endif
194
106
  initialized = FcTrue;
195
106
    }
196
197
#  ifdef _AIX
198
    random_r (&res, &fcrandbuf);
199
    result = (int32_t)res;
200
#  else
201
320
    random_r (&fcrandbuf, &result);
202
320
#  endif
203
#elif HAVE_RANDOM
204
    static char   statebuf[256];
205
    char         *state;
206
    static FcBool initialized = FcFalse;
207
208
    if (initialized != FcTrue) {
209
  state = initstate (time (NULL), statebuf, 256);
210
  initialized = FcTrue;
211
    } else
212
  state = setstate (statebuf);
213
214
    result = random();
215
216
    setstate (state);
217
#elif HAVE_LRAND48
218
    result = lrand48();
219
#elif HAVE_RAND_R
220
    static unsigned int seed;
221
222
    seed = time (NULL);
223
    result = rand_r (&seed);
224
#elif HAVE_RAND
225
    static FcBool initialized = FcFalse;
226
227
    if (initialized != FcTrue) {
228
  srand (time (NULL));
229
  initialized = FcTrue;
230
    }
231
    result = rand();
232
#else
233
#  error no random number generator function available.
234
#endif
235
236
320
    return result;
237
320
}
238
239
#ifdef _WIN32
240
#  include <direct.h>
241
#  define mkdir(path, mode) _mkdir (path)
242
#endif
243
244
FcBool
245
FcMakeDirectory (const FcChar8 *dir)
246
2
{
247
2
    FcChar8 *parent;
248
2
    FcBool   ret;
249
250
2
    if (strlen ((char *)dir) == 0)
251
0
  return FcFalse;
252
253
2
    parent = FcStrDirname (dir);
254
2
    if (!parent)
255
0
  return FcFalse;
256
2
    if (access ((char *)parent, F_OK) == 0)
257
1
  ret = mkdir ((char *)dir, 0755) == 0 && chmod ((char *)dir, 0755) == 0;
258
1
    else if (access ((char *)parent, F_OK) == -1)
259
1
  ret = FcMakeDirectory (parent) && (mkdir ((char *)dir, 0755) == 0) && chmod ((char *)dir, 0755) == 0;
260
0
    else
261
0
  ret = FcFalse;
262
2
    FcStrFree (parent);
263
2
    return ret;
264
2
}
265
266
ssize_t
267
FcReadLink (const FcChar8 *pathname,
268
            FcChar8       *buf,
269
            size_t         bufsiz)
270
106
{
271
106
#ifdef HAVE_READLINK
272
106
    return readlink ((const char *)pathname, (char *)buf, bufsiz);
273
#else
274
    /* XXX: this function is only used for FcConfigRealFilename() so far
275
     * and returning -1 as an error still just works.
276
     */
277
    errno = ENOSYS;
278
    return -1;
279
#endif
280
106
}
281
282
/* On Windows MingW provides dirent.h / openddir(), but MSVC does not */
283
#ifndef HAVE_DIRENT_H
284
285
struct DIR {
286
    struct dirent   d_ent;
287
    HANDLE          handle;
288
    WIN32_FIND_DATA fdata;
289
    FcBool          valid;
290
};
291
292
FcPrivate DIR *
293
FcCompatOpendirWin32 (const char *dirname)
294
{
295
    size_t len;
296
    char  *name;
297
    DIR   *dir;
298
299
    dir = calloc (1, sizeof (struct DIR));
300
    if (dir == NULL)
301
  return NULL;
302
303
    len = strlen (dirname);
304
    name = malloc (len + 3);
305
    if (name == NULL) {
306
  free (dir);
307
  return NULL;
308
    }
309
    memcpy (name, dirname, len);
310
    name[len++] = FC_DIR_SEPARATOR;
311
    name[len++] = '*';
312
    name[len] = '\0';
313
314
    dir->handle = FindFirstFileEx (name, FindExInfoBasic, &dir->fdata, FindExSearchNameMatch, NULL, 0);
315
316
    free (name);
317
318
    if (!dir->handle) {
319
  free (dir);
320
  dir = NULL;
321
322
  if (GetLastError() == ERROR_FILE_NOT_FOUND)
323
      errno = ENOENT;
324
  else
325
      errno = EACCES;
326
    }
327
328
    dir->valid = FcTrue;
329
    return dir;
330
}
331
332
FcPrivate struct dirent *
333
FcCompatReaddirWin32 (DIR *dir)
334
{
335
    if (dir->valid != FcTrue)
336
  return NULL;
337
338
    dir->d_ent.d_name = dir->fdata.cFileName;
339
340
    if ((dir->fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
341
  dir->d_ent.d_type = DT_DIR;
342
    else if (dir->fdata.dwFileAttributes == FILE_ATTRIBUTE_NORMAL)
343
  dir->d_ent.d_type = DT_REG;
344
    else
345
  dir->d_ent.d_type = DT_UNKNOWN;
346
347
    if (!FindNextFile (dir->handle, &dir->fdata))
348
  dir->valid = FcFalse;
349
350
    return &dir->d_ent;
351
}
352
353
FcPrivate int
354
FcCompatClosedirWin32 (DIR *dir)
355
{
356
    if (dir != NULL && dir->handle != NULL) {
357
  FindClose (dir->handle);
358
  free (dir);
359
    }
360
    return 0;
361
}
362
#endif /* HAVE_DIRENT_H */
363
364
FcLocale
365
FcLocaleCreate (FcLocaleMask mask, const char *locale)
366
0
{
367
#ifdef _WIN32
368
    return _create_locale (mask, locale);
369
#else
370
0
    return newlocale (mask, locale, (locale_t)0);
371
0
#endif
372
0
}
373
374
#ifndef _WIN32
375
FcLocale
376
FcLocaleSetCurrent (FcLocale loc)
377
0
{
378
0
    return uselocale (loc);
379
0
}
380
#endif
381
382
void
383
FcLocaleDestroy (FcLocale locale)
384
0
{
385
#ifdef _WIN32
386
    _free_locale (locale);
387
#else
388
0
    freelocale (locale);
389
0
#endif
390
0
}
391
392
#define __fccompat__
393
#include "fcaliastail.h"
394
#undef __fccompat__