Coverage Report

Created: 2026-08-08 08:00

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