Coverage Report

Created: 2025-06-10 07:27

/src/ghostpdl/pdf/pdf_int.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2018-2025 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
/* The PDF interpreter written in C */
17
18
#include "pdf_int.h"
19
#include "pdf_file.h"
20
#include "strmio.h"
21
#include "stream.h"
22
#include "pdf_misc.h"
23
#include "pdf_path.h"
24
#include "pdf_colour.h"
25
#include "pdf_image.h"
26
#include "pdf_shading.h"
27
#include "pdf_font.h"
28
#include "pdf_font_types.h"
29
#include "pdf_cmap.h"
30
#include "pdf_text.h"
31
#include "pdf_gstate.h"
32
#include "pdf_stack.h"
33
#include "pdf_xref.h"
34
#include "pdf_dict.h"
35
#include "pdf_array.h"
36
#include "pdf_trans.h"
37
#include "pdf_optcontent.h"
38
#include "pdf_sec.h"
39
#include <stdlib.h>
40
41
#include "gsstate.h"    /* for gs_gstate_free */
42
43
/* we use -ve returns for error, 0 for success and +ve for 'take an action' */
44
/* Defining tis return so we do not need to define a new error */
45
5.41M
#define REPAIRED_KEYWORD 1
46
47
/***********************************************************************************/
48
/* 'token' reading functions. Tokens in this sense are PDF logical objects and the */
49
/* related keywords. So that's numbers, booleans, names, strings, dictionaries,    */
50
/* arrays, the  null object and indirect references. The keywords are obj/endobj   */
51
/* stream/endstream, xref, startxref and trailer.                                  */
52
53
/***********************************************************************************/
54
/* Some simple functions to find white space, delimiters and hex bytes             */
55
static bool iswhite(char c)
56
283M
{
57
283M
    if (c == 0x00 || c == 0x09 || c == 0x0a || c == 0x0c || c == 0x0d || c == 0x20)
58
46.5M
        return true;
59
236M
    else
60
236M
        return false;
61
283M
}
62
63
static bool isdelimiter(char c)
64
167M
{
65
167M
    if (c == '/' || c == '(' || c == ')' || c == '[' || c == ']' || c == '<' || c == '>' || c == '{' || c == '}' || c == '%')
66
4.27M
        return true;
67
162M
    else
68
162M
        return false;
69
167M
}
70
71
/* The 'read' functions all return the newly created object on the context's stack
72
 * which means these objects are created with a reference count of 0, and only when
73
 * pushed onto the stack does the reference count become 1, indicating the stack is
74
 * the only reference.
75
 */
76
int pdfi_skip_white(pdf_context *ctx, pdf_c_stream *s)
77
69.6M
{
78
69.6M
    int c;
79
80
84.7M
    do {
81
84.7M
        c = pdfi_read_byte(ctx, s);
82
84.7M
        if (c < 0)
83
20.9k
            return 0;
84
84.7M
    } while (iswhite(c));
85
86
69.6M
    pdfi_unread_byte(ctx, s, (byte)c);
87
69.6M
    return 0;
88
69.6M
}
89
90
int pdfi_skip_eol(pdf_context *ctx, pdf_c_stream *s)
91
156k
{
92
156k
    int c;
93
94
163k
    do {
95
163k
        c = pdfi_read_byte(ctx, s);
96
163k
        if (c < 0 || c == 0x0a)
97
99.7k
            return 0;
98
163k
    } while (c != 0x0d);
99
56.9k
    c = pdfi_read_byte(ctx, s);
100
56.9k
    if (c == 0x0a)
101
56.3k
        return 0;
102
562
    if (c >= 0)
103
558
        pdfi_unread_byte(ctx, s, (byte)c);
104
562
    pdfi_set_warning(ctx, 0, NULL, W_PDF_STREAM_BAD_KEYWORD, "pdfi_skip_eol", NULL);
105
562
    return 0;
106
56.9k
}
107
108
/* Fast(ish) but inaccurate strtof, with Adobe overflow handling,
109
 * lifted from MuPDF. */
110
static float acrobat_compatible_atof(char *s)
111
6.08M
{
112
6.08M
    int neg = 0;
113
6.08M
    int i = 0;
114
115
6.92M
    while (*s == '-') {
116
837k
        neg = 1;
117
837k
        ++s;
118
837k
    }
119
6.08M
    while (*s == '+') {
120
1
        ++s;
121
1
    }
122
123
18.7M
    while (*s >= '0' && *s <= '9') {
124
        /* We deliberately ignore overflow here.
125
         * Tests show that Acrobat handles * overflows in exactly the same way we do:
126
         * 123450000000000000000678 is read as 678.
127
         */
128
12.6M
        i = i * 10 + (*s - '0');
129
12.6M
        ++s;
130
12.6M
    }
131
132
6.08M
    if (*s == '.') {
133
6.07M
        float MAX = (MAX_FLOAT-9)/10;
134
6.07M
        float v = (float)i;
135
6.07M
        float n = 0;
136
6.07M
        float d = 1;
137
6.07M
        ++s;
138
        /* Bug 705211: Ensure that we don't overflow n here - just ignore any
139
         * trailing digits after this. This will be plenty accurate enough. */
140
26.9M
        while (*s >= '0' && *s <= '9' && n <= MAX) {
141
20.8M
            n = 10 * n + (*s - '0');
142
20.8M
            d = 10 * d;
143
20.8M
            ++s;
144
20.8M
        }
145
6.07M
        v += n / d;
146
6.07M
        return neg ? -v : v;
147
6.07M
    } else {
148
10.2k
        return (float)(neg ? -i : i);
149
10.2k
    }
150
6.08M
}
151
152
int pdfi_read_bare_int(pdf_context *ctx, pdf_c_stream *s, int *parsed_int)
153
2.03M
{
154
2.03M
    int index = 0;
155
2.03M
    int int_val = 0;
156
2.03M
    int negative = 0;
157
158
2.03M
restart:
159
2.03M
    pdfi_skip_white(ctx, s);
160
161
8.28M
    do {
162
8.28M
        int c = pdfi_read_byte(ctx, s);
163
8.28M
        if (c == EOFC)
164
208
            break;
165
166
8.28M
        if (c < 0)
167
782
            return_error(gs_error_ioerror);
168
169
8.28M
        if (iswhite(c)) {
170
2.02M
            break;
171
6.25M
        } else if (c == '%' && index == 0) {
172
2.42k
            pdfi_skip_comment(ctx, s);
173
2.42k
            goto restart;
174
6.25M
        } else if (isdelimiter(c)) {
175
941
            pdfi_unread_byte(ctx, s, (byte)c);
176
941
            break;
177
941
        }
178
179
6.25M
        if (c >= '0' && c <= '9') {
180
6.23M
            int_val = int_val*10 + c - '0';
181
6.23M
        } else if (c == '.') {
182
63
            goto error;
183
20.5k
        } else if (c == 'e' || c == 'E') {
184
120
            pdfi_log_info(ctx, "pdfi_read_bare_int", (char *)"Invalid number format: scientific notation\n");
185
120
            goto error;
186
20.4k
        } else if (c == '-') {
187
            /* Any - sign not at the start of the string indicates a malformed number. */
188
41
            if (index != 0 || negative) {
189
6
                pdfi_log_info(ctx, "pdfi_read_bare_int", (char *)"Invalid number format: sign not at the start\n");
190
6
                goto error;
191
6
            }
192
35
            negative = 1;
193
20.4k
        } else if (c == '+') {
194
17.0k
            if (index == 0) {
195
                /* Just drop the + it's pointless, and it'll get in the way
196
                 * of our negation handling for floats. */
197
17.0k
                continue;
198
17.0k
            } else {
199
1
                pdfi_log_info(ctx, "pdfi_read_bare_int", (char *)"Invalid number format: sign not at the start\n");
200
1
                goto error;
201
1
            }
202
17.0k
        } else {
203
3.31k
            if (index > 0) {
204
436
                pdfi_log_info(ctx, "pdfi_read_bare_int", (char *)"Invalid number format: Ignoring missing white space while parsing number\n");
205
436
                goto error;
206
436
            }
207
2.88k
            pdfi_unread_byte(ctx, s, (byte)c);
208
2.88k
            goto error;
209
3.31k
        }
210
6.23M
        if (++index > 255)
211
1
            goto error;
212
6.24M
    } while(1);
213
214
2.02M
    *parsed_int = negative ? -int_val : int_val;
215
2.02M
    if (ctx->args.pdfdebug)
216
0
        outprintf(ctx->memory, " %d", *parsed_int);
217
2.02M
    return (index > 0);
218
219
3.51k
error:
220
3.51k
    *parsed_int = 0;
221
3.51k
    return_error(gs_error_syntaxerror);
222
2.03M
}
223
224
static int pdfi_read_num(pdf_context *ctx, pdf_c_stream *s, uint32_t indirect_num, uint32_t indirect_gen)
225
18.9M
{
226
18.9M
    byte Buffer[256];
227
18.9M
    unsigned short index = 0;
228
18.9M
    bool real = false;
229
18.9M
    bool has_decimal_point = false;
230
18.9M
    bool has_exponent = false;
231
18.9M
    unsigned short exponent_index = 0;
232
18.9M
    pdf_num *num;
233
18.9M
    int code = 0, malformed = false, doubleneg = false, recovered = false, negative = false, overflowed = false;
234
18.9M
    unsigned int int_val = 0;
235
18.9M
    int tenth_max_int = max_int / 10, tenth_max_uint = max_uint / 10;
236
237
18.9M
    pdfi_skip_white(ctx, s);
238
239
95.8M
    do {
240
95.8M
        int c = pdfi_read_byte(ctx, s);
241
95.8M
        if (c == EOFC) {
242
511
            Buffer[index] = 0x00;
243
511
            break;
244
511
        }
245
246
95.8M
        if (c < 0)
247
163
            return_error(gs_error_ioerror);
248
249
95.8M
        if (iswhite(c)) {
250
16.6M
            Buffer[index] = 0x00;
251
16.6M
            break;
252
79.1M
        } else if (isdelimiter(c)) {
253
1.83M
            pdfi_unread_byte(ctx, s, (byte)c);
254
1.83M
            Buffer[index] = 0x00;
255
1.83M
            break;
256
1.83M
        }
257
77.3M
        Buffer[index] = (byte)c;
258
259
77.3M
        if (c >= '0' && c <= '9') {
260
68.9M
            if  (!(malformed && recovered) && !overflowed && !real) {
261
46.7M
                if ((negative && int_val <= tenth_max_int) || (!negative && int_val <= tenth_max_uint))
262
46.7M
                    int_val = int_val*10 + c - '0';
263
60.8k
                else {
264
60.8k
                    if ((code = pdfi_set_error_stop(ctx, gs_note_error(gs_error_syntaxerror), NULL, E_PDF_NUMBEROVERFLOW, "pdfi_read_num", NULL)) < 0) {
265
0
                        return code;
266
0
                    }
267
60.8k
                    overflowed = true;
268
60.8k
                }
269
46.7M
            }
270
68.9M
        } else if (c == '.') {
271
6.27M
            if (has_decimal_point == true) {
272
120k
                if ((code = pdfi_set_error_stop(ctx, gs_note_error(gs_error_syntaxerror), NULL, E_PDF_MALFORMEDNUMBER, "pdfi_read_num", NULL)) < 0) {
273
0
                    return code;
274
0
                }
275
120k
                malformed = true;
276
6.15M
            } else {
277
6.15M
                has_decimal_point = true;
278
6.15M
                real = true;
279
6.15M
            }
280
6.27M
        } else if (c == 'e' || c == 'E') {
281
            /* TODO: technically scientific notation isn't in PDF spec,
282
             * but gs seems to accept it, so we should also?
283
             */
284
31.0k
            if (has_exponent == true) {
285
421
                if ((code = pdfi_set_error_stop(ctx, gs_note_error(gs_error_syntaxerror), NULL, E_PDF_MALFORMEDNUMBER, "pdfi_read_num", NULL)) < 0) {
286
0
                    return code;
287
0
                }
288
421
                malformed = true;
289
30.6k
            } else {
290
30.6k
                pdfi_set_warning(ctx, 0, NULL, W_PDF_NUM_EXPONENT, "pdfi_read_num", NULL);
291
30.6k
                has_exponent = true;
292
30.6k
                exponent_index = index;
293
30.6k
                real = true;
294
30.6k
            }
295
2.06M
        } else if (c == '-') {
296
            /* Any - sign not at the start of the string, or just after an exponent
297
             * indicates a malformed number. */
298
1.61M
            if (!(index == 0 || (has_exponent && index == exponent_index+1))) {
299
224k
                if ((code = pdfi_set_error_stop(ctx, gs_note_error(gs_error_syntaxerror), NULL, E_PDF_MALFORMEDNUMBER, "pdfi_read_num", NULL)) < 0) {
300
0
                    return code;
301
0
                }
302
224k
                if (Buffer[index - 1] != '-') {
303
                    /* We are parsing a number line 123-56. We should continue parsing, but
304
                     * ignore anything from the second -. */
305
57.1k
                    malformed = true;
306
57.1k
                    Buffer[index] = 0;
307
57.1k
                    recovered = true;
308
57.1k
                }
309
224k
            }
310
1.61M
            if (!has_exponent && !(malformed && recovered)) {
311
1.55M
                doubleneg = negative;
312
1.55M
                negative = 1;
313
1.55M
            }
314
1.61M
        } else if (c == '+') {
315
1.99k
            if (index == 0 || (has_exponent && index == exponent_index+1)) {
316
                /* Just drop the + it's pointless, and it'll get in the way
317
                 * of our negation handling for floats. */
318
1.68k
                index--;
319
1.68k
            } else {
320
309
                if ((code = pdfi_set_error_stop(ctx, gs_note_error(gs_error_syntaxerror), NULL, E_PDF_MALFORMEDNUMBER, "pdfi_read_num", NULL)) < 0) {
321
0
                    return code;
322
0
                }
323
309
                if (Buffer[index - 1] != '-') {
324
                    /* We are parsing a number line 123-56. We should continue parsing, but
325
                     * ignore anything from the second -. */
326
304
                    malformed = true;
327
304
                    Buffer[index] = 0;
328
304
                    recovered = true;
329
304
                }
330
309
            }
331
442k
        } else {
332
442k
            if ((code = pdfi_set_error_stop(ctx, gs_note_error(gs_error_syntaxerror), NULL, E_PDF_MISSINGWHITESPACE, "pdfi_read_num", NULL)) < 0) {
333
0
                return code;
334
0
            }
335
442k
            pdfi_unread_byte(ctx, s, (byte)c);
336
442k
            Buffer[index] = 0x00;
337
442k
            break;
338
442k
        }
339
76.8M
        if (++index > 255)
340
837
            return_error(gs_error_syntaxerror);
341
76.8M
    } while(1);
342
343
18.9M
    if (real && (!malformed || (malformed && recovered)))
344
6.11M
        code = pdfi_object_alloc(ctx, PDF_REAL, 0, (pdf_obj **)&num);
345
12.8M
    else
346
12.8M
        code = pdfi_object_alloc(ctx, PDF_INT, 0, (pdf_obj **)&num);
347
18.9M
    if (code < 0)
348
0
        return code;
349
350
18.9M
    if ((malformed && !recovered) || (!real && doubleneg)) {
351
68.3k
        if ((code = pdfi_set_warning_var(ctx, gs_note_error(gs_error_syntaxerror), NULL, E_PDF_MALFORMEDNUMBER, "pdfi_read_num", "Treating malformed number %s as 0", Buffer)) < 0) {
352
0
            goto exit;
353
0
        }
354
68.3k
        num->value.i = 0;
355
18.9M
    } else if (has_exponent) {
356
29.4k
        float f, exp;
357
29.4k
        char *p = strstr((const char *)Buffer, "e");
358
359
29.4k
        if (p == NULL)
360
2.31k
            p = strstr((const char *)Buffer, "E");
361
362
29.4k
        if (p == NULL) {
363
445
            if ((code = pdfi_set_warning_var(ctx, gs_note_error(gs_error_syntaxerror), NULL, E_PDF_MALFORMEDNUMBER, "pdfi_read_num", "Treating malformed float %s as 0", Buffer)) < 0) {
364
0
                goto exit;
365
0
            }
366
445
            num->value.d = 0;
367
29.0k
        } else {
368
29.0k
            p++;
369
370
29.0k
            if (sscanf((char *)p, "%g", &exp) != 1 || exp > 38) {
371
28.2k
                if ((code = pdfi_set_warning_var(ctx, gs_note_error(gs_error_syntaxerror), NULL, E_PDF_MALFORMEDNUMBER, "pdfi_read_num", "Treating malformed float %s as 0", Buffer)) < 0) {
372
0
                    goto exit;
373
0
                }
374
28.2k
                num->value.d = 0;
375
28.2k
            } else {
376
746
                if (sscanf((char *)Buffer, "%g", &f) == 1) {
377
727
                    num->value.d = f;
378
727
                } else {
379
19
                    if ((code = pdfi_set_warning_var(ctx, gs_note_error(gs_error_syntaxerror), NULL, E_PDF_MALFORMEDNUMBER, "pdfi_read_num", "Treating malformed float %s as 0", Buffer)) < 0) {
380
0
                        goto exit;
381
0
                    }
382
19
                    num->value.d = 0;
383
19
                }
384
746
            }
385
29.0k
        }
386
18.8M
    } else if (real) {
387
6.08M
        num->value.d = acrobat_compatible_atof((char *)Buffer);
388
12.7M
    } else {
389
        /* The doubleneg case is taken care of above. */
390
12.7M
        num->value.i = negative ? (int64_t)int_val * -1 : (int64_t)int_val;
391
12.7M
    }
392
18.9M
    if (ctx->args.pdfdebug) {
393
0
        if (real)
394
0
            outprintf(ctx->memory, " %f", num->value.d);
395
0
        else
396
0
            outprintf(ctx->memory, " %"PRIi64, num->value.i);
397
0
    }
398
18.9M
    num->indirect_num = indirect_num;
399
18.9M
    num->indirect_gen = indirect_gen;
400
401
18.9M
    code = pdfi_push(ctx, (pdf_obj *)num);
402
403
18.9M
exit:
404
18.9M
    if (code < 0)
405
947
        pdfi_free_object((pdf_obj *)num);
406
407
18.9M
    return code;
408
18.9M
}
409
410
static int pdfi_read_name(pdf_context *ctx, pdf_c_stream *s, uint32_t indirect_num, uint32_t indirect_gen)
411
6.16M
{
412
6.16M
    char *Buffer, *NewBuf = NULL;
413
6.16M
    unsigned short index = 0;
414
6.16M
    short bytes = 0;
415
6.16M
    uint32_t size = 256;
416
6.16M
    pdf_name *name = NULL;
417
6.16M
    int code;
418
419
6.16M
    Buffer = (char *)gs_alloc_bytes(ctx->memory, size, "pdfi_read_name");
420
6.16M
    if (Buffer == NULL)
421
0
        return_error(gs_error_VMerror);
422
423
43.1M
    do {
424
43.1M
        int c = pdfi_read_byte(ctx, s);
425
43.1M
        if (c < 0)
426
426
            break;
427
428
43.1M
        if (iswhite((char)c)) {
429
4.40M
            Buffer[index] = 0x00;
430
4.40M
            break;
431
38.7M
        } else if (isdelimiter((char)c)) {
432
1.75M
            pdfi_unread_byte(ctx, s, (char)c);
433
1.75M
            Buffer[index] = 0x00;
434
1.75M
            break;
435
1.75M
        }
436
36.9M
        Buffer[index] = (char)c;
437
438
        /* Check for and convert escaped name characters */
439
36.9M
        if (c == '#') {
440
27.3k
            byte NumBuf[2];
441
442
27.3k
            bytes = pdfi_read_bytes(ctx, (byte *)&NumBuf, 1, 2, s);
443
27.3k
            if (bytes < 2 || (!ishex(NumBuf[0]) || !ishex(NumBuf[1]))) {
444
4.88k
                pdfi_set_warning(ctx, 0, NULL, W_PDF_BAD_NAME_ESCAPE, "pdfi_read_name", NULL);
445
4.88k
                pdfi_unread(ctx, s, (byte *)NumBuf, bytes);
446
                /* This leaves the name buffer with a # in it, rather than anything sane! */
447
4.88k
            }
448
22.4k
            else
449
22.4k
                Buffer[index] = (fromhex(NumBuf[0]) << 4) + fromhex(NumBuf[1]);
450
27.3k
        }
451
452
        /* If we ran out of memory, increase the buffer size */
453
36.9M
        if (index++ >= size - 1) {
454
5.14k
            NewBuf = (char *)gs_alloc_bytes(ctx->memory, size + 256, "pdfi_read_name");
455
5.14k
            if (NewBuf == NULL) {
456
0
                gs_free_object(ctx->memory, Buffer, "pdfi_read_name error");
457
0
                return_error(gs_error_VMerror);
458
0
            }
459
5.14k
            memcpy(NewBuf, Buffer, size);
460
5.14k
            gs_free_object(ctx->memory, Buffer, "pdfi_read_name");
461
5.14k
            Buffer = NewBuf;
462
5.14k
            size += 256;
463
5.14k
        }
464
36.9M
    } while(1);
465
466
6.16M
    code = pdfi_object_alloc(ctx, PDF_NAME, index, (pdf_obj **)&name);
467
6.16M
    if (code < 0) {
468
0
        gs_free_object(ctx->memory, Buffer, "pdfi_read_name error");
469
0
        return code;
470
0
    }
471
6.16M
    memcpy(name->data, Buffer, index);
472
6.16M
    name->indirect_num = indirect_num;
473
6.16M
    name->indirect_gen = indirect_gen;
474
475
6.16M
    if (ctx->args.pdfdebug)
476
0
        outprintf(ctx->memory, " /%s", Buffer);
477
478
6.16M
    gs_free_object(ctx->memory, Buffer, "pdfi_read_name");
479
480
6.16M
    code = pdfi_push(ctx, (pdf_obj *)name);
481
482
6.16M
    if (code < 0)
483
0
        pdfi_free_object((pdf_obj *)name);
484
485
6.16M
    return code;
486
6.16M
}
487
488
static int pdfi_read_hexstring(pdf_context *ctx, pdf_c_stream *s, uint32_t indirect_num, uint32_t indirect_gen)
489
193k
{
490
193k
    char *Buffer, *NewBuf = NULL;
491
193k
    unsigned short index = 0;
492
193k
    uint32_t size = 256;
493
193k
    pdf_string *string = NULL;
494
193k
    int code, hex0, hex1;
495
496
193k
    Buffer = (char *)gs_alloc_bytes(ctx->memory, size, "pdfi_read_hexstring");
497
193k
    if (Buffer == NULL)
498
0
        return_error(gs_error_VMerror);
499
500
193k
    if (ctx->args.pdfdebug)
501
0
        outprintf(ctx->memory, " <");
502
503
3.91M
    do {
504
3.91M
        do {
505
3.91M
            hex0 = pdfi_read_byte(ctx, s);
506
3.91M
            if (hex0 < 0)
507
36
                break;
508
3.91M
        } while(iswhite(hex0));
509
3.91M
        if (hex0 < 0)
510
36
            break;
511
512
3.91M
        if (hex0 == '>')
513
172k
            break;
514
515
3.73M
        if (ctx->args.pdfdebug)
516
0
            outprintf(ctx->memory, "%c", (char)hex0);
517
518
3.74M
        do {
519
3.74M
            hex1 = pdfi_read_byte(ctx, s);
520
3.74M
            if (hex1 < 0)
521
38
                break;
522
3.74M
        } while(iswhite(hex1));
523
3.73M
        if (hex1 < 0)
524
38
            break;
525
526
3.73M
        if (hex1 == '>') {
527
            /* PDF Reference 1.7 page 56:
528
             * "If the final digit of a hexadecimal string is missing that is,
529
             * if there is an odd number of digits the final digit is assumed to be 0."
530
             */
531
2.94k
            hex1 = 0x30;
532
2.94k
            if (!ishex(hex0) || !ishex(hex1)) {
533
103
                code = gs_note_error(gs_error_syntaxerror);
534
103
                goto exit;
535
103
            }
536
2.83k
            Buffer[index] = (fromhex(hex0) << 4) + fromhex(hex1);
537
2.83k
            if (ctx->args.pdfdebug)
538
0
                outprintf(ctx->memory, "%c", hex1);
539
2.83k
            break;
540
2.94k
        }
541
542
3.73M
        if (!ishex(hex0) || !ishex(hex1)) {
543
18.0k
            code = gs_note_error(gs_error_syntaxerror);
544
18.0k
            goto exit;
545
18.0k
        }
546
547
3.71M
        if (ctx->args.pdfdebug)
548
0
            outprintf(ctx->memory, "%c", (char)hex1);
549
550
3.71M
        Buffer[index] = (fromhex(hex0) << 4) + fromhex(hex1);
551
552
3.71M
        if (index++ >= size - 1) {
553
10.3k
            NewBuf = (char *)gs_alloc_bytes(ctx->memory, size + 256, "pdfi_read_hexstring");
554
10.3k
            if (NewBuf == NULL) {
555
0
                code = gs_note_error(gs_error_VMerror);
556
0
                goto exit;
557
0
            }
558
10.3k
            memcpy(NewBuf, Buffer, size);
559
10.3k
            gs_free_object(ctx->memory, Buffer, "pdfi_read_hexstring");
560
10.3k
            Buffer = NewBuf;
561
10.3k
            size += 256;
562
10.3k
        }
563
3.71M
    } while(1);
564
565
175k
    if (ctx->args.pdfdebug)
566
0
        outprintf(ctx->memory, ">");
567
568
175k
    code = pdfi_object_alloc(ctx, PDF_STRING, index, (pdf_obj **)&string);
569
175k
    if (code < 0)
570
0
        goto exit;
571
175k
    memcpy(string->data, Buffer, index);
572
175k
    string->indirect_num = indirect_num;
573
175k
    string->indirect_gen = indirect_gen;
574
575
175k
    if (ctx->encryption.is_encrypted && ctx->encryption.decrypt_strings) {
576
144
        code = pdfi_decrypt_string(ctx, string);
577
144
        if (code < 0)
578
0
            return code;
579
144
    }
580
581
175k
    code = pdfi_push(ctx, (pdf_obj *)string);
582
175k
    if (code < 0)
583
0
        pdfi_free_object((pdf_obj *)string);
584
585
193k
 exit:
586
193k
    gs_free_object(ctx->memory, Buffer, "pdfi_read_hexstring");
587
193k
    return code;
588
175k
}
589
590
static int pdfi_read_string(pdf_context *ctx, pdf_c_stream *s, uint32_t indirect_num, uint32_t indirect_gen)
591
1.43M
{
592
1.43M
    char *Buffer, *NewBuf = NULL;
593
1.43M
    unsigned short index = 0;
594
1.43M
    uint32_t size = 256;
595
1.43M
    pdf_string *string = NULL;
596
1.43M
    int c, code, nesting = 0;
597
1.43M
    bool escape = false, skip_eol = false, exit_loop = false;
598
599
1.43M
    Buffer = (char *)gs_alloc_bytes(ctx->memory, size, "pdfi_read_string");
600
1.43M
    if (Buffer == NULL)
601
0
        return_error(gs_error_VMerror);
602
603
52.2M
    do {
604
52.2M
        if (index >= size - 1) {
605
112k
            NewBuf = (char *)gs_alloc_bytes(ctx->memory, size + 256, "pdfi_read_string");
606
112k
            if (NewBuf == NULL) {
607
0
                gs_free_object(ctx->memory, Buffer, "pdfi_read_string error");
608
0
                return_error(gs_error_VMerror);
609
0
            }
610
112k
            memcpy(NewBuf, Buffer, size);
611
112k
            gs_free_object(ctx->memory, Buffer, "pdfi_read_string");
612
112k
            Buffer = NewBuf;
613
112k
            size += 256;
614
112k
        }
615
616
52.2M
        c = pdfi_read_byte(ctx, s);
617
618
52.2M
        if (c < 0) {
619
1.06k
            if (nesting > 0 && (code = pdfi_set_error_stop(ctx, gs_note_error(gs_error_syntaxerror), NULL, E_PDF_UNESCAPEDSTRING, "pdfi_read_string", NULL) < 0)) {
620
0
                gs_free_object(ctx->memory, Buffer, "pdfi_read_string error");
621
0
                return code;
622
0
            }
623
1.06k
            Buffer[index] = 0x00;
624
1.06k
            break;
625
1.06k
        }
626
627
52.2M
        if (skip_eol) {
628
1.06M
            if (c == 0x0a || c == 0x0d)
629
214k
                continue;
630
855k
            skip_eol = false;
631
855k
        }
632
52.0M
        Buffer[index] = (char)c;
633
634
52.0M
        if (escape) {
635
238k
            escape = false;
636
238k
            switch (Buffer[index]) {
637
599
                case 0x0a:
638
2.56k
                case 0x0d:
639
2.56k
                    skip_eol = true;
640
2.56k
                    continue;
641
6.19k
                case 'n':
642
6.19k
                    Buffer[index] = 0x0a;
643
6.19k
                    break;
644
5.28k
                case 'r':
645
5.28k
                    Buffer[index] = 0x0d;
646
5.28k
                    break;
647
1.78k
                case 't':
648
1.78k
                    Buffer[index] = 0x09;
649
1.78k
                    break;
650
2.16k
                case 'b':
651
2.16k
                    Buffer[index] = 0x08;
652
2.16k
                    break;
653
1.80k
                case 'f':
654
1.80k
                    Buffer[index] = 0x0c;
655
1.80k
                    break;
656
22.3k
                case '(':
657
47.1k
                case ')':
658
59.3k
                case '\\':
659
59.3k
                    break;
660
54.3k
                case '0':
661
55.6k
                case '1':
662
72.3k
                case '2':
663
84.0k
                case '3':
664
84.4k
                case '4':
665
84.8k
                case '5':
666
86.7k
                case '6':
667
87.0k
                case '7':
668
87.0k
                {
669
                    /* Octal chars can be 1, 2 or 3 chars in length, terminated either
670
                     * by being 3 chars long, EOFC, or a non-octal char. We do not allow
671
                     * line breaks in the middle of octal chars. */
672
87.0k
                    int c1 = pdfi_read_byte(ctx, s);
673
87.0k
                    c -= '0';
674
87.0k
                    if (c1 < 0) {
675
                        /* Nothing to do, or unread */
676
87.0k
                    } else if (c1 < '0' || c1 > '7') {
677
4.61k
                        pdfi_unread_byte(ctx, s, (char)c1);
678
82.4k
                    } else {
679
82.4k
                        c = c*8 + c1 - '0';
680
82.4k
                        c1 = pdfi_read_byte(ctx, s);
681
82.4k
                        if (c1 < 0) {
682
                            /* Nothing to do, or unread */
683
82.4k
                        } else if (c1 < '0' || c1 > '7') {
684
2.25k
                            pdfi_unread_byte(ctx, s, (char)c1);
685
2.25k
                        } else
686
80.1k
                            c = c*8 + c1 - '0';
687
82.4k
                    }
688
87.0k
                    Buffer[index] = c;
689
87.0k
                    break;
690
86.7k
                }
691
72.3k
                default:
692
                    /* PDF Reference, literal strings, if the character following a
693
                     * escape \ character is not recognised, then it is ignored.
694
                     */
695
72.3k
                    escape = false;
696
72.3k
                    index++;
697
72.3k
                    continue;
698
238k
            }
699
51.7M
        } else {
700
51.7M
            switch(Buffer[index]) {
701
250k
                case 0x0d:
702
250k
                    Buffer[index] = 0x0a;
703
                    /*fallthrough*/
704
852k
                case 0x0a:
705
852k
                    skip_eol = true;
706
852k
                    break;
707
1.61M
                case ')':
708
1.61M
                    if (nesting == 0) {
709
1.43M
                        Buffer[index] = 0x00;
710
1.43M
                        exit_loop = true;
711
1.43M
                    } else
712
181k
                        nesting--;
713
1.61M
                    break;
714
238k
                case '\\':
715
238k
                    escape = true;
716
238k
                    continue;
717
218k
                case '(':
718
218k
                    nesting++;
719
218k
                    break;
720
48.8M
                default:
721
48.8M
                    break;
722
51.7M
            }
723
51.7M
        }
724
725
51.7M
        if (exit_loop)
726
1.43M
            break;
727
728
50.2M
        index++;
729
50.8M
    } while(1);
730
731
1.43M
    code = pdfi_object_alloc(ctx, PDF_STRING, index, (pdf_obj **)&string);
732
1.43M
    if (code < 0) {
733
0
        gs_free_object(ctx->memory, Buffer, "pdfi_read_name error");
734
0
        return code;
735
0
    }
736
1.43M
    memcpy(string->data, Buffer, index);
737
1.43M
    string->indirect_num = indirect_num;
738
1.43M
    string->indirect_gen = indirect_gen;
739
740
1.43M
    gs_free_object(ctx->memory, Buffer, "pdfi_read_string");
741
742
1.43M
    if (ctx->encryption.is_encrypted && ctx->encryption.decrypt_strings) {
743
1.29k
        code = pdfi_decrypt_string(ctx, string);
744
1.29k
        if (code < 0)
745
0
            return code;
746
1.29k
    }
747
748
1.43M
    if (ctx->args.pdfdebug) {
749
0
        int i;
750
0
        outprintf(ctx->memory, " (");
751
0
        for (i=0;i<string->length;i++)
752
0
            outprintf(ctx->memory, "%c", string->data[i]);
753
0
        outprintf(ctx->memory, ")");
754
0
    }
755
756
1.43M
    code = pdfi_push(ctx, (pdf_obj *)string);
757
1.43M
    if (code < 0) {
758
0
        pdfi_free_object((pdf_obj *)string);
759
0
        pdfi_set_error(ctx, code, NULL, 0, "pdfi_read_string", NULL);
760
0
    }
761
762
1.43M
    return code;
763
1.43M
}
764
765
int pdfi_read_dict(pdf_context *ctx, pdf_c_stream *s, uint32_t indirect_num, uint32_t indirect_gen)
766
709
{
767
709
    int code, depth;
768
769
709
    code = pdfi_read_token(ctx, s, indirect_num, indirect_gen);
770
709
    if (code < 0)
771
2
        return code;
772
707
    if (code == 0)
773
0
        return_error(gs_error_syntaxerror);
774
775
707
    if (pdfi_type_of(ctx->stack_top[-1]) != PDF_DICT_MARK)
776
2
        return_error(gs_error_typecheck);
777
705
    depth = pdfi_count_stack(ctx);
778
779
30.2k
    do {
780
30.2k
        code = pdfi_read_token(ctx, s, indirect_num, indirect_gen);
781
30.2k
        if (code < 0)
782
11
            return code;
783
30.2k
        if (code == 0)
784
2
            return_error(gs_error_syntaxerror);
785
30.2k
    } while(pdfi_count_stack(ctx) > depth);
786
692
    return 0;
787
705
}
788
789
int pdfi_skip_comment(pdf_context *ctx, pdf_c_stream *s)
790
117k
{
791
117k
    int c;
792
793
117k
    if (ctx->args.pdfdebug)
794
0
        outprintf (ctx->memory, " %%");
795
796
1.75M
    do {
797
1.75M
        c = pdfi_read_byte(ctx, s);
798
1.75M
        if (c < 0)
799
919
            break;
800
801
1.75M
        if (ctx->args.pdfdebug)
802
0
            outprintf (ctx->memory, "%c", (char)c);
803
804
1.75M
    } while (c != 0x0a && c != 0x0d);
805
806
0
    return 0;
807
117k
}
808
809
#define PARAM1(A) # A,
810
#define PARAM2(A,B) A,
811
static const char pdf_token_strings[][10] = {
812
#include "pdf_tokens.h"
813
};
814
815
9.04M
#define nelems(A) (sizeof(A)/sizeof(A[0]))
816
817
typedef int (*bsearch_comparator)(const void *, const void *);
818
819
int pdfi_read_bare_keyword(pdf_context *ctx, pdf_c_stream *s)
820
257k
{
821
257k
    byte Buffer[256];
822
257k
    int code, index = 0;
823
257k
    int c;
824
257k
    void *t;
825
826
257k
    pdfi_skip_white(ctx, s);
827
828
1.56M
    do {
829
1.56M
        c = pdfi_read_byte(ctx, s);
830
1.56M
        if (c < 0)
831
1.01k
            break;
832
833
1.56M
        if (iswhite(c) || isdelimiter(c)) {
834
256k
            pdfi_unread_byte(ctx, s, (byte)c);
835
256k
            break;
836
256k
        }
837
1.30M
        Buffer[index] = (byte)c;
838
1.30M
        index++;
839
1.30M
    } while (index < 255);
840
841
257k
    if (index >= 255 || index == 0) {
842
1.84k
        if ((code = pdfi_set_error_stop(ctx, gs_note_error(gs_error_syntaxerror), NULL, E_PDF_NOERROR, "pdfi_read_bare_keyword", "")) < 0) {
843
0
            return code;
844
0
        }
845
1.84k
        return TOKEN_INVALID_KEY;
846
1.84k
    }
847
848
255k
    Buffer[index] = 0x00;
849
255k
    t = bsearch((const void *)Buffer,
850
255k
                (const void *)pdf_token_strings[TOKEN_INVALID_KEY+1],
851
255k
                nelems(pdf_token_strings)-(TOKEN_INVALID_KEY+1),
852
255k
                sizeof(pdf_token_strings[0]),
853
255k
                (bsearch_comparator)&strcmp);
854
255k
    if (t == NULL)
855
4.95k
        return TOKEN_INVALID_KEY;
856
857
250k
    if (ctx->args.pdfdebug)
858
0
        outprintf(ctx->memory, " %s\n", Buffer);
859
860
250k
    return (((const char *)t) - pdf_token_strings[0]) / sizeof(pdf_token_strings[0]);
861
255k
}
862
863
static pdf_key lookup_keyword(const byte *Buffer)
864
8.78M
{
865
8.78M
    void *t = bsearch((const void *)Buffer,
866
8.78M
                      (const void *)pdf_token_strings[TOKEN_INVALID_KEY+1],
867
8.78M
                      nelems(pdf_token_strings)-(TOKEN_INVALID_KEY+1),
868
8.78M
                      sizeof(pdf_token_strings[0]),
869
8.78M
                      (bsearch_comparator)&strcmp);
870
8.78M
    if (t == NULL)
871
798k
        return TOKEN_NOT_A_KEYWORD;
872
873
7.98M
    return (pdf_key)((((const char *)t) - pdf_token_strings[0]) /
874
7.98M
                     sizeof(pdf_token_strings[0]));
875
8.78M
}
876
877
/* This function is slightly misnamed. We read 'keywords' from
878
 * the stream (including null, true, false and R), and will usually
879
 * return them directly as TOKENs cast to be pointers. In the event
880
 * that we can't match what we parse to a known keyword, we'll
881
 * instead return a PDF_KEYWORD object. In the even that we parse
882
 * an 'R', we will return a PDF_INDIRECT object.
883
 */
884
static int pdfi_read_keyword(pdf_context *ctx, pdf_c_stream *s, uint32_t indirect_num, uint32_t indirect_gen)
885
8.71M
{
886
8.71M
    byte Buffer[256];
887
8.71M
    unsigned short index = 0;
888
8.71M
    int c, code;
889
8.71M
    pdf_keyword *keyword;
890
8.71M
    pdf_key key;
891
892
8.71M
    pdfi_skip_white(ctx, s);
893
894
41.0M
    do {
895
41.0M
        c = pdfi_read_byte(ctx, s);
896
41.0M
        if (c < 0)
897
10.3k
            break;
898
899
41.0M
        if (iswhite(c) || isdelimiter(c)) {
900
8.66M
            pdfi_unread_byte(ctx, s, (byte)c);
901
8.66M
            break;
902
8.66M
        }
903
32.4M
        Buffer[index] = (byte)c;
904
32.4M
        index++;
905
32.4M
    } while (index < 255);
906
907
8.71M
    if (index >= 255 || index == 0) {
908
46.8k
        if ((code = pdfi_set_error_stop(ctx, gs_note_error(gs_error_syntaxerror), NULL, 0, "pdfi_read_keyword", NULL) < 0)) {
909
0
            return code;
910
0
        }
911
46.8k
        key = (index >= 255 ? TOKEN_TOO_LONG : TOKEN_INVALID_KEY);
912
46.8k
        index = 0;
913
46.8k
        Buffer[0] = 0;
914
8.67M
    } else {
915
8.67M
        Buffer[index] = 0x00;
916
8.67M
        key = lookup_keyword(Buffer);
917
918
8.67M
        if (ctx->args.pdfdebug)
919
0
            outprintf(ctx->memory, " %s\n", Buffer);
920
921
8.67M
        switch (key) {
922
1.15M
            case TOKEN_R:
923
1.15M
            {
924
1.15M
                pdf_indirect_ref *o;
925
1.15M
                uint64_t obj_num;
926
1.15M
                uint32_t gen_num;
927
928
1.15M
                if(pdfi_count_stack(ctx) < 2) {
929
1.64k
                    pdfi_clearstack(ctx);
930
1.64k
                    return_error(gs_error_stackunderflow);
931
1.64k
                }
932
933
1.15M
                if(pdfi_type_of(ctx->stack_top[-1]) != PDF_INT || pdfi_type_of(ctx->stack_top[-2]) != PDF_INT) {
934
2.77k
                    pdfi_clearstack(ctx);
935
2.77k
                    return_error(gs_error_typecheck);
936
2.77k
                }
937
938
1.14M
                gen_num = ((pdf_num *)ctx->stack_top[-1])->value.i;
939
1.14M
                pdfi_pop(ctx, 1);
940
1.14M
                obj_num = ((pdf_num *)ctx->stack_top[-1])->value.i;
941
1.14M
                pdfi_pop(ctx, 1);
942
943
1.14M
                code = pdfi_object_alloc(ctx, PDF_INDIRECT, 0, (pdf_obj **)&o);
944
1.14M
                if (code < 0)
945
0
                    return code;
946
947
1.14M
                o->ref_generation_num = gen_num;
948
1.14M
                o->ref_object_num = obj_num;
949
1.14M
                o->indirect_num = indirect_num;
950
1.14M
                o->indirect_gen = indirect_gen;
951
952
1.14M
                code = pdfi_push(ctx, (pdf_obj *)o);
953
1.14M
                if (code < 0)
954
0
                    pdfi_free_object((pdf_obj *)o);
955
956
1.14M
                return code;
957
1.14M
            }
958
798k
            case TOKEN_NOT_A_KEYWORD:
959
                 /* Unexpected keyword found. We'll allocate an object for the buffer below. */
960
798k
                 break;
961
156k
            case TOKEN_STREAM:
962
156k
                code = pdfi_skip_eol(ctx, s);
963
156k
                if (code < 0)
964
0
                    return code;
965
                /* fallthrough */
966
234k
            case TOKEN_PDF_TRUE:
967
251k
            case TOKEN_PDF_FALSE:
968
257k
            case TOKEN_null:
969
6.72M
            default:
970
                /* This is the fast, common exit case. We just push the key
971
                 * onto the stack. No allocation required. No deallocation
972
                 * in the case of error. */
973
6.72M
                return pdfi_push(ctx, (pdf_obj *)(intptr_t)key);
974
8.67M
        }
975
8.67M
    }
976
977
    /* Unexpected keyword. We can't handle this with the fast no-allocation case. */
978
845k
    code = pdfi_object_alloc(ctx, PDF_KEYWORD, index, (pdf_obj **)&keyword);
979
845k
    if (code < 0)
980
0
        return code;
981
982
845k
    if (index)
983
798k
        memcpy(keyword->data, Buffer, index);
984
985
    /* keyword->length set as part of allocation. */
986
845k
    keyword->indirect_num = indirect_num;
987
845k
    keyword->indirect_gen = indirect_gen;
988
989
845k
    code = pdfi_push(ctx, (pdf_obj *)keyword);
990
845k
    if (code < 0)
991
30
        pdfi_free_object((pdf_obj *)keyword);
992
993
845k
    return code;
994
845k
}
995
996
/* This function reads from the given stream, at the current offset in the stream,
997
 * a single PDF 'token' and returns it on the stack.
998
 */
999
int pdfi_read_token(pdf_context *ctx, pdf_c_stream *s, uint32_t indirect_num, uint32_t indirect_gen)
1000
38.9M
{
1001
38.9M
    int c, code;
1002
1003
39.1M
rescan:
1004
39.1M
    pdfi_skip_white(ctx, s);
1005
1006
39.1M
    c = pdfi_read_byte(ctx, s);
1007
39.1M
    if (c == EOFC)
1008
18.0k
        return 0;
1009
39.1M
    if (c < 0)
1010
799
        return_error(gs_error_ioerror);
1011
1012
39.1M
    switch(c) {
1013
6.49M
        case 0x30:
1014
9.63M
        case 0x31:
1015
11.3M
        case 0x32:
1016
12.8M
        case 0x33:
1017
13.9M
        case 0x34:
1018
14.9M
        case 0x35:
1019
15.7M
        case 0x36:
1020
16.5M
        case 0x37:
1021
17.1M
        case 0x38:
1022
17.4M
        case 0x39:
1023
17.4M
        case '+':
1024
18.8M
        case '-':
1025
18.9M
        case '.':
1026
18.9M
            pdfi_unread_byte(ctx, s, (byte)c);
1027
18.9M
            code = pdfi_read_num(ctx, s, indirect_num, indirect_gen);
1028
18.9M
            if (code < 0)
1029
1.94k
                return code;
1030
18.9M
            break;
1031
18.9M
        case '/':
1032
6.16M
            code = pdfi_read_name(ctx, s, indirect_num, indirect_gen);
1033
6.16M
            if (code < 0)
1034
0
                return code;
1035
6.16M
            return 1;
1036
0
            break;
1037
1.10M
        case '<':
1038
1.10M
            c = pdfi_read_byte(ctx, s);
1039
1.10M
            if (c < 0)
1040
9
                return (gs_error_ioerror);
1041
1.10M
            if (iswhite(c)) {
1042
1.99k
                code = pdfi_skip_white(ctx, s);
1043
1.99k
                if (code < 0)
1044
0
                    return code;
1045
1.99k
                c = pdfi_read_byte(ctx, s);
1046
1.99k
            }
1047
1.10M
            if (c == '<') {
1048
876k
                if (ctx->args.pdfdebug)
1049
0
                    outprintf (ctx->memory, " <<\n");
1050
876k
                if (ctx->object_nesting < MAX_NESTING_DEPTH) {
1051
721k
                    ctx->object_nesting++;
1052
721k
                    code = pdfi_mark_stack(ctx, PDF_DICT_MARK);
1053
721k
                    if (code < 0)
1054
1
                        return code;
1055
721k
                }
1056
154k
                else if ((code = pdfi_set_error_stop(ctx, gs_note_error(gs_error_limitcheck), NULL, E_PDF_NESTEDTOODEEP, "pdfi_read_token", NULL) < 0)) {
1057
0
                    return code;
1058
0
                }
1059
876k
                return 1;
1060
876k
            } else if (c == '>') {
1061
1.93k
                pdfi_unread_byte(ctx, s, (byte)c);
1062
1.93k
                code = pdfi_read_hexstring(ctx, s, indirect_num, indirect_gen);
1063
1.93k
                if (code < 0)
1064
0
                    return code;
1065
1.93k
                return 1;
1066
227k
            } else if (ishex(c)) {
1067
191k
                pdfi_unread_byte(ctx, s, (byte)c);
1068
191k
                code = pdfi_read_hexstring(ctx, s, indirect_num, indirect_gen);
1069
191k
                if (code < 0)
1070
18.1k
                    return code;
1071
191k
            }
1072
35.4k
            else
1073
35.4k
                return_error(gs_error_syntaxerror);
1074
173k
            break;
1075
810k
        case '>':
1076
810k
            c = pdfi_read_byte(ctx, s);
1077
810k
            if (c < 0)
1078
20
                return (gs_error_ioerror);
1079
810k
            if (c == '>') {
1080
757k
                if (ctx->object_nesting > 0) {
1081
700k
                    ctx->object_nesting--;
1082
700k
                    code = pdfi_dict_from_stack(ctx, indirect_num, indirect_gen, false);
1083
700k
                    if (code < 0)
1084
27.5k
                        return code;
1085
700k
                } else {
1086
57.0k
                    if ((code = pdfi_set_error_stop(ctx, gs_note_error(gs_error_unmatchedmark), NULL, E_PDF_UNMATCHEDMARK, "pdfi_read_token", NULL) < 0)) {
1087
0
                        return code;
1088
0
                    }
1089
57.0k
                    goto rescan;
1090
57.0k
                }
1091
672k
                return 1;
1092
757k
            } else {
1093
53.2k
                pdfi_unread_byte(ctx, s, (byte)c);
1094
53.2k
                return_error(gs_error_syntaxerror);
1095
53.2k
            }
1096
0
            break;
1097
1.43M
        case '(':
1098
1.43M
            code = pdfi_read_string(ctx, s, indirect_num, indirect_gen);
1099
1.43M
            if (code < 0)
1100
0
                return code;
1101
1.43M
            return 1;
1102
0
            break;
1103
896k
        case '[':
1104
896k
            if (ctx->args.pdfdebug)
1105
0
                outprintf (ctx->memory, "[");
1106
896k
            if (ctx->object_nesting < MAX_NESTING_DEPTH) {
1107
877k
                ctx->object_nesting++;
1108
877k
                code = pdfi_mark_stack(ctx, PDF_ARRAY_MARK);
1109
877k
                if (code < 0)
1110
0
                    return code;
1111
877k
            } else
1112
18.0k
                if ((code = pdfi_set_error_stop(ctx, gs_note_error(gs_error_syntaxerror), NULL, E_PDF_NESTEDTOODEEP, "pdfi_read_token", NULL)) < 0)
1113
0
                    return code;
1114
896k
            return 1;
1115
0
            break;
1116
879k
        case ']':
1117
879k
            if (ctx->object_nesting > 0) {
1118
871k
                ctx->object_nesting--;
1119
871k
                code = pdfi_array_from_stack(ctx, indirect_num, indirect_gen);
1120
871k
                if (code < 0)
1121
14.5k
                    return code;
1122
871k
            } else {
1123
8.79k
                if ((code = pdfi_set_error_stop(ctx, gs_note_error(gs_error_unmatchedmark), NULL, E_PDF_UNMATCHEDMARK, "pdfi_read_token", NULL) < 0)) {
1124
0
                    return code;
1125
0
                }
1126
8.79k
                goto rescan;
1127
8.79k
            }
1128
856k
            break;
1129
856k
        case '{':
1130
11.7k
            if (ctx->args.pdfdebug)
1131
0
                outprintf (ctx->memory, "{");
1132
11.7k
            code = pdfi_mark_stack(ctx, PDF_PROC_MARK);
1133
11.7k
            if (code < 0)
1134
0
                return code;
1135
11.7k
            return 1;
1136
0
            break;
1137
11.5k
        case '}':
1138
11.5k
            pdfi_clear_to_mark(ctx);
1139
11.5k
            goto rescan;
1140
0
            break;
1141
110k
        case '%':
1142
110k
            pdfi_skip_comment(ctx, s);
1143
110k
            goto rescan;
1144
0
            break;
1145
8.78M
        default:
1146
8.78M
            if (isdelimiter(c)) {
1147
61.1k
                if ((code = pdfi_set_error_stop(ctx, gs_note_error(gs_error_syntaxerror), NULL, 0, "pdfi_read_token", NULL) < 0)) {
1148
0
                    return code;
1149
0
                }
1150
61.1k
                goto rescan;
1151
61.1k
            }
1152
8.71M
            pdfi_unread_byte(ctx, s, (byte)c);
1153
8.71M
            code = pdfi_read_keyword(ctx, s, indirect_num, indirect_gen);
1154
8.71M
            if (code < 0)
1155
4.54k
                return code;
1156
8.71M
            return 1;
1157
0
            break;
1158
39.1M
    }
1159
20.0M
    return 1;
1160
39.1M
}
1161
1162
/* In contrast to the 'read' functions, the 'make' functions create an object with a
1163
 * reference count of 1. This indicates that the caller holds the reference. Thus the
1164
 * caller need not increment the reference count to the object, but must decrement
1165
 * it (pdf_countdown) before exiting.
1166
 */
1167
int pdfi_name_alloc(pdf_context *ctx, byte *n, uint32_t size, pdf_obj **o)
1168
5.78M
{
1169
5.78M
    int code;
1170
5.78M
    *o = NULL;
1171
1172
5.78M
    code = pdfi_object_alloc(ctx, PDF_NAME, size, o);
1173
5.78M
    if (code < 0)
1174
0
        return code;
1175
1176
5.78M
    memcpy(((pdf_name *)*o)->data, n, size);
1177
1178
5.78M
    return 0;
1179
5.78M
}
1180
1181
static char op_table_3[5][3] = {
1182
    "BDC", "BMC", "EMC", "SCN", "scn"
1183
};
1184
1185
static char op_table_2[39][2] = {
1186
    "b*", "BI", "BT", "BX", "cm", "CS", "cs", "EI", "d0", "d1", "Do", "DP", "ET", "EX", "f*", "gs", "ID", "MP", "re", "RG",
1187
    "rg", "ri", "SC", "sc", "sh", "T*", "Tc", "Td", "TD", "Tf", "Tj", "TJ", "TL", "Tm", "Tr", "Ts", "Tw", "Tz", "W*",
1188
};
1189
1190
static char op_table_1[27][1] = {
1191
    "b", "B", "c", "d", "f", "F", "G", "g", "h", "i", "j", "J", "K", "k", "l", "m", "n", "q", "Q", "s", "S", "v", "w", "W",
1192
    "y", "'", "\""
1193
};
1194
1195
/* forward definition for the 'split_bogus_operator' function to use */
1196
static int pdfi_interpret_stream_operator(pdf_context *ctx, pdf_c_stream *source,
1197
                                          pdf_dict *stream_dict, pdf_dict *page_dict);
1198
1199
static int
1200
make_keyword_obj(pdf_context *ctx, const byte *data, int length, pdf_keyword **pkey)
1201
114k
{
1202
114k
    byte Buffer[256];
1203
114k
    pdf_key key;
1204
114k
    int code;
1205
1206
114k
    if (length > 255)
1207
0
        return_error(gs_error_rangecheck);
1208
1209
114k
    memcpy(Buffer, data, length);
1210
114k
    Buffer[length] = 0;
1211
114k
    key = lookup_keyword(Buffer);
1212
114k
    if (key != TOKEN_INVALID_KEY) {
1213
        /* The common case. We've found a real key, just cast the token to
1214
         * a pointer, and return that. */
1215
114k
        *pkey = (pdf_keyword *)PDF_TOKEN_AS_OBJ(key);
1216
114k
        return 1;
1217
114k
    }
1218
    /* We still haven't found a real keyword. Allocate a new object and
1219
     * return it. */
1220
0
    code = pdfi_object_alloc(ctx, PDF_KEYWORD, length, (pdf_obj **)pkey);
1221
0
    if (code < 0)
1222
0
        return code;
1223
0
    if (length)
1224
0
        memcpy((*pkey)->data, Buffer, length);
1225
0
    pdfi_countup(*pkey);
1226
1227
0
    return 1;
1228
0
}
1229
1230
static int search_table_3(pdf_context *ctx, unsigned char *str, pdf_keyword **key)
1231
135k
{
1232
135k
    int i;
1233
1234
811k
    for (i = 0; i < 5; i++) {
1235
676k
        if (memcmp(str, op_table_3[i], 3) == 0)
1236
349
            return make_keyword_obj(ctx, str, 3, key);
1237
676k
    }
1238
135k
    return 0;
1239
135k
}
1240
1241
static int search_table_2(pdf_context *ctx, unsigned char *str, pdf_keyword **key)
1242
192k
{
1243
192k
    int i;
1244
1245
7.43M
    for (i = 0; i < 39; i++) {
1246
7.25M
        if (memcmp(str, op_table_2[i], 2) == 0)
1247
12.4k
            return make_keyword_obj(ctx, str, 2, key);
1248
7.25M
    }
1249
180k
    return 0;
1250
192k
}
1251
1252
static int search_table_1(pdf_context *ctx, unsigned char *str, pdf_keyword **key)
1253
153k
{
1254
153k
    int i;
1255
1256
2.97M
    for (i = 0; i < 27; i++) {
1257
2.92M
        if (memcmp(str, op_table_1[i], 1) == 0)
1258
101k
            return make_keyword_obj(ctx, str, 1, key);
1259
2.92M
    }
1260
51.8k
    return 0;
1261
153k
}
1262
1263
static int split_bogus_operator(pdf_context *ctx, pdf_c_stream *source, pdf_dict *stream_dict, pdf_dict *page_dict)
1264
394k
{
1265
394k
    int code = 0;
1266
394k
    pdf_keyword *keyword = (pdf_keyword *)ctx->stack_top[-1], *key1 = NULL, *key2 = NULL;
1267
394k
    int length = keyword->length - 6;
1268
1269
394k
    if (length > 0) {
1270
        /* Longer than 2 3-character operators, we only allow for up to two
1271
         * operators. Check to see if it includes an endstream or endobj.
1272
         */
1273
186k
        if (memcmp(&keyword->data[length], "endobj", 6) == 0) {
1274
            /* Keyword is "<something>endobj". So make a keyword just from
1275
             * <something>, push that, execute it, then push endobj. */
1276
1
            code = make_keyword_obj(ctx, keyword->data, length, &key1);
1277
1
            if (code < 0)
1278
0
                goto error_exit;
1279
1
            pdfi_pop(ctx, 1);
1280
1
            pdfi_push(ctx, (pdf_obj *)key1);
1281
1
            pdfi_countdown(key1); /* Drop the reference returned by make_keyword_obj. */
1282
1
            code = pdfi_interpret_stream_operator(ctx, source, stream_dict, page_dict);
1283
1
            if (code < 0)
1284
0
                goto error_exit;
1285
1
            pdfi_push(ctx, PDF_TOKEN_AS_OBJ(TOKEN_ENDOBJ));
1286
1
            return 0;
1287
186k
        } else {
1288
186k
            length = keyword->length - 9;
1289
186k
            if (length > 0 && memcmp(&keyword->data[length], "endstream", 9) == 0) {
1290
                /* Keyword is "<something>endstream". So make a keyword just from
1291
                 * <something>, push that, execute it, then push endstream. */
1292
0
                code = make_keyword_obj(ctx, keyword->data, length, &key1);
1293
0
                if (code < 0)
1294
0
                    goto error_exit;
1295
0
                pdfi_pop(ctx, 1);
1296
0
                pdfi_push(ctx, (pdf_obj *)key1);
1297
0
                pdfi_countdown(key1); /* Drop the reference returned by make_keyword_obj. */
1298
0
                code = pdfi_interpret_stream_operator(ctx, source, stream_dict, page_dict);
1299
0
                if (code < 0)
1300
0
                    goto error_exit;
1301
0
                pdfi_push(ctx, PDF_TOKEN_AS_OBJ(TOKEN_ENDSTREAM));
1302
0
                return 0;
1303
186k
            } else {
1304
186k
                pdfi_clearstack(ctx);
1305
186k
                return 0;
1306
186k
            }
1307
186k
        }
1308
186k
    }
1309
1310
208k
    if (keyword->length > 3) {
1311
107k
        code = search_table_3(ctx, keyword->data, &key1);
1312
107k
        if (code < 0)
1313
0
            goto error_exit;
1314
1315
107k
        if (code > 0) {
1316
242
            switch (keyword->length - 3) {
1317
164
                case 1:
1318
164
                    code = search_table_1(ctx, &keyword->data[3], &key2);
1319
164
                    break;
1320
40
                case 2:
1321
40
                    code = search_table_2(ctx, &keyword->data[3], &key2);
1322
40
                    break;
1323
38
                case 3:
1324
38
                    code = search_table_3(ctx, &keyword->data[3], &key2);
1325
38
                    break;
1326
0
                default:
1327
0
                    goto error_exit;
1328
242
            }
1329
242
        }
1330
107k
        if (code < 0)
1331
0
            goto error_exit;
1332
107k
        if (code > 0)
1333
74
            goto match;
1334
107k
    }
1335
208k
    pdfi_countdown(key1);
1336
208k
    pdfi_countdown(key2);
1337
208k
    key1 = NULL;
1338
208k
    key2 = NULL;
1339
1340
208k
    if (keyword->length > 5 || keyword->length < 2)
1341
43.7k
        goto error_exit;
1342
1343
164k
    code = search_table_2(ctx, keyword->data, &key1);
1344
164k
    if (code < 0)
1345
0
        goto error_exit;
1346
1347
164k
    if (code > 0) {
1348
11.2k
        switch(keyword->length - 2) {
1349
4.61k
            case 1:
1350
4.61k
                code = search_table_1(ctx, &keyword->data[2], &key2);
1351
4.61k
                break;
1352
4.34k
            case 2:
1353
4.34k
                code = search_table_2(ctx, &keyword->data[2], &key2);
1354
4.34k
                break;
1355
2.24k
            case 3:
1356
2.24k
                code = search_table_3(ctx, &keyword->data[2], &key2);
1357
2.24k
                break;
1358
0
            default:
1359
0
                goto error_exit;
1360
11.2k
        }
1361
11.2k
        if (code < 0)
1362
0
            goto error_exit;
1363
11.2k
        if (code > 0)
1364
1.06k
            goto match;
1365
11.2k
    }
1366
163k
    pdfi_countdown(key1);
1367
163k
    pdfi_countdown(key2);
1368
163k
    key1 = NULL;
1369
163k
    key2 = NULL;
1370
1371
163k
    if (keyword->length > 4)
1372
50.4k
        goto error_exit;
1373
1374
112k
    code = search_table_1(ctx, keyword->data, &key1);
1375
112k
    if (code <= 0)
1376
26.9k
        goto error_exit;
1377
1378
85.9k
    switch(keyword->length - 1) {
1379
35.7k
        case 1:
1380
35.7k
            code = search_table_1(ctx, &keyword->data[1], &key2);
1381
35.7k
            break;
1382
24.2k
        case 2:
1383
24.2k
            code = search_table_2(ctx, &keyword->data[1], &key2);
1384
24.2k
            break;
1385
25.9k
        case 3:
1386
25.9k
            code = search_table_3(ctx, &keyword->data[1], &key2);
1387
25.9k
            break;
1388
0
        default:
1389
0
            goto error_exit;
1390
85.9k
    }
1391
85.9k
    if (code <= 0)
1392
70.1k
        goto error_exit;
1393
1394
16.9k
match:
1395
16.9k
    pdfi_set_warning(ctx, 0, NULL, W_PDF_MISSING_WHITE_OPS, "split_bogus_operator", NULL);
1396
    /* If we get here, we have two PDF_KEYWORD objects. We push them on the stack
1397
     * one at a time, and execute them.
1398
     */
1399
16.9k
    pdfi_push(ctx, (pdf_obj *)key1);
1400
16.9k
    code = pdfi_interpret_stream_operator(ctx, source, stream_dict, page_dict);
1401
16.9k
    if (code < 0)
1402
10.4k
        goto error_exit;
1403
1404
6.47k
    pdfi_push(ctx, (pdf_obj *)key2);
1405
6.47k
    code = pdfi_interpret_stream_operator(ctx, source, stream_dict, page_dict);
1406
1407
6.47k
    pdfi_countdown(key1);
1408
6.47k
    pdfi_countdown(key2);
1409
6.47k
    pdfi_clearstack(ctx);
1410
6.47k
    return code;
1411
1412
201k
error_exit:
1413
201k
    pdfi_set_error(ctx, code, NULL, E_PDF_TOKENERROR, "split_bogus_operator", NULL);
1414
201k
    pdfi_countdown(key1);
1415
201k
    pdfi_countdown(key2);
1416
201k
    pdfi_clearstack(ctx);
1417
201k
    return code;
1418
16.9k
}
1419
1420
static int pdfi_interpret_stream_operator(pdf_context *ctx, pdf_c_stream *source,
1421
                                          pdf_dict *stream_dict, pdf_dict *page_dict)
1422
5.43M
{
1423
5.43M
    pdf_obj *keyword = ctx->stack_top[-1];
1424
5.43M
    int code = 0;
1425
1426
5.43M
    if (keyword < PDF_TOKEN_AS_OBJ(TOKEN__LAST_KEY))
1427
5.04M
    {
1428
5.04M
        switch((uintptr_t)keyword) {
1429
1.15k
            case TOKEN_b:           /* closepath, fill, stroke */
1430
1.15k
                pdfi_pop(ctx, 1);
1431
1.15k
                code = pdfi_b(ctx);
1432
1.15k
                break;
1433
1.71k
            case TOKEN_B:           /* fill, stroke */
1434
1.71k
                pdfi_pop(ctx, 1);
1435
1.71k
                code = pdfi_B(ctx);
1436
1.71k
                break;
1437
23
            case TOKEN_bstar:       /* closepath, eofill, stroke */
1438
23
                pdfi_pop(ctx, 1);
1439
23
                code = pdfi_b_star(ctx);
1440
23
                break;
1441
187
            case TOKEN_Bstar:       /* eofill, stroke */
1442
187
                pdfi_pop(ctx, 1);
1443
187
                code = pdfi_B_star(ctx);
1444
187
                break;
1445
13.7k
            case TOKEN_BI:       /* begin inline image */
1446
13.7k
                pdfi_pop(ctx, 1);
1447
13.7k
                code = pdfi_BI(ctx);
1448
13.7k
                break;
1449
35.4k
            case TOKEN_BDC:   /* begin marked content sequence with property list */
1450
35.4k
                pdfi_pop(ctx, 1);
1451
35.4k
                code = pdfi_op_BDC(ctx, stream_dict, page_dict);
1452
35.4k
                break;
1453
1.73k
            case TOKEN_BMC:   /* begin marked content sequence */
1454
1.73k
                pdfi_pop(ctx, 1);
1455
1.73k
                code = pdfi_op_BMC(ctx);
1456
1.73k
                break;
1457
198k
            case TOKEN_BT:       /* begin text */
1458
198k
                pdfi_pop(ctx, 1);
1459
198k
                code = pdfi_BT(ctx);
1460
198k
                break;
1461
7.03k
            case TOKEN_BX:       /* begin compatibility section */
1462
7.03k
                pdfi_pop(ctx, 1);
1463
7.03k
                break;
1464
187k
            case TOKEN_c:           /* curveto */
1465
187k
                pdfi_pop(ctx, 1);
1466
187k
                code = pdfi_curveto(ctx);
1467
187k
                break;
1468
231k
            case TOKEN_cm:       /* concat */
1469
231k
                pdfi_pop(ctx, 1);
1470
231k
                code = pdfi_concat(ctx);
1471
231k
                break;
1472
2.52k
            case TOKEN_CS:       /* set stroke colour space */
1473
2.52k
                pdfi_pop(ctx, 1);
1474
2.52k
                code = pdfi_setstrokecolor_space(ctx, stream_dict, page_dict);
1475
2.52k
                break;
1476
18.2k
            case TOKEN_cs:       /* set non-stroke colour space */
1477
18.2k
                pdfi_pop(ctx, 1);
1478
18.2k
                code = pdfi_setfillcolor_space(ctx, stream_dict, page_dict);
1479
18.2k
                break;
1480
67.2k
            case TOKEN_d:           /* set dash params */
1481
67.2k
                pdfi_pop(ctx, 1);
1482
67.2k
                code = pdfi_setdash(ctx);
1483
67.2k
                break;
1484
116
            case TOKEN_d0:       /* set type 3 font glyph width */
1485
116
                pdfi_pop(ctx, 1);
1486
116
                code = pdfi_d0(ctx);
1487
116
                break;
1488
1.61k
            case TOKEN_d1:       /* set type 3 font glyph width and bounding box */
1489
1.61k
                pdfi_pop(ctx, 1);
1490
1.61k
                code = pdfi_d1(ctx);
1491
1.61k
                break;
1492
18.5k
            case TOKEN_Do:       /* invoke named XObject */
1493
18.5k
                pdfi_pop(ctx, 1);
1494
18.5k
                code = pdfi_Do(ctx, stream_dict, page_dict);
1495
18.5k
                break;
1496
6
            case TOKEN_DP:       /* define marked content point with property list */
1497
6
                pdfi_pop(ctx, 1);
1498
6
                code = pdfi_op_DP(ctx, stream_dict, page_dict);
1499
6
                break;
1500
13.3k
            case TOKEN_EI:       /* end inline image */
1501
13.3k
                pdfi_pop(ctx, 1);
1502
13.3k
                code = pdfi_EI(ctx);
1503
13.3k
                break;
1504
198k
            case TOKEN_ET:       /* end text */
1505
198k
                pdfi_pop(ctx, 1);
1506
198k
                code = pdfi_ET(ctx);
1507
198k
                break;
1508
36.5k
            case TOKEN_EMC:   /* end marked content sequence */
1509
36.5k
                pdfi_pop(ctx, 1);
1510
36.5k
                code = pdfi_op_EMC(ctx);
1511
36.5k
                break;
1512
6.99k
            case TOKEN_EX:       /* end compatibility section */
1513
6.99k
                pdfi_pop(ctx, 1);
1514
6.99k
                break;
1515
64.2k
            case TOKEN_f:           /* fill */
1516
64.2k
                pdfi_pop(ctx, 1);
1517
64.2k
                code = pdfi_fill(ctx);
1518
64.2k
                break;
1519
276
            case TOKEN_F:           /* fill (obselete operator) */
1520
276
                pdfi_pop(ctx, 1);
1521
276
                code = pdfi_fill(ctx);
1522
276
                break;
1523
4.46k
            case TOKEN_fstar:       /* eofill */
1524
4.46k
                pdfi_pop(ctx, 1);
1525
4.46k
                code = pdfi_eofill(ctx);
1526
4.46k
                break;
1527
44.7k
            case TOKEN_G:           /* setgray for stroke */
1528
44.7k
                pdfi_pop(ctx, 1);
1529
44.7k
                code = pdfi_setgraystroke(ctx);
1530
44.7k
                break;
1531
62.0k
            case TOKEN_g:           /* setgray for non-stroke */
1532
62.0k
                pdfi_pop(ctx, 1);
1533
62.0k
                code = pdfi_setgrayfill(ctx);
1534
62.0k
                break;
1535
29.4k
            case TOKEN_gs:       /* set graphics state from dictionary */
1536
29.4k
                pdfi_pop(ctx, 1);
1537
29.4k
                code = pdfi_setgstate(ctx, stream_dict, page_dict);
1538
29.4k
                break;
1539
37.8k
            case TOKEN_h:           /* closepath */
1540
37.8k
                pdfi_pop(ctx, 1);
1541
37.8k
                code = pdfi_closepath(ctx);
1542
37.8k
                break;
1543
14.6k
            case TOKEN_i:           /* setflat */
1544
14.6k
                pdfi_pop(ctx, 1);
1545
14.6k
                code = pdfi_setflat(ctx);
1546
14.6k
                break;
1547
13.5k
            case TOKEN_ID:       /* begin inline image data */
1548
13.5k
                pdfi_pop(ctx, 1);
1549
13.5k
                code = pdfi_ID(ctx, stream_dict, page_dict, source);
1550
13.5k
                break;
1551
73.5k
            case TOKEN_j:           /* setlinejoin */
1552
73.5k
                pdfi_pop(ctx, 1);
1553
73.5k
                code = pdfi_setlinejoin(ctx);
1554
73.5k
                break;
1555
77.2k
            case TOKEN_J:           /* setlinecap */
1556
77.2k
                pdfi_pop(ctx, 1);
1557
77.2k
                code = pdfi_setlinecap(ctx);
1558
77.2k
                break;
1559
1.33k
            case TOKEN_K:           /* setcmyk for non-stroke */
1560
1.33k
                pdfi_pop(ctx, 1);
1561
1.33k
                code = pdfi_setcmykstroke(ctx);
1562
1.33k
                break;
1563
4.57k
            case TOKEN_k:           /* setcmyk for non-stroke */
1564
4.57k
                pdfi_pop(ctx, 1);
1565
4.57k
                code = pdfi_setcmykfill(ctx);
1566
4.57k
                break;
1567
641k
            case TOKEN_l:           /* lineto */
1568
641k
                pdfi_pop(ctx, 1);
1569
641k
                code = pdfi_lineto(ctx);
1570
641k
                break;
1571
490k
            case TOKEN_m:           /* moveto */
1572
490k
                pdfi_pop(ctx, 1);
1573
490k
                code = pdfi_moveto(ctx);
1574
490k
                break;
1575
1.18k
            case TOKEN_M:           /* setmiterlimit */
1576
1.18k
                pdfi_pop(ctx, 1);
1577
1.18k
                code = pdfi_setmiterlimit(ctx);
1578
1.18k
                break;
1579
216
            case TOKEN_MP:       /* define marked content point */
1580
216
                pdfi_pop(ctx, 1);
1581
216
                code = pdfi_op_MP(ctx);
1582
216
                break;
1583
91.9k
            case TOKEN_n:           /* newpath */
1584
91.9k
                pdfi_pop(ctx, 1);
1585
91.9k
                code = pdfi_newpath(ctx);
1586
91.9k
                break;
1587
278k
            case TOKEN_q:           /* gsave */
1588
278k
                pdfi_pop(ctx, 1);
1589
278k
                code = pdfi_op_q(ctx);
1590
278k
                break;
1591
275k
            case TOKEN_Q:           /* grestore */
1592
275k
                pdfi_pop(ctx, 1);
1593
275k
                code = pdfi_op_Q(ctx);
1594
275k
                break;
1595
1.46k
            case TOKEN_r:       /* non-standard set rgb colour for non-stroke */
1596
1.46k
                pdfi_pop(ctx, 1);
1597
1.46k
                code = pdfi_setrgbfill_array(ctx);
1598
1.46k
                break;
1599
165k
            case TOKEN_re:       /* append rectangle */
1600
165k
                pdfi_pop(ctx, 1);
1601
165k
                code = pdfi_rectpath(ctx);
1602
165k
                break;
1603
66.0k
            case TOKEN_RG:       /* set rgb colour for stroke */
1604
66.0k
                pdfi_pop(ctx, 1);
1605
66.0k
                code = pdfi_setrgbstroke(ctx);
1606
66.0k
                break;
1607
102k
            case TOKEN_rg:       /* set rgb colour for non-stroke */
1608
102k
                pdfi_pop(ctx, 1);
1609
102k
                code = pdfi_setrgbfill(ctx);
1610
102k
                break;
1611
6.26k
            case TOKEN_ri:       /* set rendering intent */
1612
6.26k
                pdfi_pop(ctx, 1);
1613
6.26k
                code = pdfi_ri(ctx);
1614
6.26k
                break;
1615
1.97k
            case TOKEN_s:           /* closepath, stroke */
1616
1.97k
                pdfi_pop(ctx, 1);
1617
1.97k
                code = pdfi_closepath_stroke(ctx);
1618
1.97k
                break;
1619
267k
            case TOKEN_S:           /* stroke */
1620
267k
                pdfi_pop(ctx, 1);
1621
267k
                code = pdfi_stroke(ctx);
1622
267k
                break;
1623
3.42k
            case TOKEN_SC:       /* set colour for stroke */
1624
3.42k
                pdfi_pop(ctx, 1);
1625
3.42k
                code = pdfi_setstrokecolor(ctx);
1626
3.42k
                break;
1627
12.0k
            case TOKEN_sc:       /* set colour for non-stroke */
1628
12.0k
                pdfi_pop(ctx, 1);
1629
12.0k
                code = pdfi_setfillcolor(ctx);
1630
12.0k
                break;
1631
707
            case TOKEN_SCN:   /* set special colour for stroke */
1632
707
                pdfi_pop(ctx, 1);
1633
707
                code = pdfi_setcolorN(ctx, stream_dict, page_dict, false);
1634
707
                break;
1635
8.53k
            case TOKEN_scn:   /* set special colour for non-stroke */
1636
8.53k
                pdfi_pop(ctx, 1);
1637
8.53k
                code = pdfi_setcolorN(ctx, stream_dict, page_dict, true);
1638
8.53k
                break;
1639
12.1k
            case TOKEN_sh:       /* fill with sahding pattern */
1640
12.1k
                pdfi_pop(ctx, 1);
1641
12.1k
                code = pdfi_shading(ctx, stream_dict, page_dict);
1642
12.1k
                break;
1643
6.54k
            case TOKEN_Tstar:       /* Move to start of next text line */
1644
6.54k
                pdfi_pop(ctx, 1);
1645
6.54k
                code = pdfi_T_star(ctx);
1646
6.54k
                break;
1647
44.5k
            case TOKEN_Tc:       /* set character spacing */
1648
44.5k
                pdfi_pop(ctx, 1);
1649
44.5k
                code = pdfi_Tc(ctx);
1650
44.5k
                break;
1651
155k
            case TOKEN_Td:       /* move text position */
1652
155k
                pdfi_pop(ctx, 1);
1653
155k
                code = pdfi_Td(ctx);
1654
155k
                break;
1655
22.7k
            case TOKEN_TD:       /* Move text position, set leading */
1656
22.7k
                pdfi_pop(ctx, 1);
1657
22.7k
                code = pdfi_TD(ctx);
1658
22.7k
                break;
1659
121k
            case TOKEN_Tf:       /* set font and size */
1660
121k
                pdfi_pop(ctx, 1);
1661
121k
                code = pdfi_Tf(ctx, stream_dict, page_dict);
1662
121k
                break;
1663
164k
            case TOKEN_Tj:       /* show text */
1664
164k
                pdfi_pop(ctx, 1);
1665
164k
                code = pdfi_Tj(ctx);
1666
164k
                break;
1667
160k
            case TOKEN_TJ:       /* show text with individual glyph positioning */
1668
160k
                pdfi_pop(ctx, 1);
1669
160k
                code = pdfi_TJ(ctx);
1670
160k
                break;
1671
1.88k
            case TOKEN_TL:       /* set text leading */
1672
1.88k
                pdfi_pop(ctx, 1);
1673
1.88k
                code = pdfi_TL(ctx);
1674
1.88k
                break;
1675
143k
            case TOKEN_Tm:       /* set text matrix */
1676
143k
                pdfi_pop(ctx, 1);
1677
143k
                code = pdfi_Tm(ctx);
1678
143k
                break;
1679
53.4k
            case TOKEN_Tr:       /* set text rendering mode */
1680
53.4k
                pdfi_pop(ctx, 1);
1681
53.4k
                code = pdfi_Tr(ctx);
1682
53.4k
                break;
1683
299
            case TOKEN_Ts:       /* set text rise */
1684
299
                pdfi_pop(ctx, 1);
1685
299
                code = pdfi_Ts(ctx);
1686
299
                break;
1687
4.84k
            case TOKEN_Tw:       /* set word spacing */
1688
4.84k
                pdfi_pop(ctx, 1);
1689
4.84k
                code = pdfi_Tw(ctx);
1690
4.84k
                break;
1691
21.9k
            case TOKEN_Tz:       /* set text matrix */
1692
21.9k
                pdfi_pop(ctx, 1);
1693
21.9k
                code = pdfi_Tz(ctx);
1694
21.9k
                break;
1695
1.52k
            case TOKEN_v:           /* append curve (initial point replicated) */
1696
1.52k
                pdfi_pop(ctx, 1);
1697
1.52k
                code = pdfi_v_curveto(ctx);
1698
1.52k
                break;
1699
194k
            case TOKEN_w:           /* setlinewidth */
1700
194k
                pdfi_pop(ctx, 1);
1701
194k
                code = pdfi_setlinewidth(ctx);
1702
194k
                break;
1703
42.8k
            case TOKEN_W:           /* clip */
1704
42.8k
                pdfi_pop(ctx, 1);
1705
42.8k
                ctx->clip_active = true;
1706
42.8k
                ctx->do_eoclip = false;
1707
42.8k
                break;
1708
3.76k
            case TOKEN_Wstar:       /* eoclip */
1709
3.76k
                pdfi_pop(ctx, 1);
1710
3.76k
                ctx->clip_active = true;
1711
3.76k
                ctx->do_eoclip = true;
1712
3.76k
                break;
1713
2.83k
            case TOKEN_y:           /* append curve (final point replicated) */
1714
2.83k
                pdfi_pop(ctx, 1);
1715
2.83k
                code = pdfi_y_curveto(ctx);
1716
2.83k
                break;
1717
542
            case TOKEN_APOSTROPHE:          /* move to next line and show text */
1718
542
                pdfi_pop(ctx, 1);
1719
542
                code = pdfi_singlequote(ctx);
1720
542
                break;
1721
50
            case TOKEN_QUOTE:           /* set word and character spacing, move to next line, show text */
1722
50
                pdfi_pop(ctx, 1);
1723
50
                code = pdfi_doublequote(ctx);
1724
50
                break;
1725
141
            default:
1726
                /* Shouldn't we return an error here? Original code didn't seem to. */
1727
141
                break;
1728
5.04M
        }
1729
        /* We use a return value of 1 to indicate a repaired keyword (a pair of operators
1730
         * was concatenated, and we split them up). We must not return a value > 0 from here
1731
         * to avoid tripping that test.
1732
         */
1733
5.04M
        if (code > 0)
1734
0
            code = 0;
1735
5.04M
        return code;
1736
5.04M
    } else {
1737
        /* This means we either have a corrupted or illegal operator. The most
1738
         * usual corruption is two concatented operators (eg QBT instead of Q BT)
1739
         * I plan to tackle this by trying to see if I can make two or more operators
1740
         * out of the mangled one.
1741
         */
1742
394k
        code = split_bogus_operator(ctx, source, stream_dict, page_dict);
1743
394k
        if (code < 0)
1744
16.5k
            return code;
1745
378k
        if (pdfi_count_stack(ctx) > 0) {
1746
1
            keyword = ctx->stack_top[-1];
1747
1
            if (keyword != PDF_TOKEN_AS_OBJ(TOKEN_NOT_A_KEYWORD))
1748
1
                return REPAIRED_KEYWORD;
1749
1
        }
1750
378k
    }
1751
378k
    return 0;
1752
5.43M
}
1753
1754
void local_save_stream_state(pdf_context *ctx, stream_save *local_save)
1755
34.1k
{
1756
    /* copy the 'save_stream' data from the context to a local structure */
1757
34.1k
    local_save->stream_offset = ctx->current_stream_save.stream_offset;
1758
34.1k
    local_save->gsave_level = ctx->current_stream_save.gsave_level;
1759
34.1k
    local_save->stack_count = ctx->current_stream_save.stack_count;
1760
34.1k
    local_save->group_depth = ctx->current_stream_save.group_depth;
1761
34.1k
}
1762
1763
void cleanup_context_interpretation(pdf_context *ctx, stream_save *local_save)
1764
34.1k
{
1765
34.1k
    pdfi_seek(ctx, ctx->main_stream, ctx->current_stream_save.stream_offset, SEEK_SET);
1766
    /* The transparency group implenetation does a gsave, so the end group does a
1767
     * grestore. Therefore we need to do this before we check the saved gstate depth
1768
     */
1769
34.1k
    if (ctx->current_stream_save.group_depth != local_save->group_depth) {
1770
0
        pdfi_set_warning(ctx, 0, NULL, W_PDF_GROUPERROR, "pdfi_cleanup_context_interpretation", NULL);
1771
0
        while (ctx->current_stream_save.group_depth > local_save->group_depth)
1772
0
            pdfi_trans_end_group(ctx);
1773
0
    }
1774
34.1k
    if (ctx->pgs->level > ctx->current_stream_save.gsave_level)
1775
981
        pdfi_set_warning(ctx, 0, NULL, W_PDF_TOOMANYq, "pdfi_cleanup_context_interpretation", NULL);
1776
34.1k
    if (pdfi_count_stack(ctx) > ctx->current_stream_save.stack_count)
1777
230
        pdfi_set_warning(ctx, 0, NULL, W_PDF_STACKGARBAGE, "pdfi_cleanup_context_interpretation", NULL);
1778
45.2k
    while (ctx->pgs->level > ctx->current_stream_save.gsave_level)
1779
11.1k
        pdfi_grestore(ctx);
1780
34.1k
    pdfi_clearstack(ctx);
1781
34.1k
}
1782
1783
void local_restore_stream_state(pdf_context *ctx, stream_save *local_save)
1784
34.1k
{
1785
    /* Put the entries stored in the context back to what they were on entry
1786
     * We shouldn't really need to do this, the cleanup above should mean all the
1787
     * entries are properly reset.
1788
     */
1789
34.1k
    ctx->current_stream_save.stream_offset = local_save->stream_offset;
1790
34.1k
    ctx->current_stream_save.gsave_level = local_save->gsave_level;
1791
34.1k
    ctx->current_stream_save.stack_count = local_save->stack_count;
1792
34.1k
    ctx->current_stream_save.group_depth = local_save->group_depth;
1793
34.1k
}
1794
1795
void initialise_stream_save(pdf_context *ctx)
1796
34.1k
{
1797
    /* Set up the values in the context to the current values */
1798
34.1k
    ctx->current_stream_save.stream_offset = pdfi_tell(ctx->main_stream);
1799
34.1k
    ctx->current_stream_save.gsave_level = ctx->pgs->level;
1800
34.1k
    ctx->current_stream_save.stack_count = pdfi_count_total_stack(ctx);
1801
34.1k
}
1802
1803
/* Run a stream in a sub-context (saves/restores DefaultQState) */
1804
int pdfi_run_context(pdf_context *ctx, pdf_stream *stream_obj,
1805
                     pdf_dict *page_dict, bool stoponerror, const char *desc)
1806
12.2k
{
1807
12.2k
    int code = 0, code1 = 0;
1808
12.2k
    gs_gstate *DefaultQState = NULL;
1809
    /* Save any existing Default* colour spaces */
1810
12.2k
    gs_color_space *PageDefaultGray = ctx->page.DefaultGray_cs;
1811
12.2k
    gs_color_space *PageDefaultRGB = ctx->page.DefaultRGB_cs;
1812
12.2k
    gs_color_space *PageDefaultCMYK = ctx->page.DefaultCMYK_cs;
1813
1814
12.2k
    ctx->page.DefaultGray_cs = NULL;
1815
12.2k
    ctx->page.DefaultRGB_cs = NULL;
1816
12.2k
    ctx->page.DefaultCMYK_cs = NULL;
1817
1818
#if DEBUG_CONTEXT
1819
    dbgmprintf(ctx->memory, "pdfi_run_context BEGIN\n");
1820
#endif
1821
    /* If the stream has any Default* colour spaces, replace the page level ones.
1822
     * This will derement the reference counts to the current spaces if they are replaced.
1823
     */
1824
12.2k
    code = pdfi_setup_DefaultSpaces(ctx, stream_obj->stream_dict);
1825
12.2k
    if (code < 0)
1826
0
        goto exit;
1827
1828
    /* If no Default* space found, try using the Page level ones (if any) */
1829
12.2k
    if (ctx->page.DefaultGray_cs == NULL) {
1830
12.2k
        ctx->page.DefaultGray_cs = PageDefaultGray;
1831
12.2k
        rc_increment(PageDefaultGray);
1832
12.2k
    }
1833
12.2k
    if (ctx->page.DefaultRGB_cs == NULL) {
1834
12.2k
        ctx->page.DefaultRGB_cs = PageDefaultRGB;
1835
12.2k
        rc_increment(PageDefaultRGB);
1836
12.2k
    }
1837
12.2k
    if (ctx->page.DefaultCMYK_cs == NULL) {
1838
12.2k
        ctx->page.DefaultCMYK_cs = PageDefaultCMYK;
1839
12.2k
        rc_increment(PageDefaultCMYK);
1840
12.2k
    }
1841
1842
12.2k
    code = pdfi_copy_DefaultQState(ctx, &DefaultQState);
1843
12.2k
    if (code < 0)
1844
0
        goto exit;
1845
1846
12.2k
    code = pdfi_set_DefaultQState(ctx, ctx->pgs);
1847
12.2k
    if (code < 0)
1848
0
        goto exit;
1849
1850
12.2k
    code = pdfi_interpret_inner_content_stream(ctx, stream_obj, page_dict, stoponerror, desc);
1851
1852
12.2k
    code1 = pdfi_restore_DefaultQState(ctx, &DefaultQState);
1853
12.2k
    if (code >= 0)
1854
12.2k
        code = code1;
1855
1856
12.2k
exit:
1857
12.2k
    if (DefaultQState != NULL) {
1858
0
        gs_gstate_free(DefaultQState);
1859
0
        DefaultQState = NULL;
1860
0
    }
1861
1862
    /* Count down any Default* colour spaces */
1863
12.2k
    rc_decrement(ctx->page.DefaultGray_cs, "pdfi_run_context");
1864
12.2k
    rc_decrement(ctx->page.DefaultRGB_cs, "pdfi_run_context");
1865
12.2k
    rc_decrement(ctx->page.DefaultCMYK_cs, "pdfi_run_context");
1866
1867
    /* And restore the page level ones (if any) */
1868
12.2k
    ctx->page.DefaultGray_cs = PageDefaultGray;
1869
12.2k
    ctx->page.DefaultRGB_cs = PageDefaultRGB;
1870
12.2k
    ctx->page.DefaultCMYK_cs = PageDefaultCMYK;
1871
1872
#if DEBUG_CONTEXT
1873
    dbgmprintf(ctx->memory, "pdfi_run_context END\n");
1874
#endif
1875
12.2k
    return code;
1876
12.2k
}
1877
1878
1879
/* Interpret a sub-content stream, with some handling of error recovery, clearing stack, etc.
1880
 * This temporarily turns on pdfstoponerror if requested.
1881
 * It will make sure the stack is cleared and the gstate is matched.
1882
 */
1883
static int
1884
pdfi_interpret_inner_content(pdf_context *ctx, pdf_c_stream *content_stream, pdf_stream *stream_obj,
1885
                             pdf_dict *page_dict, bool stoponerror, const char *desc)
1886
15.8k
{
1887
15.8k
    int code = 0;
1888
15.8k
    bool saved_stoponerror = ctx->args.pdfstoponerror;
1889
15.8k
    stream_save local_entry_save;
1890
1891
15.8k
    local_save_stream_state(ctx, &local_entry_save);
1892
15.8k
    initialise_stream_save(ctx);
1893
1894
    /* This causes several files to render 'incorrectly', even though they are in some sense
1895
     * invalid. It doesn't seem to provide any benefits so I have, for now, removed it. If
1896
     * there is a good reason for it we can put it back again.
1897
     * FIXME - either restore or remove these lines
1898
     * /tests_private/pdf/PDF_2.0_FTS/fts_23_2310.pdf
1899
     * /tests_private/pdf/PDF_2.0_FTS/fts_23_2311.pdf
1900
     * /tests_private/pdf/PDF_2.0_FTS/fts_23_2312.pdf
1901
     * /tests_private/pdf/sumatra/recursive_colorspace.pdf
1902
     * /tests_private/pdf/uploads/Bug696410.pdf
1903
     * /tests_private/pdf/sumatra/1900_-_cairo_transparency_inefficiency.pdf (with pdfwrite)
1904
     */
1905
#if 0
1906
    /* Stop on error in substream, and also be prepared to clean up the stack */
1907
    if (stoponerror)
1908
        ctx->args.pdfstoponerror = true;
1909
#endif
1910
1911
#if DEBUG_CONTEXT
1912
    dbgmprintf1(ctx->memory, "BEGIN %s stream\n", desc);
1913
#endif
1914
15.8k
    code = pdfi_interpret_content_stream(ctx, content_stream, stream_obj, page_dict);
1915
#if DEBUG_CONTEXT
1916
    dbgmprintf1(ctx->memory, "END %s stream\n", desc);
1917
#endif
1918
1919
15.8k
    if (code < 0)
1920
15.8k
        dbgmprintf1(ctx->memory, "ERROR: inner_stream: code %d when rendering stream\n", code);
1921
1922
15.8k
    ctx->args.pdfstoponerror = saved_stoponerror;
1923
1924
    /* Put our state back the way it was on entry */
1925
#if PROBE_STREAMS
1926
    if (ctx->pgs->level > ctx->current_stream_save.gsave_level ||
1927
        pdfi_count_stack(ctx) > ctx->current_stream_save.stack_count)
1928
        code = ((pdf_context *)0)->first_page;
1929
#endif
1930
1931
15.8k
    cleanup_context_interpretation(ctx, &local_entry_save);
1932
15.8k
    local_restore_stream_state(ctx, &local_entry_save);
1933
15.8k
    if (code < 0)
1934
437
        code = pdfi_set_error_stop(ctx, code, NULL, 0, "pdfi_interpret_inner_content", NULL);
1935
15.8k
    return code;
1936
15.8k
}
1937
1938
/* Interpret inner content from a buffer
1939
 */
1940
int
1941
pdfi_interpret_inner_content_buffer(pdf_context *ctx, byte *content_data,
1942
                                      uint32_t content_length,
1943
                                      pdf_dict *stream_dict, pdf_dict *page_dict,
1944
                                      bool stoponerror, const char *desc)
1945
3.59k
{
1946
3.59k
    int code = 0;
1947
3.59k
    pdf_c_stream *stream = NULL;
1948
3.59k
    pdf_stream *stream_obj = NULL;
1949
1950
3.59k
    if (content_length == 0)
1951
0
        return 0;
1952
1953
3.59k
    code = pdfi_open_memory_stream_from_memory(ctx, content_length,
1954
3.59k
                                               content_data, &stream, true);
1955
3.59k
    if (code < 0)
1956
0
        goto exit;
1957
1958
3.59k
    code = pdfi_obj_dict_to_stream(ctx, stream_dict, &stream_obj, false);
1959
3.59k
    if (code < 0)
1960
0
        return code;
1961
1962
    /* NOTE: stream gets closed in here */
1963
3.59k
    code = pdfi_interpret_inner_content(ctx, stream, stream_obj, page_dict, stoponerror, desc);
1964
3.59k
    pdfi_countdown(stream_obj);
1965
3.59k
 exit:
1966
3.59k
    return code;
1967
3.59k
}
1968
1969
/* Interpret inner content from a C string
1970
 */
1971
int
1972
pdfi_interpret_inner_content_c_string(pdf_context *ctx, char *content_string,
1973
                                      pdf_dict *stream_dict, pdf_dict *page_dict,
1974
                                      bool stoponerror, const char *desc)
1975
1.35k
{
1976
1.35k
    uint32_t length = (uint32_t)strlen(content_string);
1977
1.35k
    bool decrypt_strings;
1978
1.35k
    int code;
1979
1980
1.35k
    if (length == 0)
1981
0
        return 0;
1982
1983
    /* Underlying buffer limit is uint32, so handle the extremely unlikely case that
1984
     * our string is too big.
1985
     */
1986
1.35k
    if (length != strlen(content_string))
1987
0
        return_error(gs_error_limitcheck);
1988
1989
    /* Since this is a constructed string content, not part of the file, it can never
1990
     * be encrypted. So disable decryption during this call.
1991
     */
1992
1.35k
    decrypt_strings = ctx->encryption.decrypt_strings;
1993
1.35k
    ctx->encryption.decrypt_strings = false;
1994
1.35k
    code = pdfi_interpret_inner_content_buffer(ctx, (byte *)content_string, length,
1995
1.35k
                                               stream_dict, page_dict, stoponerror, desc);
1996
1.35k
    ctx->encryption.decrypt_strings = decrypt_strings;
1997
1998
1.35k
    return code;
1999
1.35k
}
2000
2001
/* Interpret inner content from a string
2002
 */
2003
int
2004
pdfi_interpret_inner_content_string(pdf_context *ctx, pdf_string *content_string,
2005
                                    pdf_dict *stream_dict, pdf_dict *page_dict,
2006
                                    bool stoponerror, const char *desc)
2007
2.23k
{
2008
2.23k
    return pdfi_interpret_inner_content_buffer(ctx, content_string->data, content_string->length,
2009
2.23k
                                               stream_dict, page_dict, stoponerror, desc);
2010
2.23k
}
2011
2012
/* Interpret inner content from a stream_dict
2013
 */
2014
int
2015
pdfi_interpret_inner_content_stream(pdf_context *ctx, pdf_stream *stream_obj,
2016
                                    pdf_dict *page_dict, bool stoponerror, const char *desc)
2017
12.2k
{
2018
12.2k
    return pdfi_interpret_inner_content(ctx, NULL, stream_obj, page_dict, stoponerror, desc);
2019
12.2k
}
2020
2021
/*
2022
 * Interpret a content stream.
2023
 * content_stream -- content to parse.  If NULL, get it from the stream_dict
2024
 * stream_dict -- dict containing the stream
2025
 */
2026
int
2027
pdfi_interpret_content_stream(pdf_context *ctx, pdf_c_stream *content_stream,
2028
                              pdf_stream *stream_obj, pdf_dict *page_dict)
2029
25.6k
{
2030
25.6k
    int code;
2031
25.6k
    pdf_c_stream *stream = NULL, *SubFile_stream = NULL;
2032
25.6k
    pdf_keyword *keyword;
2033
25.6k
    pdf_stream *s = ctx->current_stream;
2034
25.6k
    pdf_obj_type type;
2035
25.6k
    char EODString[] = "endstream";
2036
2037
    /* Check this stream, and all the streams currently being executed, to see
2038
     * if the stream we've been given is already in train. If it is, then we
2039
     * have encountered recursion. This can happen if a non-page stream such
2040
     * as a Form or Pattern uses a Resource, but does not declare it in it's
2041
     * Resources, and instead inherits it from the parent. We cannot detect that
2042
     * before the Resource is used, so all we can do is check here.
2043
     */
2044
36.2k
    while (s != NULL && pdfi_type_of(s) == PDF_STREAM) {
2045
10.6k
        if (s->object_num > 0) {
2046
10.6k
            if (s->object_num == stream_obj->object_num) {
2047
32
                pdf_dict *d = NULL;
2048
32
                bool known = false;
2049
2050
32
                code = pdfi_dict_from_obj(ctx, (pdf_obj *)stream_obj, &d);
2051
32
                if (code >= 0) {
2052
32
                    code = pdfi_dict_known(ctx, d, "Parent", &known);
2053
32
                    if (code >= 0 && known)
2054
5
                        (void)pdfi_dict_delete(ctx, d, "Parent");
2055
32
                }
2056
32
                pdfi_set_error(ctx, 0, NULL, E_PDF_CIRCULARREF, "pdfi_interpret_content_stream", "Aborting stream");
2057
32
                return_error(gs_error_circular_reference);
2058
32
            }
2059
10.6k
        }
2060
10.6k
        s = (pdf_stream *)s->parent_obj;
2061
10.6k
    }
2062
2063
25.5k
    if (content_stream != NULL) {
2064
6.09k
        stream = content_stream;
2065
19.4k
    } else {
2066
19.4k
        code = pdfi_seek(ctx, ctx->main_stream, pdfi_stream_offset(ctx, stream_obj), SEEK_SET);
2067
19.4k
        if (code < 0)
2068
0
            return code;
2069
2070
19.4k
        if (stream_obj->length_valid) {
2071
19.1k
            if (stream_obj->Length == 0)
2072
60
                return 0;
2073
19.0k
            code = pdfi_apply_SubFileDecode_filter(ctx, stream_obj->Length, NULL, ctx->main_stream, &SubFile_stream, false);
2074
19.0k
        }
2075
382
        else
2076
382
            code = pdfi_apply_SubFileDecode_filter(ctx, 0, EODString, ctx->main_stream, &SubFile_stream, false);
2077
19.4k
        if (code < 0)
2078
0
            return code;
2079
2080
19.4k
        code = pdfi_filter(ctx, stream_obj, SubFile_stream, &stream, false);
2081
19.4k
        if (code < 0) {
2082
8
            pdfi_close_file(ctx, SubFile_stream);
2083
8
            return code;
2084
8
        }
2085
19.4k
    }
2086
2087
25.5k
    pdfi_set_stream_parent(ctx, stream_obj, ctx->current_stream);
2088
25.5k
    ctx->current_stream = stream_obj;
2089
2090
17.7M
    do {
2091
17.7M
        code = pdfi_read_token(ctx, stream, stream_obj->object_num, stream_obj->generation_num);
2092
17.7M
        if (code < 0) {
2093
38.9k
            if (code == gs_error_ioerror || code == gs_error_VMerror || ctx->args.pdfstoponerror) {
2094
918
                if (code == gs_error_ioerror) {
2095
918
                    pdfi_set_error(ctx, code, NULL, E_PDF_BADSTREAM, "pdfi_interpret_content_stream", (char *)"**** Error reading a content stream.  The page may be incomplete");
2096
918
                } else if (code == gs_error_VMerror) {
2097
0
                    pdfi_set_error(ctx, code, NULL, E_PDF_OUTOFMEMORY, "pdfi_interpret_content_stream", (char *)"**** Error ran out of memory reading a content stream.  The page may be incomplete");
2098
0
                }
2099
918
                goto exit;
2100
918
            }
2101
38.0k
            continue;
2102
38.9k
        }
2103
2104
17.7M
        if (pdfi_count_stack(ctx) <= 0) {
2105
14.0k
            if(stream->eof == true)
2106
13.7k
                break;
2107
14.0k
        }
2108
2109
17.7M
repaired_keyword:
2110
17.7M
        type = pdfi_type_of(ctx->stack_top[-1]);
2111
17.7M
        if (type == PDF_FAST_KEYWORD) {
2112
5.02M
            keyword = (pdf_keyword *)ctx->stack_top[-1];
2113
2114
5.02M
            switch((uintptr_t)keyword) {
2115
2.50k
                case TOKEN_ENDSTREAM:
2116
2.50k
                    pdfi_pop(ctx,1);
2117
2.50k
                    goto exit;
2118
0
                    break;
2119
5
                case TOKEN_ENDOBJ:
2120
5
                    pdfi_clearstack(ctx);
2121
5
                    code = pdfi_set_error_stop(ctx, gs_note_error(gs_error_syntaxerror), NULL, E_PDF_MISSINGENDSTREAM, "pdfi_interpret_content_stream", NULL);
2122
5
                    goto exit;
2123
0
                    break;
2124
0
                case TOKEN_INVALID_KEY:
2125
0
                    pdfi_clearstack(ctx);
2126
0
                    if ((code = pdfi_set_error_stop(ctx, gs_note_error(gs_error_limitcheck), NULL, E_PDF_KEYWORDTOOLONG, "pdfi_interpret_content_stream", NULL)) < 0)
2127
0
                        goto exit;
2128
0
                    break;
2129
0
                case TOKEN_TOO_LONG:
2130
0
                    pdfi_clearstack(ctx);
2131
0
                    if ((code = pdfi_set_error_stop(ctx, gs_note_error(gs_error_syntaxerror), NULL, E_PDF_MISSINGENDSTREAM, "pdfi_interpret_content_stream", NULL)) < 0)
2132
0
                        goto exit;
2133
0
                    break;
2134
5.02M
                default:
2135
5.02M
                    goto execute;
2136
5.02M
            }
2137
5.02M
        }
2138
12.6M
        else if (type == PDF_KEYWORD)
2139
394k
        {
2140
5.41M
execute:
2141
5.41M
            {
2142
5.41M
                pdf_dict *stream_dict = NULL;
2143
2144
5.41M
                code = pdfi_dict_from_obj(ctx, (pdf_obj *)stream_obj, &stream_dict);
2145
5.41M
                if (code < 0)
2146
0
                    goto exit;
2147
2148
5.41M
                code = pdfi_interpret_stream_operator(ctx, stream, stream_dict, page_dict);
2149
5.41M
                if (code == REPAIRED_KEYWORD)
2150
1
                    goto repaired_keyword;
2151
2152
5.41M
                if (code < 0) {
2153
262k
                    if ((code = pdfi_set_error_stop(ctx, code, NULL, E_PDF_TOKENERROR, "pdf_interpret_content_stream", NULL)) < 0) {
2154
105
                        pdfi_clearstack(ctx);
2155
105
                        goto exit;
2156
105
                    }
2157
262k
                }
2158
5.41M
            }
2159
5.41M
        }
2160
17.7M
        if(stream->eof == true)
2161
8.23k
            break;
2162
17.7M
    }while(1);
2163
2164
25.5k
exit:
2165
25.5k
    ctx->current_stream = pdfi_stream_parent(ctx, stream_obj);
2166
25.5k
    pdfi_clear_stream_parent(ctx, stream_obj);
2167
25.5k
    pdfi_close_file(ctx, stream);
2168
25.5k
    if (SubFile_stream != NULL)
2169
19.4k
        pdfi_close_file(ctx, SubFile_stream);
2170
25.5k
    return code;
2171
25.5k
}