Coverage Report

Created: 2022-10-31 07:00

/src/ghostpdl/jbig2dec/jbig2.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2001-2021 Artifex Software, Inc.
2
   All Rights Reserved.
3
4
   This software is provided AS-IS with no warranty, either express or
5
   implied.
6
7
   This software is distributed under license and may not be copied,
8
   modified or distributed except as expressly authorized under the terms
9
   of the license contained in the file LICENSE in this distribution.
10
11
   Refer to licensing information at http://www.artifex.com or contact
12
   Artifex Software, Inc.,  1305 Grant Avenue - Suite 200, Novato,
13
   CA 94945, U.S.A., +1(415)492-9861, for further information.
14
*/
15
16
/*
17
    jbig2dec
18
*/
19
20
#ifdef HAVE_CONFIG_H
21
#include "config.h"
22
#endif
23
#include "os_types.h"
24
25
#include <stdio.h>
26
#include <stdlib.h>
27
#include <stdarg.h>
28
#include <string.h>
29
#include <limits.h>
30
31
#include "jbig2.h"
32
#include "jbig2_priv.h"
33
#include "jbig2_image.h"
34
#include "jbig2_page.h"
35
#include "jbig2_segment.h"
36
37
static void *
38
jbig2_default_alloc(Jbig2Allocator *allocator, size_t size)
39
0
{
40
0
    return malloc(size);
41
0
}
42
43
static void
44
jbig2_default_free(Jbig2Allocator *allocator, void *p)
45
0
{
46
0
    free(p);
47
0
}
48
49
static void *
50
jbig2_default_realloc(Jbig2Allocator *allocator, void *p, size_t size)
51
0
{
52
0
    return realloc(p, size);
53
0
}
54
55
static Jbig2Allocator jbig2_default_allocator = {
56
    jbig2_default_alloc,
57
    jbig2_default_free,
58
    jbig2_default_realloc
59
};
60
61
void *
62
jbig2_alloc(Jbig2Allocator *allocator, size_t size, size_t num)
63
1.44k
{
64
    /* Check for integer multiplication overflow when computing
65
    the full size of the allocation. */
66
1.44k
    if (num > 0 && size > SIZE_MAX / num)
67
0
        return NULL;
68
1.44k
    return allocator->alloc(allocator, size * num);
69
1.44k
}
70
71
/* jbig2_free and jbig2_realloc moved to the bottom of this file */
72
73
static void
74
jbig2_default_error(void *data, const char *msg, Jbig2Severity severity, uint32_t seg_idx)
75
0
{
76
    /* report only fatal errors by default */
77
0
    if (severity == JBIG2_SEVERITY_FATAL) {
78
0
        fprintf(stderr, "jbig2 decoder FATAL ERROR: %s", msg);
79
0
        if (seg_idx != JBIG2_UNKNOWN_SEGMENT_NUMBER)
80
0
            fprintf(stderr, " (segment 0x%02x)", seg_idx);
81
0
        fprintf(stderr, "\n");
82
0
        fflush(stderr);
83
0
    }
84
0
}
85
86
int
87
jbig2_error(Jbig2Ctx *ctx, Jbig2Severity severity, uint32_t segment_number, const char *fmt, ...)
88
902
{
89
902
    char buf[1024];
90
902
    va_list ap;
91
902
    int n;
92
93
902
    va_start(ap, fmt);
94
902
    n = vsnprintf(buf, sizeof(buf), fmt, ap);
95
902
    va_end(ap);
96
902
    if (n < 0 || n == sizeof(buf))
97
0
        strncpy(buf, "failed to generate error string", sizeof(buf));
98
902
    ctx->error_callback(ctx->error_callback_data, buf, severity, segment_number);
99
902
    return -1;
100
902
}
101
102
Jbig2Ctx *
103
jbig2_ctx_new_imp(Jbig2Allocator *allocator, Jbig2Options options, Jbig2GlobalCtx *global_ctx, Jbig2ErrorCallback error_callback, void *error_callback_data, int jbig2_version_major, int jbig2_version_minor)
104
64
{
105
64
    Jbig2Ctx *result;
106
107
64
    if (jbig2_version_major != JBIG2_VERSION_MAJOR || jbig2_version_minor != JBIG2_VERSION_MINOR) {
108
0
        Jbig2Ctx fakectx;
109
0
        fakectx.error_callback = error_callback;
110
0
        fakectx.error_callback_data = error_callback_data;
111
0
        jbig2_error(&fakectx, JBIG2_SEVERITY_FATAL, JBIG2_UNKNOWN_SEGMENT_NUMBER, "incompatible jbig2dec header (%d.%d) and library (%d.%d) versions",
112
0
            jbig2_version_major, jbig2_version_minor, JBIG2_VERSION_MAJOR, JBIG2_VERSION_MINOR);
113
0
        return NULL;
114
0
    }
115
116
64
    if (allocator == NULL)
117
0
        allocator = &jbig2_default_allocator;
118
64
    if (error_callback == NULL)
119
0
        error_callback = &jbig2_default_error;
120
121
64
    result = (Jbig2Ctx *) jbig2_alloc(allocator, sizeof(Jbig2Ctx), 1);
122
64
    if (result == NULL) {
123
0
        error_callback(error_callback_data, "failed to allocate initial context", JBIG2_SEVERITY_FATAL, JBIG2_UNKNOWN_SEGMENT_NUMBER);
124
0
        return NULL;
125
0
    }
126
127
64
    result->allocator = allocator;
128
64
    result->options = options;
129
64
    result->global_ctx = (const Jbig2Ctx *)global_ctx;
130
64
    result->error_callback = error_callback;
131
64
    result->error_callback_data = error_callback_data;
132
133
64
    result->state = (options & JBIG2_OPTIONS_EMBEDDED) ? JBIG2_FILE_SEQUENTIAL_HEADER : JBIG2_FILE_HEADER;
134
135
64
    result->buf = NULL;
136
137
64
    result->n_segments = 0;
138
64
    result->n_segments_max = 16;
139
64
    result->segments = jbig2_new(result, Jbig2Segment *, result->n_segments_max);
140
64
    if (result->segments == NULL) {
141
0
        error_callback(error_callback_data, "failed to allocate initial segments", JBIG2_SEVERITY_FATAL, JBIG2_UNKNOWN_SEGMENT_NUMBER);
142
0
        jbig2_free(allocator, result);
143
0
        return NULL;
144
0
    }
145
64
    result->segment_index = 0;
146
147
64
    result->current_page = 0;
148
64
    result->max_page_index = 4;
149
64
    result->pages = jbig2_new(result, Jbig2Page, result->max_page_index);
150
64
    if (result->pages == NULL) {
151
0
        error_callback(error_callback_data, "failed to allocated initial pages", JBIG2_SEVERITY_FATAL, JBIG2_UNKNOWN_SEGMENT_NUMBER);
152
0
        jbig2_free(allocator, result->segments);
153
0
        jbig2_free(allocator, result);
154
0
        return NULL;
155
0
    }
156
64
    {
157
64
        uint32_t index;
158
159
320
        for (index = 0; index < result->max_page_index; index++) {
160
256
            result->pages[index].state = JBIG2_PAGE_FREE;
161
256
            result->pages[index].number = 0;
162
256
            result->pages[index].width = 0;
163
256
            result->pages[index].height = 0xffffffff;
164
256
            result->pages[index].x_resolution = 0;
165
256
            result->pages[index].y_resolution = 0;
166
256
            result->pages[index].stripe_size = 0;
167
256
            result->pages[index].striped = 0;
168
256
            result->pages[index].end_row = 0;
169
256
            result->pages[index].flags = 0;
170
256
            result->pages[index].image = NULL;
171
256
        }
172
64
    }
173
174
64
    return result;
175
64
}
176
177
#define get_uint16(bptr)\
178
1.66k
    (((bptr)[0] << 8) | (bptr)[1])
179
#define get_int16(bptr)\
180
61
    (((int)get_uint16(bptr) ^ 0x8000) - 0x8000)
181
182
/* coverity[ -tainted_data_return ] */
183
/* coverity[ -tainted_data_argument : arg-0 ] */
184
int16_t
185
jbig2_get_int16(const byte *bptr)
186
61
{
187
61
    return get_int16(bptr);
188
61
}
189
190
/* coverity[ -tainted_data_return ] */
191
/* coverity[ -tainted_data_argument : arg-0 ] */
192
uint16_t
193
jbig2_get_uint16(const byte *bptr)
194
20
{
195
20
    return get_uint16(bptr);
196
20
}
197
198
/* coverity[ -tainted_data_return ] */
199
/* coverity[ -tainted_data_argument : arg-0 ] */
200
int32_t
201
jbig2_get_int32(const byte *bptr)
202
0
{
203
0
    return ((int32_t) get_int16(bptr) << 16) | get_uint16(bptr + 2);
204
0
}
205
206
/* coverity[ -tainted_data_return ] */
207
/* coverity[ -tainted_data_argument : arg-0 ] */
208
uint32_t
209
jbig2_get_uint32(const byte *bptr)
210
794
{
211
794
    return ((uint32_t) get_uint16(bptr) << 16) | get_uint16(bptr + 2);
212
794
}
213
214
static size_t
215
jbig2_find_buffer_size(size_t desired)
216
239
{
217
239
    const size_t initial_buf_size = 1024;
218
239
    size_t size = initial_buf_size;
219
220
239
    if (desired == SIZE_MAX)
221
0
        return SIZE_MAX;
222
223
899
    while (size < desired)
224
660
        size <<= 1;
225
226
239
    return size;
227
239
}
228
229
230
/**
231
 * jbig2_data_in: submit data for decoding
232
 * @ctx: The jbig2dec decoder context
233
 * @data: a pointer to the data buffer
234
 * @size: the size of the data buffer in bytes
235
 *
236
 * Copies the specified data into internal storage and attempts
237
 * to (continue to) parse it as part of a jbig2 data stream.
238
 *
239
 * Return code: 0 on success
240
 *             -1 if there is a parsing error
241
 **/
242
int
243
jbig2_data_in(Jbig2Ctx *ctx, const unsigned char *data, size_t size)
244
564
{
245
564
    if (ctx->buf == NULL) {
246
61
        size_t buf_size = jbig2_find_buffer_size(size);
247
61
        ctx->buf = jbig2_new(ctx, byte, buf_size);
248
61
        if (ctx->buf == NULL) {
249
0
            return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, JBIG2_UNKNOWN_SEGMENT_NUMBER, "failed to allocate buffer when reading data");
250
0
        }
251
61
        ctx->buf_size = buf_size;
252
61
        ctx->buf_rd_ix = 0;
253
61
        ctx->buf_wr_ix = 0;
254
503
    } else if (size > ctx->buf_size - ctx->buf_wr_ix) {
255
178
        size_t already = ctx->buf_wr_ix - ctx->buf_rd_ix;
256
257
178
        if (ctx->buf_rd_ix <= (ctx->buf_size >> 1) && size <= ctx->buf_size - already) {
258
0
            memmove(ctx->buf, ctx->buf + ctx->buf_rd_ix, already);
259
178
        } else {
260
178
            byte *buf;
261
178
            size_t buf_size;
262
263
178
            if (already > SIZE_MAX - size) {
264
0
                return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, JBIG2_UNKNOWN_SEGMENT_NUMBER, "read data causes buffer to grow too large");
265
0
            }
266
267
178
            buf_size = jbig2_find_buffer_size(size + already);
268
269
178
            buf = jbig2_new(ctx, byte, buf_size);
270
178
            if (buf == NULL) {
271
0
                return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, JBIG2_UNKNOWN_SEGMENT_NUMBER, "failed to allocate bigger buffer when reading data");
272
0
            }
273
178
            memcpy(buf, ctx->buf + ctx->buf_rd_ix, already);
274
178
            jbig2_free(ctx->allocator, ctx->buf);
275
178
            ctx->buf = buf;
276
178
            ctx->buf_size = buf_size;
277
178
        }
278
178
        ctx->buf_wr_ix -= ctx->buf_rd_ix;
279
178
        ctx->buf_rd_ix = 0;
280
178
    }
281
282
564
    memcpy(ctx->buf + ctx->buf_wr_ix, data, size);
283
564
    ctx->buf_wr_ix += size;
284
285
    /* data has now been added to buffer */
286
287
824
    for (;;) {
288
824
        const byte jbig2_id_string[8] = { 0x97, 0x4a, 0x42, 0x32, 0x0d, 0x0a, 0x1a, 0x0a };
289
824
        Jbig2Segment *segment;
290
824
        size_t header_size;
291
824
        int code;
292
293
824
        switch (ctx->state) {
294
0
        case JBIG2_FILE_HEADER:
295
            /* D.4.1 */
296
0
            if (ctx->buf_wr_ix - ctx->buf_rd_ix < 9)
297
0
                return 0;
298
0
            if (memcmp(ctx->buf + ctx->buf_rd_ix, jbig2_id_string, 8))
299
0
                return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, JBIG2_UNKNOWN_SEGMENT_NUMBER, "not a JBIG2 file header");
300
            /* D.4.2 */
301
0
            ctx->file_header_flags = ctx->buf[ctx->buf_rd_ix + 8];
302
            /* Check for T.88 amendment 2 */
303
0
            if (ctx->file_header_flags & 0x04)
304
0
                return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, JBIG2_UNKNOWN_SEGMENT_NUMBER, "file header indicates use of 12 adaptive template pixels (NYI)");
305
            /* Check for T.88 amendment 3 */
306
0
            if (ctx->file_header_flags & 0x08)
307
0
                return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, JBIG2_UNKNOWN_SEGMENT_NUMBER, "file header indicates use of colored region segments (NYI)");
308
0
            if (ctx->file_header_flags & 0xFC) {
309
0
                jbig2_error(ctx, JBIG2_SEVERITY_WARNING, JBIG2_UNKNOWN_SEGMENT_NUMBER, "reserved bits (2-7) of file header flags are not zero (0x%02x)", ctx->file_header_flags);
310
0
            }
311
            /* D.4.3 */
312
0
            if (!(ctx->file_header_flags & 2)) {        /* number of pages is known */
313
0
                if (ctx->buf_wr_ix - ctx->buf_rd_ix < 13)
314
0
                    return 0;
315
0
                ctx->n_pages = jbig2_get_uint32(ctx->buf + ctx->buf_rd_ix + 9);
316
0
                ctx->buf_rd_ix += 13;
317
0
                if (ctx->n_pages == 1)
318
0
                    jbig2_error(ctx, JBIG2_SEVERITY_INFO, JBIG2_UNKNOWN_SEGMENT_NUMBER, "file header indicates a single page document");
319
0
                else
320
0
                    jbig2_error(ctx, JBIG2_SEVERITY_INFO, JBIG2_UNKNOWN_SEGMENT_NUMBER, "file header indicates a %d page document", ctx->n_pages);
321
0
            } else {            /* number of pages not known */
322
0
                ctx->n_pages = 0;
323
0
                ctx->buf_rd_ix += 9;
324
0
            }
325
            /* determine the file organization based on the flags - D.4.2 again */
326
0
            if (ctx->file_header_flags & 1) {
327
0
                ctx->state = JBIG2_FILE_SEQUENTIAL_HEADER;
328
0
                jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, JBIG2_UNKNOWN_SEGMENT_NUMBER, "file header indicates sequential organization");
329
0
            } else {
330
0
                ctx->state = JBIG2_FILE_RANDOM_HEADERS;
331
0
                jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, JBIG2_UNKNOWN_SEGMENT_NUMBER, "file header indicates random-access organization");
332
0
            }
333
0
            break;
334
185
        case JBIG2_FILE_SEQUENTIAL_HEADER:
335
185
        case JBIG2_FILE_RANDOM_HEADERS:
336
185
            segment = jbig2_parse_segment_header(ctx, ctx->buf + ctx->buf_rd_ix, ctx->buf_wr_ix - ctx->buf_rd_ix, &header_size);
337
185
            if (segment == NULL)
338
49
                return 0; /* need more data */
339
136
            ctx->buf_rd_ix += header_size;
340
341
136
            if (ctx->n_segments >= ctx->n_segments_max) {
342
0
                Jbig2Segment **segments;
343
344
0
                if (ctx->n_segments_max == UINT32_MAX) {
345
0
                    ctx->state = JBIG2_FILE_EOF;
346
0
                    return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "too many segments in jbig2 image");
347
0
                }
348
0
                else if (ctx->n_segments_max > (UINT32_MAX >> 2)) {
349
0
                    ctx->n_segments_max = UINT32_MAX;
350
0
                }
351
352
0
                segments = jbig2_renew(ctx, ctx->segments, Jbig2Segment *, (ctx->n_segments_max <<= 2));
353
0
                if (segments == NULL) {
354
0
                    ctx->state = JBIG2_FILE_EOF;
355
0
                    return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "failed to allocate space for more segments");
356
0
                }
357
0
                ctx->segments = segments;
358
0
            }
359
360
136
            ctx->segments[ctx->n_segments++] = segment;
361
136
            if (ctx->state == JBIG2_FILE_RANDOM_HEADERS) {
362
0
                if ((segment->flags & 63) == 51)        /* end of file */
363
0
                    ctx->state = JBIG2_FILE_RANDOM_BODIES;
364
0
            } else              /* JBIG2_FILE_SEQUENTIAL_HEADER */
365
136
                ctx->state = JBIG2_FILE_SEQUENTIAL_BODY;
366
136
            break;
367
639
        case JBIG2_FILE_SEQUENTIAL_BODY:
368
639
        case JBIG2_FILE_RANDOM_BODIES:
369
639
            segment = ctx->segments[ctx->segment_index];
370
371
            /* immediate generic regions may have unknown size */
372
639
            if (segment->data_length == 0xffffffff && (segment->flags & 63) == 38) {
373
0
                byte *s, *e, *p;
374
0
                int mmr;
375
0
                byte mmr_marker[2] = { 0x00, 0x00 };
376
0
                byte arith_marker[2] = { 0xff, 0xac };
377
0
                byte *desired_marker;
378
379
0
                s = p = ctx->buf + ctx->buf_rd_ix;
380
0
                e = ctx->buf + ctx->buf_wr_ix;
381
382
0
                if (e - p < 18)
383
0
                        return 0; /* need more data */
384
385
0
                mmr = p[17] & 1;
386
0
                p += 18;
387
0
                desired_marker = mmr ? mmr_marker : arith_marker;
388
389
                /* look for two byte marker */
390
0
                if (e - p < 2)
391
0
                    return 0; /* need more data */
392
393
0
                while (p[0] != desired_marker[0] || p[1] != desired_marker[1]) {
394
0
                    p++;
395
0
                    if (e - p < 2)
396
0
                        return 0; /* need more data */
397
0
                }
398
0
                p += 2;
399
400
                /* the marker is followed by a four byte row count */
401
0
                if (e - p < 4)
402
0
                        return 0; /* need more data */
403
0
                segment->rows = jbig2_get_uint32(p);
404
0
                p += 4;
405
406
0
                segment->data_length = (size_t) (p - s);
407
0
                jbig2_error(ctx, JBIG2_SEVERITY_INFO, segment->number, "unknown length determined to be %lu", (long) segment->data_length);
408
0
            }
409
639
            else if (segment->data_length > ctx->buf_wr_ix - ctx->buf_rd_ix)
410
513
                    return 0; /* need more data */
411
412
126
            code = jbig2_parse_segment(ctx, segment, ctx->buf + ctx->buf_rd_ix);
413
126
            ctx->buf_rd_ix += segment->data_length;
414
126
            ctx->segment_index++;
415
126
            if (ctx->state == JBIG2_FILE_RANDOM_BODIES) {
416
0
                if (ctx->segment_index == ctx->n_segments)
417
0
                    ctx->state = JBIG2_FILE_EOF;
418
126
            } else {            /* JBIG2_FILE_SEQUENTIAL_BODY */
419
126
                ctx->state = JBIG2_FILE_SEQUENTIAL_HEADER;
420
126
            }
421
126
            if (code < 0) {
422
2
                ctx->state = JBIG2_FILE_EOF;
423
2
                return jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "failed to decode; treating as end of file");
424
2
            }
425
124
            break;
426
124
        case JBIG2_FILE_EOF:
427
0
            if (ctx->buf_rd_ix == ctx->buf_wr_ix)
428
0
                return 0;
429
0
            return jbig2_error(ctx, JBIG2_SEVERITY_WARNING, JBIG2_UNKNOWN_SEGMENT_NUMBER, "garbage beyond end of file");
430
824
        }
431
824
    }
432
564
}
433
434
Jbig2Allocator *
435
jbig2_ctx_free(Jbig2Ctx *ctx)
436
64
{
437
64
    Jbig2Allocator *ca;
438
64
    uint32_t i;
439
440
64
    if (ctx == NULL)
441
0
        return NULL;
442
443
64
    ca = ctx->allocator;
444
64
    jbig2_free(ca, ctx->buf);
445
64
    if (ctx->segments != NULL) {
446
200
        for (i = 0; i < ctx->n_segments; i++)
447
136
            jbig2_free_segment(ctx, ctx->segments[i]);
448
64
        jbig2_free(ca, ctx->segments);
449
64
    }
450
451
64
    if (ctx->pages != NULL) {
452
128
        for (i = 0; i <= ctx->current_page; i++)
453
64
            if (ctx->pages[i].image != NULL)
454
61
                jbig2_image_release(ctx, ctx->pages[i].image);
455
64
        jbig2_free(ca, ctx->pages);
456
64
    }
457
458
64
    jbig2_free(ca, ctx);
459
460
64
    return ca;
461
64
}
462
463
Jbig2GlobalCtx *
464
jbig2_make_global_ctx(Jbig2Ctx *ctx)
465
0
{
466
0
    return (Jbig2GlobalCtx *) ctx;
467
0
}
468
469
Jbig2Allocator *
470
jbig2_global_ctx_free(Jbig2GlobalCtx *global_ctx)
471
0
{
472
0
    return jbig2_ctx_free((Jbig2Ctx *) global_ctx);
473
0
}
474
475
/* I'm not committed to keeping the word stream interface. It's handy
476
   when you think you may be streaming your input, but if you're not
477
   (as is currently the case), it just adds complexity.
478
*/
479
480
typedef struct {
481
    Jbig2WordStream super;
482
    const byte *data;
483
    size_t size;
484
} Jbig2WordStreamBuf;
485
486
static int
487
jbig2_word_stream_buf_get_next_word(Jbig2Ctx *ctx, Jbig2WordStream *self, size_t offset, uint32_t *word)
488
257k
{
489
257k
    Jbig2WordStreamBuf *z = (Jbig2WordStreamBuf *) self;
490
257k
    uint32_t val = 0;
491
257k
    int ret = 0;
492
493
257k
    if (self == NULL || word == NULL) {
494
0
        return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, JBIG2_UNKNOWN_SEGMENT_NUMBER, "failed to read next word of stream because stream or output missing");
495
0
    }
496
257k
    if (offset >= z->size) {
497
8
        *word = 0;
498
8
        return 0;
499
8
    }
500
501
257k
    if (offset < z->size) {
502
257k
        val = (uint32_t) z->data[offset] << 24;
503
257k
        ret++;
504
257k
    }
505
257k
    if (offset + 1 < z->size) {
506
257k
        val |= (uint32_t) z->data[offset + 1] << 16;
507
257k
        ret++;
508
257k
    }
509
257k
    if (offset + 2 < z->size) {
510
257k
        val |= (uint32_t) z->data[offset + 2] << 8;
511
257k
        ret++;
512
257k
    }
513
257k
    if (offset + 3 < z->size) {
514
257k
        val |= z->data[offset + 3];
515
257k
        ret++;
516
257k
    }
517
257k
    *word = val;
518
257k
    return ret;
519
257k
}
520
521
Jbig2WordStream *
522
jbig2_word_stream_buf_new(Jbig2Ctx *ctx, const byte *data, size_t size)
523
65
{
524
65
    Jbig2WordStreamBuf *result = jbig2_new(ctx, Jbig2WordStreamBuf, 1);
525
526
65
    if (result == NULL) {
527
0
        jbig2_error(ctx, JBIG2_SEVERITY_FATAL, JBIG2_UNKNOWN_SEGMENT_NUMBER, "failed to allocate word stream");
528
0
        return NULL;
529
0
    }
530
531
65
    result->super.get_next_word = jbig2_word_stream_buf_get_next_word;
532
65
    result->data = data;
533
65
    result->size = size;
534
535
65
    return &result->super;
536
65
}
537
538
void
539
jbig2_word_stream_buf_free(Jbig2Ctx *ctx, Jbig2WordStream *ws)
540
65
{
541
65
    jbig2_free(ctx->allocator, ws);
542
65
}
543
544
/* When Memento is in use, the ->free and ->realloc calls get
545
 * turned into ->Memento_free and ->Memento_realloc, which is
546
 * obviously problematic. Undefine free and realloc here to
547
 * avoid this. */
548
#ifdef MEMENTO
549
#undef free
550
#undef realloc
551
#endif
552
553
void
554
jbig2_free(Jbig2Allocator *allocator, void *p)
555
1.65k
{
556
1.65k
    allocator->free(allocator, p);
557
1.65k
}
558
559
void *
560
jbig2_realloc(Jbig2Allocator *allocator, void *p, size_t size, size_t num)
561
0
{
562
    /* check for integer multiplication overflow */
563
0
    if (num > 0 && size >= SIZE_MAX / num)
564
0
        return NULL;
565
0
    return allocator->realloc(allocator, p, size * num);
566
0
}