Coverage Report

Created: 2025-06-13 06:50

/src/libtiff/libtiff/tif_unix.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (c) 1988-1997 Sam Leffler
3
 * Copyright (c) 1991-1997 Silicon Graphics, Inc.
4
 *
5
 * Permission to use, copy, modify, distribute, and sell this software and
6
 * its documentation for any purpose is hereby granted without fee, provided
7
 * that (i) the above copyright notices and this permission notice appear in
8
 * all copies of the software and related documentation, and (ii) the names of
9
 * Sam Leffler and Silicon Graphics may not be used in any advertising or
10
 * publicity relating to the software without the specific, prior written
11
 * permission of Sam Leffler and Silicon Graphics.
12
 *
13
 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
14
 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
15
 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
16
 *
17
 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
18
 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
19
 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
20
 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
21
 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
22
 * OF THIS SOFTWARE.
23
 */
24
25
/*
26
 * TIFF Library UNIX-specific Routines. These are should also work with the
27
 * Windows Common RunTime Library.
28
 */
29
30
#ifdef TIFF_DO_NOT_USE_NON_EXT_ALLOC_FUNCTIONS
31
#undef TIFF_DO_NOT_USE_NON_EXT_ALLOC_FUNCTIONS
32
#endif
33
34
#include "tif_config.h"
35
36
#ifdef HAVE_SYS_TYPES_H
37
#include <sys/types.h>
38
#endif
39
40
#include <errno.h>
41
42
#include <stdarg.h>
43
#include <stdlib.h>
44
#include <sys/stat.h>
45
46
#ifdef HAVE_UNISTD_H
47
#include <unistd.h>
48
#endif
49
50
#ifdef HAVE_FCNTL_H
51
#include <fcntl.h>
52
#endif
53
54
#ifdef HAVE_IO_H
55
#include <io.h>
56
#endif
57
58
#include "tiffiop.h"
59
60
0
#define TIFF_IO_MAX 2147483647U
61
62
typedef union fd_as_handle_union
63
{
64
    int fd;
65
    thandle_t h;
66
} fd_as_handle_union_t;
67
68
static tmsize_t _tiffReadProc(thandle_t fd, void *buf, tmsize_t size)
69
0
{
70
0
    fd_as_handle_union_t fdh;
71
0
    const size_t bytes_total = (size_t)size;
72
0
    size_t bytes_read;
73
0
    tmsize_t count = -1;
74
0
    if ((tmsize_t)bytes_total != size)
75
0
    {
76
0
        errno = EINVAL;
77
0
        return (tmsize_t)-1;
78
0
    }
79
0
    fdh.h = fd;
80
0
    for (bytes_read = 0; bytes_read < bytes_total; bytes_read += count)
81
0
    {
82
0
        char *buf_offset = (char *)buf + bytes_read;
83
0
        size_t io_size = bytes_total - bytes_read;
84
0
        if (io_size > TIFF_IO_MAX)
85
0
            io_size = TIFF_IO_MAX;
86
        /* Below is an obvious false positive of Coverity Scan */
87
        /* coverity[overflow_sink] */
88
0
        count = read(fdh.fd, buf_offset, (TIFFIOSize_t)io_size);
89
0
        if (count <= 0)
90
0
            break;
91
0
    }
92
0
    if (count < 0)
93
0
        return (tmsize_t)-1;
94
    /* Silence Coverity Scan warning about unsigned to signed underflow. */
95
    /* coverity[return_overflow:SUPPRESS] */
96
0
    return (tmsize_t)bytes_read;
97
0
}
98
99
static tmsize_t _tiffWriteProc(thandle_t fd, void *buf, tmsize_t size)
100
0
{
101
0
    fd_as_handle_union_t fdh;
102
0
    const size_t bytes_total = (size_t)size;
103
0
    size_t bytes_written;
104
0
    tmsize_t count = -1;
105
0
    if ((tmsize_t)bytes_total != size)
106
0
    {
107
0
        errno = EINVAL;
108
0
        return (tmsize_t)-1;
109
0
    }
110
0
    fdh.h = fd;
111
0
    for (bytes_written = 0; bytes_written < bytes_total; bytes_written += count)
112
0
    {
113
0
        const char *buf_offset = (char *)buf + bytes_written;
114
0
        size_t io_size = bytes_total - bytes_written;
115
0
        if (io_size > TIFF_IO_MAX)
116
0
            io_size = TIFF_IO_MAX;
117
        /* Below is an obvious false positive of Coverity Scan */
118
        /* coverity[overflow_sink] */
119
0
        count = write(fdh.fd, buf_offset, (TIFFIOSize_t)io_size);
120
0
        if (count <= 0)
121
0
            break;
122
0
    }
123
0
    if (count < 0)
124
0
        return (tmsize_t)-1;
125
    /* Silence Coverity Scan warning about unsigned to signed underflow. */
126
    /* coverity[return_overflow:SUPPRESS] */
127
0
    return (tmsize_t)bytes_written;
128
    /* return ((tmsize_t) write(fdh.fd, buf, bytes_total)); */
129
0
}
130
131
static uint64_t _tiffSeekProc(thandle_t fd, uint64_t off, int whence)
132
0
{
133
0
    fd_as_handle_union_t fdh;
134
0
    _TIFF_off_t off_io = (_TIFF_off_t)off;
135
0
    if ((uint64_t)off_io != off)
136
0
    {
137
0
        errno = EINVAL;
138
0
        return (uint64_t)-1; /* this is really gross */
139
0
    }
140
0
    fdh.h = fd;
141
0
    return ((uint64_t)_TIFF_lseek_f(fdh.fd, off_io, whence));
142
0
}
143
144
static int _tiffCloseProc(thandle_t fd)
145
0
{
146
0
    fd_as_handle_union_t fdh;
147
0
    fdh.h = fd;
148
0
    return (close(fdh.fd));
149
0
}
150
151
static uint64_t _tiffSizeProc(thandle_t fd)
152
0
{
153
0
    _TIFF_stat_s sb;
154
0
    fd_as_handle_union_t fdh;
155
0
    fdh.h = fd;
156
0
    if (_TIFF_fstat_f(fdh.fd, &sb) < 0)
157
0
        return (0);
158
0
    else
159
0
        return ((uint64_t)sb.st_size);
160
0
}
161
162
#ifdef HAVE_MMAP
163
#include <sys/mman.h>
164
165
static int _tiffMapProc(thandle_t fd, void **pbase, toff_t *psize)
166
0
{
167
0
    uint64_t size64 = _tiffSizeProc(fd);
168
0
    tmsize_t sizem = (tmsize_t)size64;
169
0
    if (size64 && (uint64_t)sizem == size64)
170
0
    {
171
0
        fd_as_handle_union_t fdh;
172
0
        fdh.h = fd;
173
0
        *pbase =
174
0
            (void *)mmap(0, (size_t)sizem, PROT_READ, MAP_SHARED, fdh.fd, 0);
175
0
        if (*pbase != (void *)-1)
176
0
        {
177
0
            *psize = (tmsize_t)sizem;
178
0
            return (1);
179
0
        }
180
0
    }
181
0
    return (0);
182
0
}
183
184
static void _tiffUnmapProc(thandle_t fd, void *base, toff_t size)
185
0
{
186
0
    (void)fd;
187
0
    (void)munmap(base, (off_t)size);
188
0
}
189
#else  /* !HAVE_MMAP */
190
static int _tiffMapProc(thandle_t fd, void **pbase, toff_t *psize)
191
{
192
    (void)fd;
193
    (void)pbase;
194
    (void)psize;
195
    return (0);
196
}
197
198
static void _tiffUnmapProc(thandle_t fd, void *base, toff_t size)
199
{
200
    (void)fd;
201
    (void)base;
202
    (void)size;
203
}
204
#endif /* !HAVE_MMAP */
205
206
/*
207
 * Open a TIFF file descriptor for read/writing.
208
 */
209
TIFF *TIFFFdOpen(int fd, const char *name, const char *mode)
210
0
{
211
0
    return TIFFFdOpenExt(fd, name, mode, NULL);
212
0
}
213
214
TIFF *TIFFFdOpenExt(int fd, const char *name, const char *mode,
215
                    TIFFOpenOptions *opts)
216
0
{
217
0
    TIFF *tif;
218
219
0
    fd_as_handle_union_t fdh;
220
0
    fdh.fd = fd;
221
0
    tif = TIFFClientOpenExt(name, mode, fdh.h, _tiffReadProc, _tiffWriteProc,
222
0
                            _tiffSeekProc, _tiffCloseProc, _tiffSizeProc,
223
0
                            _tiffMapProc, _tiffUnmapProc, opts);
224
0
    if (tif)
225
0
        tif->tif_fd = fd;
226
0
    return (tif);
227
0
}
228
229
/*
230
 * Open a TIFF file for read/writing.
231
 */
232
TIFF *TIFFOpen(const char *name, const char *mode)
233
0
{
234
0
    return TIFFOpenExt(name, mode, NULL);
235
0
}
236
237
TIFF *TIFFOpenExt(const char *name, const char *mode, TIFFOpenOptions *opts)
238
0
{
239
0
    static const char module[] = "TIFFOpen";
240
0
    int m, fd;
241
0
    TIFF *tif;
242
243
0
    m = _TIFFgetMode(opts, NULL, mode, module);
244
0
    if (m == -1)
245
0
        return ((TIFF *)0);
246
247
/* for cygwin and mingw */
248
#ifdef O_BINARY
249
    m |= O_BINARY;
250
#endif
251
252
0
    fd = open(name, m, 0666);
253
0
    if (fd < 0)
254
0
    {
255
0
        if (errno > 0 && strerror(errno) != NULL)
256
0
        {
257
0
            _TIFFErrorEarly(opts, NULL, module, "%s: %s", name,
258
0
                            strerror(errno));
259
0
        }
260
0
        else
261
0
        {
262
0
            _TIFFErrorEarly(opts, NULL, module, "%s: Cannot open", name);
263
0
        }
264
0
        return ((TIFF *)0);
265
0
    }
266
267
0
    tif = TIFFFdOpenExt((int)fd, name, mode, opts);
268
0
    if (!tif)
269
0
        close(fd);
270
0
    return tif;
271
0
}
272
273
#ifdef _WIN32
274
#include <windows.h>
275
/*
276
 * Open a TIFF file with a Unicode filename, for read/writing.
277
 */
278
TIFF *TIFFOpenW(const wchar_t *name, const char *mode)
279
{
280
    return TIFFOpenWExt(name, mode, NULL);
281
}
282
TIFF *TIFFOpenWExt(const wchar_t *name, const char *mode, TIFFOpenOptions *opts)
283
{
284
    static const char module[] = "TIFFOpenW";
285
    int m, fd;
286
    int mbsize;
287
    char *mbname;
288
    TIFF *tif;
289
290
    m = _TIFFgetMode(opts, NULL, mode, module);
291
    if (m == -1)
292
        return ((TIFF *)0);
293
294
/* for cygwin and mingw */
295
#ifdef O_BINARY
296
    m |= O_BINARY;
297
#endif
298
299
    fd = _wopen(name, m, 0666);
300
    if (fd < 0)
301
    {
302
        _TIFFErrorEarly(opts, NULL, module, "%ls: Cannot open", name);
303
        return ((TIFF *)0);
304
    }
305
306
    mbname = NULL;
307
    mbsize = WideCharToMultiByte(CP_ACP, 0, name, -1, NULL, 0, NULL, NULL);
308
    if (mbsize > 0)
309
    {
310
        mbname = _TIFFmalloc(mbsize);
311
        if (!mbname)
312
        {
313
            _TIFFErrorEarly(
314
                opts, NULL, module,
315
                "Can't allocate space for filename conversion buffer");
316
            return ((TIFF *)0);
317
        }
318
319
        WideCharToMultiByte(CP_ACP, 0, name, -1, mbname, mbsize, NULL, NULL);
320
    }
321
322
    tif = TIFFFdOpenExt((int)fd, (mbname != NULL) ? mbname : "<unknown>", mode,
323
                        opts);
324
325
    _TIFFfree(mbname);
326
327
    if (!tif)
328
        close(fd);
329
    return tif;
330
}
331
#endif
332
333
void *_TIFFmalloc(tmsize_t s)
334
58.6k
{
335
58.6k
    if (s == 0)
336
0
        return ((void *)NULL);
337
338
58.6k
    return (malloc((size_t)s));
339
58.6k
}
340
341
void *_TIFFcalloc(tmsize_t nmemb, tmsize_t siz)
342
0
{
343
0
    if (nmemb == 0 || siz == 0)
344
0
        return ((void *)NULL);
345
346
0
    return calloc((size_t)nmemb, (size_t)siz);
347
0
}
348
349
127k
void _TIFFfree(void *p) { free(p); }
350
351
87.9k
void *_TIFFrealloc(void *p, tmsize_t s) { return (realloc(p, (size_t)s)); }
352
353
87.9k
void _TIFFmemset(void *p, int v, tmsize_t c) { memset(p, v, (size_t)c); }
354
355
void _TIFFmemcpy(void *d, const void *s, tmsize_t c)
356
39.0k
{
357
39.0k
    memcpy(d, s, (size_t)c);
358
39.0k
}
359
360
int _TIFFmemcmp(const void *p1, const void *p2, tmsize_t c)
361
0
{
362
0
    return (memcmp(p1, p2, (size_t)c));
363
0
}
364
365
static void unixWarningHandler(const char *module, const char *fmt, va_list ap)
366
0
{
367
0
    if (module != NULL)
368
0
        fprintf(stderr, "%s: ", module);
369
0
    fprintf(stderr, "Warning, ");
370
0
    vfprintf(stderr, fmt, ap);
371
0
    fprintf(stderr, ".\n");
372
0
}
373
TIFFErrorHandler _TIFFwarningHandler = unixWarningHandler;
374
375
static void unixErrorHandler(const char *module, const char *fmt, va_list ap)
376
0
{
377
0
    if (module != NULL)
378
0
        fprintf(stderr, "%s: ", module);
379
0
    vfprintf(stderr, fmt, ap);
380
0
    fprintf(stderr, ".\n");
381
0
}
382
TIFFErrorHandler _TIFFerrorHandler = unixErrorHandler;