Coverage Report

Created: 2026-04-01 07:17

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