Coverage Report

Created: 2026-09-14 07:34

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