Coverage Report

Created: 2023-06-07 06:20

/src/mupdf/thirdparty/jbig2dec/jbig2.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2001-2023 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.,  39 Mesa Street, Suite 108A, San Francisco,
13
   CA 94129, USA, 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
28.1M
{
64
    /* Check for integer multiplication overflow when computing
65
    the full size of the allocation. */
66
28.1M
    if (num > 0 && size > SIZE_MAX / num)
67
0
        return NULL;
68
28.1M
    return allocator->alloc(allocator, size * num);
69
28.1M
}
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
129M
{
89
129M
    char buf[1024];
90
129M
    va_list ap;
91
129M
    int n;
92
93
129M
    va_start(ap, fmt);
94
129M
    n = vsnprintf(buf, sizeof(buf), fmt, ap);
95
129M
    va_end(ap);
96
129M
    if (n < 0 || n == sizeof(buf))
97
0
        strncpy(buf, "failed to generate error string", sizeof(buf));
98
129M
    ctx->error_callback(ctx->error_callback_data, buf, severity, segment_number);
99
129M
    return -1;
100
129M
}
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
1.09k
{
105
1.09k
    Jbig2Ctx *result;
106
107
1.09k
    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
1.09k
    if (allocator == NULL)
117
0
        allocator = &jbig2_default_allocator;
118
1.09k
    if (error_callback == NULL)
119
0
        error_callback = &jbig2_default_error;
120
121
1.09k
    result = (Jbig2Ctx *) jbig2_alloc(allocator, sizeof(Jbig2Ctx), 1);
122
1.09k
    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
1.09k
    result->allocator = allocator;
128
1.09k
    result->options = options;
129
1.09k
    result->global_ctx = (const Jbig2Ctx *)global_ctx;
130
1.09k
    result->error_callback = error_callback;
131
1.09k
    result->error_callback_data = error_callback_data;
132
133
1.09k
    result->state = (options & JBIG2_OPTIONS_EMBEDDED) ? JBIG2_FILE_SEQUENTIAL_HEADER : JBIG2_FILE_HEADER;
134
135
1.09k
    result->buf = NULL;
136
137
1.09k
    result->n_segments = 0;
138
1.09k
    result->n_segments_max = 16;
139
1.09k
    result->segments = jbig2_new(result, Jbig2Segment *, result->n_segments_max);
140
1.09k
    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
1.09k
    result->segment_index = 0;
146
147
1.09k
    result->current_page = 0;
148
1.09k
    result->max_page_index = 4;
149
1.09k
    result->pages = jbig2_new(result, Jbig2Page, result->max_page_index);
150
1.09k
    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
1.09k
    {
157
1.09k
        uint32_t index;
158
159
5.47k
        for (index = 0; index < result->max_page_index; index++) {
160
4.38k
            result->pages[index].state = JBIG2_PAGE_FREE;
161
4.38k
            result->pages[index].number = 0;
162
4.38k
            result->pages[index].width = 0;
163
4.38k
            result->pages[index].height = 0xffffffff;
164
4.38k
            result->pages[index].x_resolution = 0;
165
4.38k
            result->pages[index].y_resolution = 0;
166
4.38k
            result->pages[index].stripe_size = 0;
167
4.38k
            result->pages[index].striped = 0;
168
4.38k
            result->pages[index].end_row = 0;
169
4.38k
            result->pages[index].flags = 0;
170
4.38k
            result->pages[index].image = NULL;
171
4.38k
        }
172
1.09k
    }
173
174
1.09k
    return result;
175
1.09k
}
176
177
#define get_uint16(bptr)\
178
264k
    (((bptr)[0] << 8) | (bptr)[1])
179
#define get_int16(bptr)\
180
132
    (((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
102
{
187
102
    return get_int16(bptr);
188
102
}
189
190
/* coverity[ -tainted_data_return ] */
191
/* coverity[ -tainted_data_argument : arg-0 ] */
192
uint16_t
193
jbig2_get_uint16(const byte *bptr)
194
590
{
195
590
    return get_uint16(bptr);
196
590
}
197
198
/* coverity[ -tainted_data_return ] */
199
/* coverity[ -tainted_data_argument : arg-0 ] */
200
int32_t
201
jbig2_get_int32(const byte *bptr)
202
30
{
203
30
    return ((int32_t) get_int16(bptr) << 16) | get_uint16(bptr + 2);
204
30
}
205
206
/* coverity[ -tainted_data_return ] */
207
/* coverity[ -tainted_data_argument : arg-0 ] */
208
uint32_t
209
jbig2_get_uint32(const byte *bptr)
210
131k
{
211
131k
    return ((uint32_t) get_uint16(bptr) << 16) | get_uint16(bptr + 2);
212
131k
}
213
214
static size_t
215
jbig2_find_buffer_size(size_t desired)
216
1.44k
{
217
1.44k
    const size_t initial_buf_size = 1024;
218
1.44k
    size_t size = initial_buf_size;
219
220
1.44k
    if (desired == SIZE_MAX)
221
0
        return SIZE_MAX;
222
223
3.18k
    while (size < desired)
224
1.74k
        size <<= 1;
225
226
1.44k
    return size;
227
1.44k
}
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
1.80k
{
245
1.80k
    if (ctx->buf == NULL) {
246
1.09k
        size_t buf_size = jbig2_find_buffer_size(size);
247
1.09k
        ctx->buf = jbig2_new(ctx, byte, buf_size);
248
1.09k
        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
1.09k
        ctx->buf_size = buf_size;
252
1.09k
        ctx->buf_rd_ix = 0;
253
1.09k
        ctx->buf_wr_ix = 0;
254
1.09k
    } else if (size > ctx->buf_size - ctx->buf_wr_ix) {
255
346
        size_t already = ctx->buf_wr_ix - ctx->buf_rd_ix;
256
257
346
        if (ctx->buf_rd_ix <= (ctx->buf_size >> 1) && size <= ctx->buf_size - already) {
258
1
            memmove(ctx->buf, ctx->buf + ctx->buf_rd_ix, already);
259
345
        } else {
260
345
            byte *buf;
261
345
            size_t buf_size;
262
263
345
            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
345
            buf_size = jbig2_find_buffer_size(size + already);
268
269
345
            buf = jbig2_new(ctx, byte, buf_size);
270
345
            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
345
            memcpy(buf, ctx->buf + ctx->buf_rd_ix, already);
274
345
            jbig2_free(ctx->allocator, ctx->buf);
275
345
            ctx->buf = buf;
276
345
            ctx->buf_size = buf_size;
277
345
        }
278
346
        ctx->buf_wr_ix -= ctx->buf_rd_ix;
279
346
        ctx->buf_rd_ix = 0;
280
346
    }
281
282
1.80k
    memcpy(ctx->buf + ctx->buf_wr_ix, data, size);
283
1.80k
    ctx->buf_wr_ix += size;
284
285
    /* data has now been added to buffer */
286
287
3.21k
    for (;;) {
288
3.21k
        const byte jbig2_id_string[8] = { 0x97, 0x4a, 0x42, 0x32, 0x0d, 0x0a, 0x1a, 0x0a };
289
3.21k
        Jbig2Segment *segment;
290
3.21k
        size_t header_size;
291
3.21k
        int code;
292
293
3.21k
        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
1.29k
        case JBIG2_FILE_SEQUENTIAL_HEADER:
335
1.29k
        case JBIG2_FILE_RANDOM_HEADERS:
336
1.29k
            segment = jbig2_parse_segment_header(ctx, ctx->buf + ctx->buf_rd_ix, ctx->buf_wr_ix - ctx->buf_rd_ix, &header_size);
337
1.29k
            if (segment == NULL)
338
70
                return 0; /* need more data */
339
1.22k
            ctx->buf_rd_ix += header_size;
340
341
1.22k
            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
1.22k
            ctx->segments[ctx->n_segments++] = segment;
361
1.22k
            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
1.22k
                ctx->state = JBIG2_FILE_SEQUENTIAL_BODY;
366
1.22k
            break;
367
1.91k
        case JBIG2_FILE_SEQUENTIAL_BODY:
368
1.91k
        case JBIG2_FILE_RANDOM_BODIES:
369
1.91k
            segment = ctx->segments[ctx->segment_index];
370
371
            /* immediate generic regions may have unknown size */
372
1.91k
            if (segment->data_length == 0xffffffff && (segment->flags & 63) == 38) {
373
90
                byte *s, *e, *p;
374
90
                int mmr;
375
90
                byte mmr_marker[2] = { 0x00, 0x00 };
376
90
                byte arith_marker[2] = { 0xff, 0xac };
377
90
                byte *desired_marker;
378
379
90
                s = p = ctx->buf + ctx->buf_rd_ix;
380
90
                e = ctx->buf + ctx->buf_wr_ix;
381
382
90
                if (e - p < 18)
383
0
                        return 0; /* need more data */
384
385
90
                mmr = p[17] & 1;
386
90
                p += 18;
387
90
                desired_marker = mmr ? mmr_marker : arith_marker;
388
389
                /* look for two byte marker */
390
90
                if (e - p < 2)
391
0
                    return 0; /* need more data */
392
393
117k
                while (p[0] != desired_marker[0] || p[1] != desired_marker[1]) {
394
117k
                    p++;
395
117k
                    if (e - p < 2)
396
80
                        return 0; /* need more data */
397
117k
                }
398
10
                p += 2;
399
400
                /* the marker is followed by a four byte row count */
401
10
                if (e - p < 4)
402
0
                        return 0; /* need more data */
403
10
                segment->rows = jbig2_get_uint32(p);
404
10
                p += 4;
405
406
10
                segment->data_length = (size_t) (p - s);
407
10
                jbig2_error(ctx, JBIG2_SEVERITY_INFO, segment->number, "unknown length determined to be %lu", (long) segment->data_length);
408
10
            }
409
1.82k
            else if (segment->data_length > ctx->buf_wr_ix - ctx->buf_rd_ix)
410
1.61k
                    return 0; /* need more data */
411
412
224
            code = jbig2_parse_segment(ctx, segment, ctx->buf + ctx->buf_rd_ix);
413
224
            ctx->buf_rd_ix += segment->data_length;
414
224
            ctx->segment_index++;
415
224
            if (ctx->state == JBIG2_FILE_RANDOM_BODIES) {
416
0
                if (ctx->segment_index == ctx->n_segments)
417
0
                    ctx->state = JBIG2_FILE_EOF;
418
224
            } else {            /* JBIG2_FILE_SEQUENTIAL_BODY */
419
224
                ctx->state = JBIG2_FILE_SEQUENTIAL_HEADER;
420
224
            }
421
224
            if (code < 0) {
422
38
                ctx->state = JBIG2_FILE_EOF;
423
38
                return jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "failed to decode; treating as end of file");
424
38
            }
425
186
            break;
426
186
        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
3.21k
        }
431
3.21k
    }
432
1.80k
}
433
434
Jbig2Allocator *
435
jbig2_ctx_free(Jbig2Ctx *ctx)
436
1.09k
{
437
1.09k
    Jbig2Allocator *ca;
438
1.09k
    uint32_t i;
439
440
1.09k
    if (ctx == NULL)
441
0
        return NULL;
442
443
1.09k
    ca = ctx->allocator;
444
1.09k
    jbig2_free(ca, ctx->buf);
445
1.09k
    if (ctx->segments != NULL) {
446
2.31k
        for (i = 0; i < ctx->n_segments; i++)
447
1.22k
            jbig2_free_segment(ctx, ctx->segments[i]);
448
1.09k
        jbig2_free(ca, ctx->segments);
449
1.09k
    }
450
451
1.09k
    if (ctx->pages != NULL) {
452
2.19k
        for (i = 0; i <= ctx->current_page; i++)
453
1.09k
            if (ctx->pages[i].image != NULL)
454
99
                jbig2_image_release(ctx, ctx->pages[i].image);
455
1.09k
        jbig2_free(ca, ctx->pages);
456
1.09k
    }
457
458
1.09k
    jbig2_free(ca, ctx);
459
460
1.09k
    return ca;
461
1.09k
}
462
463
Jbig2GlobalCtx *
464
jbig2_make_global_ctx(Jbig2Ctx *ctx)
465
15
{
466
15
    return (Jbig2GlobalCtx *) ctx;
467
15
}
468
469
Jbig2Allocator *
470
jbig2_global_ctx_free(Jbig2GlobalCtx *global_ctx)
471
15
{
472
15
    return jbig2_ctx_free((Jbig2Ctx *) global_ctx);
473
15
}
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
5.92M
{
489
5.92M
    Jbig2WordStreamBuf *z = (Jbig2WordStreamBuf *) self;
490
5.92M
    uint32_t val = 0;
491
5.92M
    int ret = 0;
492
493
5.92M
    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
5.92M
    if (offset >= z->size) {
497
5.46M
        *word = 0;
498
5.46M
        return 0;
499
5.46M
    }
500
501
463k
    if (offset < z->size) {
502
463k
        val = (uint32_t) z->data[offset] << 24;
503
463k
        ret++;
504
463k
    }
505
463k
    if (offset + 1 < z->size) {
506
463k
        val |= (uint32_t) z->data[offset + 1] << 16;
507
463k
        ret++;
508
463k
    }
509
463k
    if (offset + 2 < z->size) {
510
463k
        val |= (uint32_t) z->data[offset + 2] << 8;
511
463k
        ret++;
512
463k
    }
513
463k
    if (offset + 3 < z->size) {
514
463k
        val |= z->data[offset + 3];
515
463k
        ret++;
516
463k
    }
517
463k
    *word = val;
518
463k
    return ret;
519
5.92M
}
520
521
Jbig2WordStream *
522
jbig2_word_stream_buf_new(Jbig2Ctx *ctx, const byte *data, size_t size)
523
595
{
524
595
    Jbig2WordStreamBuf *result = jbig2_new(ctx, Jbig2WordStreamBuf, 1);
525
526
595
    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
595
    result->super.get_next_word = jbig2_word_stream_buf_get_next_word;
532
595
    result->data = data;
533
595
    result->size = size;
534
535
595
    return &result->super;
536
595
}
537
538
void
539
jbig2_word_stream_buf_free(Jbig2Ctx *ctx, Jbig2WordStream *ws)
540
595
{
541
595
    jbig2_free(ctx->allocator, ws);
542
595
}
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
28.1M
{
556
28.1M
    allocator->free(allocator, p);
557
28.1M
}
558
559
void *
560
jbig2_realloc(Jbig2Allocator *allocator, void *p, size_t size, size_t num)
561
6
{
562
    /* check for integer multiplication overflow */
563
6
    if (num > 0 && size >= SIZE_MAX / num)
564
0
        return NULL;
565
6
    return allocator->realloc(allocator, p, size * num);
566
6
}