Coverage Report

Created: 2025-07-17 06:39

/src/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
14.7M
{
64
    /* Check for integer multiplication overflow when computing
65
    the full size of the allocation. */
66
14.7M
    if (num > 0 && size > SIZE_MAX / num)
67
0
        return NULL;
68
14.7M
    return allocator->alloc(allocator, size * num);
69
14.7M
}
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
14.9M
{
76
    /* report only fatal errors by default */
77
14.9M
    if (severity == JBIG2_SEVERITY_FATAL) {
78
1.59k
        fprintf(stderr, "jbig2 decoder FATAL ERROR: %s", msg);
79
1.59k
        if (seg_idx != JBIG2_UNKNOWN_SEGMENT_NUMBER)
80
430
            fprintf(stderr, " (segment 0x%02x)", seg_idx);
81
1.59k
        fprintf(stderr, "\n");
82
1.59k
        fflush(stderr);
83
1.59k
    }
84
14.9M
}
85
86
int
87
jbig2_error(Jbig2Ctx *ctx, Jbig2Severity severity, uint32_t segment_number, const char *fmt, ...)
88
14.9M
{
89
14.9M
    char buf[1024];
90
14.9M
    va_list ap;
91
14.9M
    int n;
92
93
14.9M
    va_start(ap, fmt);
94
14.9M
    n = vsnprintf(buf, sizeof(buf), fmt, ap);
95
14.9M
    va_end(ap);
96
14.9M
    if (n < 0 || n == sizeof(buf))
97
0
        strncpy(buf, "failed to generate error string", sizeof(buf));
98
14.9M
    ctx->error_callback(ctx->error_callback_data, buf, severity, segment_number);
99
14.9M
    return -1;
100
14.9M
}
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.86k
{
105
1.86k
    Jbig2Ctx *result;
106
107
1.86k
    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.86k
    if (allocator == NULL)
117
0
        allocator = &jbig2_default_allocator;
118
1.86k
    if (error_callback == NULL)
119
1.86k
        error_callback = &jbig2_default_error;
120
121
1.86k
    result = (Jbig2Ctx *) jbig2_alloc(allocator, sizeof(Jbig2Ctx), 1);
122
1.86k
    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.86k
    result->allocator = allocator;
128
1.86k
    result->options = options;
129
1.86k
    result->global_ctx = (const Jbig2Ctx *)global_ctx;
130
1.86k
    result->error_callback = error_callback;
131
1.86k
    result->error_callback_data = error_callback_data;
132
133
1.86k
    result->state = (options & JBIG2_OPTIONS_EMBEDDED) ? JBIG2_FILE_SEQUENTIAL_HEADER : JBIG2_FILE_HEADER;
134
135
1.86k
    result->buf = NULL;
136
137
1.86k
    result->n_segments = 0;
138
1.86k
    result->n_segments_max = 16;
139
1.86k
    result->segments = jbig2_new(result, Jbig2Segment *, result->n_segments_max);
140
1.86k
    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.86k
    result->segment_index = 0;
146
147
1.86k
    result->current_page = 0;
148
1.86k
    result->max_page_index = 4;
149
1.86k
    result->pages = jbig2_new(result, Jbig2Page, result->max_page_index);
150
1.86k
    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.86k
    {
157
1.86k
        uint32_t index;
158
159
9.30k
        for (index = 0; index < result->max_page_index; index++) {
160
7.44k
            result->pages[index].state = JBIG2_PAGE_FREE;
161
7.44k
            result->pages[index].number = 0;
162
7.44k
            result->pages[index].width = 0;
163
7.44k
            result->pages[index].height = 0xffffffff;
164
7.44k
            result->pages[index].x_resolution = 0;
165
7.44k
            result->pages[index].y_resolution = 0;
166
7.44k
            result->pages[index].stripe_size = 0;
167
7.44k
            result->pages[index].striped = 0;
168
7.44k
            result->pages[index].end_row = 0;
169
7.44k
            result->pages[index].flags = 0;
170
7.44k
            result->pages[index].image = NULL;
171
7.44k
        }
172
1.86k
    }
173
174
1.86k
    return result;
175
1.86k
}
176
177
#define get_uint16(bptr)\
178
1.21M
    (((bptr)[0] << 8) | (bptr)[1])
179
#define get_int16(bptr)\
180
9.89k
    (((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
4.08k
{
187
4.08k
    return get_int16(bptr);
188
4.08k
}
189
190
/* coverity[ -tainted_data_return ] */
191
/* coverity[ -tainted_data_argument : arg-0 ] */
192
uint16_t
193
jbig2_get_uint16(const byte *bptr)
194
13.8k
{
195
13.8k
    return get_uint16(bptr);
196
13.8k
}
197
198
/* coverity[ -tainted_data_return ] */
199
/* coverity[ -tainted_data_argument : arg-0 ] */
200
int32_t
201
jbig2_get_int32(const byte *bptr)
202
5.80k
{
203
5.80k
    return ((int32_t) get_int16(bptr) << 16) | get_uint16(bptr + 2);
204
5.80k
}
205
206
/* coverity[ -tainted_data_return ] */
207
/* coverity[ -tainted_data_argument : arg-0 ] */
208
uint32_t
209
jbig2_get_uint32(const byte *bptr)
210
593k
{
211
593k
    return ((uint32_t) get_uint16(bptr) << 16) | get_uint16(bptr + 2);
212
593k
}
213
214
static size_t
215
jbig2_find_buffer_size(size_t desired)
216
1.86k
{
217
1.86k
    const size_t initial_buf_size = 1024;
218
1.86k
    size_t size = initial_buf_size;
219
220
1.86k
    if (desired == SIZE_MAX)
221
0
        return SIZE_MAX;
222
223
4.69k
    while (size < desired)
224
2.83k
        size <<= 1;
225
226
1.86k
    return size;
227
1.86k
}
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.86k
{
245
1.86k
    if (ctx->buf == NULL) {
246
1.86k
        size_t buf_size = jbig2_find_buffer_size(size);
247
1.86k
        ctx->buf = jbig2_new(ctx, byte, buf_size);
248
1.86k
        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.86k
        ctx->buf_size = buf_size;
252
1.86k
        ctx->buf_rd_ix = 0;
253
1.86k
        ctx->buf_wr_ix = 0;
254
1.86k
    } else if (size > ctx->buf_size - ctx->buf_wr_ix) {
255
0
        size_t already = ctx->buf_wr_ix - ctx->buf_rd_ix;
256
257
0
        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
0
        } else {
260
0
            byte *buf;
261
0
            size_t buf_size;
262
263
0
            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
0
            buf_size = jbig2_find_buffer_size(size + already);
268
269
0
            buf = jbig2_new(ctx, byte, buf_size);
270
0
            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
0
            memcpy(buf, ctx->buf + ctx->buf_rd_ix, already);
274
0
            jbig2_free(ctx->allocator, ctx->buf);
275
0
            ctx->buf = buf;
276
0
            ctx->buf_size = buf_size;
277
0
        }
278
0
        ctx->buf_wr_ix -= ctx->buf_rd_ix;
279
0
        ctx->buf_rd_ix = 0;
280
0
    }
281
282
1.86k
    memcpy(ctx->buf + ctx->buf_wr_ix, data, size);
283
1.86k
    ctx->buf_wr_ix += size;
284
285
    /* data has now been added to buffer */
286
287
130k
    for (;;) {
288
130k
        const byte jbig2_id_string[8] = { 0x97, 0x4a, 0x42, 0x32, 0x0d, 0x0a, 0x1a, 0x0a };
289
130k
        Jbig2Segment *segment;
290
130k
        size_t header_size;
291
130k
        int code;
292
293
130k
        switch (ctx->state) {
294
1.86k
        case JBIG2_FILE_HEADER:
295
            /* D.4.1 */
296
1.86k
            if (ctx->buf_wr_ix - ctx->buf_rd_ix < 9)
297
0
                return 0;
298
1.86k
            if (memcmp(ctx->buf + ctx->buf_rd_ix, jbig2_id_string, 8))
299
3
                return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, JBIG2_UNKNOWN_SEGMENT_NUMBER, "not a JBIG2 file header");
300
            /* D.4.2 */
301
1.85k
            ctx->file_header_flags = ctx->buf[ctx->buf_rd_ix + 8];
302
            /* Check for T.88 amendment 2 */
303
1.85k
            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
1.85k
            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
1.85k
            if (ctx->file_header_flags & 0xFC) {
309
199
                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
199
            }
311
            /* D.4.3 */
312
1.85k
            if (!(ctx->file_header_flags & 2)) {        /* number of pages is known */
313
1.32k
                if (ctx->buf_wr_ix - ctx->buf_rd_ix < 13)
314
0
                    return 0;
315
1.32k
                ctx->n_pages = jbig2_get_uint32(ctx->buf + ctx->buf_rd_ix + 9);
316
1.32k
                ctx->buf_rd_ix += 13;
317
1.32k
                if (ctx->n_pages == 1)
318
53
                    jbig2_error(ctx, JBIG2_SEVERITY_INFO, JBIG2_UNKNOWN_SEGMENT_NUMBER, "file header indicates a single page document");
319
1.27k
                else
320
1.27k
                    jbig2_error(ctx, JBIG2_SEVERITY_INFO, JBIG2_UNKNOWN_SEGMENT_NUMBER, "file header indicates a %d page document", ctx->n_pages);
321
1.32k
            } else {            /* number of pages not known */
322
531
                ctx->n_pages = 0;
323
531
                ctx->buf_rd_ix += 9;
324
531
            }
325
            /* determine the file organization based on the flags - D.4.2 again */
326
1.85k
            if (ctx->file_header_flags & 1) {
327
1.50k
                ctx->state = JBIG2_FILE_SEQUENTIAL_HEADER;
328
1.50k
                jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, JBIG2_UNKNOWN_SEGMENT_NUMBER, "file header indicates sequential organization");
329
1.50k
            } else {
330
354
                ctx->state = JBIG2_FILE_RANDOM_HEADERS;
331
354
                jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, JBIG2_UNKNOWN_SEGMENT_NUMBER, "file header indicates random-access organization");
332
354
            }
333
1.85k
            break;
334
33.9k
        case JBIG2_FILE_SEQUENTIAL_HEADER:
335
95.0k
        case JBIG2_FILE_RANDOM_HEADERS:
336
95.0k
            segment = jbig2_parse_segment_header(ctx, ctx->buf + ctx->buf_rd_ix, ctx->buf_wr_ix - ctx->buf_rd_ix, &header_size);
337
95.0k
            if (segment == NULL)
338
486
                return 0; /* need more data */
339
94.5k
            ctx->buf_rd_ix += header_size;
340
341
94.5k
            if (ctx->n_segments >= ctx->n_segments_max) {
342
556
                Jbig2Segment **segments;
343
344
556
                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
556
                else if (ctx->n_segments_max > (UINT32_MAX >> 2)) {
349
0
                    ctx->n_segments_max = UINT32_MAX;
350
0
                }
351
352
556
                segments = jbig2_renew(ctx, ctx->segments, Jbig2Segment *, (ctx->n_segments_max <<= 2));
353
556
                if (segments == NULL) {
354
5
                    ctx->state = JBIG2_FILE_EOF;
355
5
                    return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "failed to allocate space for more segments");
356
5
                }
357
551
                ctx->segments = segments;
358
551
            }
359
360
94.5k
            ctx->segments[ctx->n_segments++] = segment;
361
94.5k
            if (ctx->state == JBIG2_FILE_RANDOM_HEADERS) {
362
60.8k
                if ((segment->flags & 63) == 51)        /* end of file */
363
41
                    ctx->state = JBIG2_FILE_RANDOM_BODIES;
364
60.8k
            } else              /* JBIG2_FILE_SEQUENTIAL_HEADER */
365
33.7k
                ctx->state = JBIG2_FILE_SEQUENTIAL_BODY;
366
94.5k
            break;
367
33.7k
        case JBIG2_FILE_SEQUENTIAL_BODY:
368
33.9k
        case JBIG2_FILE_RANDOM_BODIES:
369
33.9k
            segment = ctx->segments[ctx->segment_index];
370
371
            /* immediate generic regions may have unknown size */
372
33.9k
            if (segment->data_length == 0xffffffff && (segment->flags & 63) == 38) {
373
10.8k
                byte *s, *e, *p;
374
10.8k
                int mmr;
375
10.8k
                byte mmr_marker[2] = { 0x00, 0x00 };
376
10.8k
                byte arith_marker[2] = { 0xff, 0xac };
377
10.8k
                byte *desired_marker;
378
379
10.8k
                s = p = ctx->buf + ctx->buf_rd_ix;
380
10.8k
                e = ctx->buf + ctx->buf_wr_ix;
381
382
10.8k
                if (e - p < 18)
383
11
                        return 0; /* need more data */
384
385
10.8k
                mmr = p[17] & 1;
386
10.8k
                p += 18;
387
10.8k
                desired_marker = mmr ? mmr_marker : arith_marker;
388
389
                /* look for two byte marker */
390
10.8k
                if (e - p < 2)
391
5
                    return 0; /* need more data */
392
393
2.50M
                while (p[0] != desired_marker[0] || p[1] != desired_marker[1]) {
394
2.49M
                    p++;
395
2.49M
                    if (e - p < 2)
396
95
                        return 0; /* need more data */
397
2.49M
                }
398
10.7k
                p += 2;
399
400
                /* the marker is followed by a four byte row count */
401
10.7k
                if (e - p < 4)
402
8
                        return 0; /* need more data */
403
10.7k
                segment->rows = jbig2_get_uint32(p);
404
10.7k
                p += 4;
405
406
10.7k
                segment->data_length = (size_t) (p - s);
407
10.7k
                jbig2_error(ctx, JBIG2_SEVERITY_INFO, segment->number, "unknown length determined to be %lu", (long) segment->data_length);
408
10.7k
            }
409
23.1k
            else if (segment->data_length > ctx->buf_wr_ix - ctx->buf_rd_ix)
410
814
                    return 0; /* need more data */
411
412
33.0k
            code = jbig2_parse_segment(ctx, segment, ctx->buf + ctx->buf_rd_ix);
413
33.0k
            ctx->buf_rd_ix += segment->data_length;
414
33.0k
            ctx->segment_index++;
415
33.0k
            if (ctx->state == JBIG2_FILE_RANDOM_BODIES) {
416
189
                if (ctx->segment_index == ctx->n_segments)
417
0
                    ctx->state = JBIG2_FILE_EOF;
418
32.8k
            } else {            /* JBIG2_FILE_SEQUENTIAL_BODY */
419
32.8k
                ctx->state = JBIG2_FILE_SEQUENTIAL_HEADER;
420
32.8k
            }
421
33.0k
            if (code < 0) {
422
434
                ctx->state = JBIG2_FILE_EOF;
423
434
                return jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "failed to decode; treating as end of file");
424
434
            }
425
32.6k
            break;
426
32.6k
        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
130k
        }
431
130k
    }
432
1.86k
}
433
434
Jbig2Allocator *
435
jbig2_ctx_free(Jbig2Ctx *ctx)
436
1.86k
{
437
1.86k
    Jbig2Allocator *ca;
438
1.86k
    uint32_t i;
439
440
1.86k
    if (ctx == NULL)
441
0
        return NULL;
442
443
1.86k
    ca = ctx->allocator;
444
1.86k
    jbig2_free(ca, ctx->buf);
445
1.86k
    if (ctx->segments != NULL) {
446
96.4k
        for (i = 0; i < ctx->n_segments; i++)
447
94.5k
            jbig2_free_segment(ctx, ctx->segments[i]);
448
1.86k
        jbig2_free(ca, ctx->segments);
449
1.86k
    }
450
451
1.86k
    if (ctx->pages != NULL) {
452
7.08k
        for (i = 0; i <= ctx->current_page; i++)
453
5.22k
            if (ctx->pages[i].image != NULL)
454
4.06k
                jbig2_image_release(ctx, ctx->pages[i].image);
455
1.86k
        jbig2_free(ca, ctx->pages);
456
1.86k
    }
457
458
1.86k
    jbig2_free(ca, ctx);
459
460
1.86k
    return ca;
461
1.86k
}
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
3.73M
{
489
3.73M
    Jbig2WordStreamBuf *z = (Jbig2WordStreamBuf *) self;
490
3.73M
    uint32_t val = 0;
491
3.73M
    int ret = 0;
492
493
3.73M
    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
3.73M
    if (offset >= z->size) {
497
3.51M
        *word = 0;
498
3.51M
        return 0;
499
3.51M
    }
500
501
218k
    if (offset < z->size) {
502
218k
        val = (uint32_t) z->data[offset] << 24;
503
218k
        ret++;
504
218k
    }
505
218k
    if (offset + 1 < z->size) {
506
215k
        val |= (uint32_t) z->data[offset + 1] << 16;
507
215k
        ret++;
508
215k
    }
509
218k
    if (offset + 2 < z->size) {
510
212k
        val |= (uint32_t) z->data[offset + 2] << 8;
511
212k
        ret++;
512
212k
    }
513
218k
    if (offset + 3 < z->size) {
514
210k
        val |= z->data[offset + 3];
515
210k
        ret++;
516
210k
    }
517
218k
    *word = val;
518
218k
    return ret;
519
3.73M
}
520
521
Jbig2WordStream *
522
jbig2_word_stream_buf_new(Jbig2Ctx *ctx, const byte *data, size_t size)
523
17.8k
{
524
17.8k
    Jbig2WordStreamBuf *result = jbig2_new(ctx, Jbig2WordStreamBuf, 1);
525
526
17.8k
    if (result == NULL) {
527
3
        jbig2_error(ctx, JBIG2_SEVERITY_FATAL, JBIG2_UNKNOWN_SEGMENT_NUMBER, "failed to allocate word stream");
528
3
        return NULL;
529
3
    }
530
531
17.8k
    result->super.get_next_word = jbig2_word_stream_buf_get_next_word;
532
17.8k
    result->data = data;
533
17.8k
    result->size = size;
534
535
17.8k
    return &result->super;
536
17.8k
}
537
538
void
539
jbig2_word_stream_buf_free(Jbig2Ctx *ctx, Jbig2WordStream *ws)
540
18.2k
{
541
18.2k
    jbig2_free(ctx->allocator, ws);
542
18.2k
}
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
14.8M
{
556
14.8M
    allocator->free(allocator, p);
557
14.8M
}
558
559
void *
560
jbig2_realloc(Jbig2Allocator *allocator, void *p, size_t size, size_t num)
561
2.96k
{
562
    /* check for integer multiplication overflow */
563
2.96k
    if (num > 0 && size >= SIZE_MAX / num)
564
0
        return NULL;
565
2.96k
    return allocator->realloc(allocator, p, size * num);
566
2.96k
}