Coverage Report

Created: 2026-10-28 08:05

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ghostpdl/pdf/pdf_int.c
Line
Count
Source
1
/* Copyright (C) 2018-2026 Artifex Software, Inc.
2
   All Rights Reserved.
3
4
   This software is provided AS-IS with no warranty, either express or
5
   implied.
6
7
   This software is distributed under license and may not be copied,
8
   modified or distributed except as expressly authorized under the terms
9
   of the license contained in the file LICENSE in this distribution.
10
11
   Refer to licensing information at http://www.artifex.com or contact
12
   Artifex Software, Inc.,  39 Mesa Street, Suite 108A, San Francisco,
13
   CA 94129, USA, for further information.
14
*/
15
16
/* The PDF interpreter written in C */
17
18
#include "pdf_int.h"
19
#include "pdf_file.h"
20
#include "strmio.h"
21
#include "stream.h"
22
#include "pdf_misc.h"
23
#include "pdf_path.h"
24
#include "pdf_colour.h"
25
#include "pdf_image.h"
26
#include "pdf_shading.h"
27
#include "pdf_font.h"
28
#include "pdf_font_types.h"
29
#include "pdf_cmap.h"
30
#include "pdf_text.h"
31
#include "pdf_gstate.h"
32
#include "pdf_stack.h"
33
#include "pdf_xref.h"
34
#include "pdf_dict.h"
35
#include "pdf_array.h"
36
#include "pdf_trans.h"
37
#include "pdf_optcontent.h"
38
#include "pdf_sec.h"
39
#include <stdlib.h>
40
41
#include "gsstate.h"    /* for gs_gstate_free */
42
43
/* we use -ve returns for error, 0 for success and +ve for 'take an action' */
44
/* Defining tis return so we do not need to define a new error */
45
79.5M
#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.98G
{
57
4.98G
    if (c == 0x00 || c == 0x09 || c == 0x0a || c == 0x0c || c == 0x0d || c == 0x20)
58
772M
        return true;
59
4.21G
    else
60
4.21G
        return false;
61
4.98G
}
62
63
static bool isdelimiter(char c)
64
2.88G
{
65
2.88G
    if (c == '/' || c == '(' || c == ')' || c == '[' || c == ']' || c == '<' || c == '>' || c == '{' || c == '}' || c == '%')
66
67.6M
        return true;
67
2.81G
    else
68
2.81G
        return false;
69
2.88G
}
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.13G
{
78
1.13G
    int c;
79
80
1.35G
    do {
81
1.35G
        c = pdfi_read_byte(ctx, s);
82
1.35G
        if (c < 0)
83
348k
            return 0;
84
1.35G
    } while (iswhite(c));
85
86
1.13G
    pdfi_unread_byte(ctx, s, (byte)c);
87
1.13G
    return 0;
88
1.13G
}
89
90
int pdfi_skip_eol(pdf_context *ctx, pdf_c_stream *s)
91
2.72M
{
92
2.72M
    int c;
93
94
3.00M
    do {
95
3.00M
        c = pdfi_read_byte(ctx, s);
96
3.00M
        if (c < 0 || c == 0x0a)
97
1.22M
            return 0;
98
3.00M
    } while (c != 0x0d);
99
1.50M
    c = pdfi_read_byte(ctx, s);
100
1.50M
    if (c == 0x0a)
101
1.49M
        return 0;
102
8.53k
    if (c >= 0)
103
8.44k
        pdfi_unread_byte(ctx, s, (byte)c);
104
8.53k
    pdfi_set_warning(ctx, 0, NULL, W_PDF_STREAM_BAD_KEYWORD, "pdfi_skip_eol", NULL);
105
8.53k
    return 0;
106
1.50M
}
107
108
/* Fast(ish) but inaccurate strtof, with Adobe overflow handling,
109
 * lifted from MuPDF. */
110
static float acrobat_compatible_atof(char *s)
111
134M
{
112
134M
    int neg = 0;
113
134M
    int i = 0;
114
115
142M
    while (*s == '-') {
116
7.91M
        neg = 1;
117
7.91M
        ++s;
118
7.91M
    }
119
134M
    while (*s == '+') {
120
6
        ++s;
121
6
    }
122
123
473M
    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
339M
        i = i * 10 + (*s - '0');
129
339M
        ++s;
130
339M
    }
131
132
134M
    if (*s == '.') {
133
134M
        float MAX = (MAX_FLOAT-9)/10;
134
134M
        float v = (float)i;
135
134M
        float n = 0;
136
134M
        float d = 1;
137
134M
        ++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
574M
        while (*s >= '0' && *s <= '9' && n <= MAX) {
141
440M
            n = 10 * n + (*s - '0');
142
440M
            d = 10 * d;
143
440M
            ++s;
144
440M
        }
145
134M
        v += n / d;
146
134M
        return neg ? -v : v;
147
134M
    } else {
148
95.8k
        return (float)(neg ? -i : i);
149
95.8k
    }
150
134M
}
151
152
int pdfi_read_bare_int(pdf_context *ctx, pdf_c_stream *s, int *parsed_int)
153
106M
{
154
106M
    int index = 0;
155
106M
    int int_val = 0;
156
106M
    int negative = 0;
157
106M
    int tenth_max_int = max_int / 10, tenth_max_uint = max_uint / 10;
158
106M
    bool overflowed = false;
159
106M
    int code = 0;
160
161
106M
restart:
162
106M
    pdfi_skip_white(ctx, s);
163
164
454M
    do {
165
454M
        int c = pdfi_read_byte(ctx, s);
166
454M
        if (c == EOFC)
167
3.83k
            break;
168
169
454M
        if (c < 0)
170
7.42k
            return_error(gs_error_ioerror);
171
172
454M
        if (iswhite(c)) {
173
105M
            break;
174
348M
        } else if (c == '%' && index == 0) {
175
46.3k
            pdfi_skip_comment(ctx, s);
176
46.3k
            goto restart;
177
348M
        } else if (isdelimiter(c)) {
178
13.9k
            pdfi_unread_byte(ctx, s, (byte)c);
179
13.9k
            break;
180
13.9k
        }
181
182
348M
        if (c >= '0' && c <= '9') {
183
348M
            if (!overflowed) {
184
347M
                if ((negative && int_val <= tenth_max_int) || (!negative && int_val <= tenth_max_uint))
185
347M
                    int_val = int_val*10 + c - '0';
186
2.31k
                else {
187
2.31k
                    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
2.31k
                    overflowed = true;
191
2.31k
                }
192
347M
            }
193
348M
        } else if (c == '.') {
194
2.51k
            goto error;
195
208k
        } else if (c == 'e' || c == 'E') {
196
2.66k
            pdfi_log_info(ctx, "pdfi_read_bare_int", (char *)"Invalid number format: scientific notation\n");
197
2.66k
            goto error;
198
205k
        } else if (c == '-') {
199
            /* Any - sign not at the start of the string indicates a malformed number. */
200
783
            if (index != 0 || negative) {
201
145
                pdfi_log_info(ctx, "pdfi_read_bare_int", (char *)"Invalid number format: sign not at the start\n");
202
145
                goto error;
203
145
            }
204
638
            negative = 1;
205
204k
        } else if (c == '+') {
206
133k
            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
133k
                continue;
210
133k
            } else {
211
151
                pdfi_log_info(ctx, "pdfi_read_bare_int", (char *)"Invalid number format: sign not at the start\n");
212
151
                goto error;
213
151
            }
214
133k
        } else {
215
71.3k
            if (index > 0) {
216
6.92k
                pdfi_log_info(ctx, "pdfi_read_bare_int", (char *)"Invalid number format: Ignoring missing white space while parsing number\n");
217
6.92k
                goto error;
218
6.92k
            }
219
64.3k
            pdfi_unread_byte(ctx, s, (byte)c);
220
64.3k
            goto error;
221
71.3k
        }
222
348M
        if (++index > 255)
223
201
            goto error;
224
348M
    } while(1);
225
226
105M
    *parsed_int = negative ? -int_val : int_val;
227
105M
    if (ctx->args.pdfdebug)
228
0
        outprintf(ctx->memory, " %d", *parsed_int);
229
105M
    return (index > 0);
230
231
77.0k
error:
232
77.0k
    *parsed_int = 0;
233
77.0k
    return_error(gs_error_syntaxerror);
234
106M
}
235
236
static int pdfi_read_num(pdf_context *ctx, pdf_c_stream *s, uint32_t indirect_num, uint32_t indirect_gen)
237
308M
{
238
308M
    byte Buffer[256];
239
308M
    unsigned short index = 0;
240
308M
    bool real = false;
241
308M
    bool has_decimal_point = false;
242
308M
    bool has_exponent = false;
243
308M
    unsigned short exponent_index = 0;
244
308M
    pdf_num *num;
245
308M
    int code = 0, malformed = false, doubleneg = false, recovered = false, negative = false, overflowed = false;
246
308M
    unsigned int int_val = 0;
247
308M
    int tenth_max_int = max_int / 10, tenth_max_uint = max_uint / 10;
248
249
308M
    pdfi_skip_white(ctx, s);
250
251
1.72G
    do {
252
1.72G
        int c = pdfi_read_byte(ctx, s);
253
1.72G
        if (c == EOFC) {
254
11.4k
            Buffer[index] = 0x00;
255
11.4k
            break;
256
11.4k
        }
257
258
1.72G
        if (c < 0)
259
3.92k
            return_error(gs_error_ioerror);
260
261
1.72G
        if (iswhite(c)) {
262
274M
            Buffer[index] = 0x00;
263
274M
            break;
264
1.44G
        } else if (isdelimiter(c)) {
265
27.8M
            pdfi_unread_byte(ctx, s, (byte)c);
266
27.8M
            Buffer[index] = 0x00;
267
27.8M
            break;
268
27.8M
        }
269
1.42G
        Buffer[index] = (byte)c;
270
271
1.42G
        if (c >= '0' && c <= '9') {
272
1.25G
            if  (!(malformed && recovered) && !overflowed && !real) {
273
774M
                if ((negative && int_val <= tenth_max_int) || (!negative && int_val <= tenth_max_uint))
274
772M
                    int_val = int_val*10 + c - '0';
275
1.36M
                else {
276
1.36M
                    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.36M
                    overflowed = true;
280
1.36M
                }
281
774M
            }
282
1.25G
        } else if (c == '.') {
283
138M
            if (has_decimal_point == true) {
284
2.97M
                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.97M
                malformed = true;
288
135M
            } else {
289
135M
                has_decimal_point = true;
290
135M
                real = true;
291
135M
            }
292
138M
        } 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
471k
            if (has_exponent == true) {
297
35.3k
                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
35.3k
                malformed = true;
301
436k
            } else {
302
436k
                pdfi_set_warning(ctx, 0, NULL, W_PDF_NUM_EXPONENT, "pdfi_read_num", NULL);
303
436k
                has_exponent = true;
304
436k
                exponent_index = index;
305
436k
                real = true;
306
436k
            }
307
24.5M
        } else if (c == '-') {
308
            /* Any - sign not at the start of the string, or just after an exponent
309
             * indicates a malformed number. */
310
18.1M
            if (!(index == 0 || (has_exponent && index == exponent_index+1))) {
311
4.40M
                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.40M
                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
619k
                    malformed = true;
318
619k
                    Buffer[index] = 0;
319
619k
                    recovered = true;
320
619k
                }
321
4.40M
            }
322
18.1M
            if (!has_exponent && !(malformed && recovered)) {
323
17.5M
                doubleneg = negative;
324
17.5M
                negative = 1;
325
17.5M
            }
326
18.1M
        } else if (c == '+') {
327
175k
            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
165k
                index--;
331
165k
            } else {
332
10.1k
                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
10.1k
                if (Buffer[index - 1] != '-') {
336
                    /* We are parsing a number line 123-56. We should continue parsing, but
337
                     * ignore anything from the second -. */
338
9.77k
                    malformed = true;
339
9.77k
                    Buffer[index] = 0;
340
9.77k
                    recovered = true;
341
9.77k
                }
342
10.1k
            }
343
6.13M
        } else {
344
6.13M
            if ((code = pdfi_set_error_stop(ctx, gs_note_error(gs_error_syntaxerror), NULL, E_PDF_MISSINGWHITESPACE, "pdfi_read_num", NULL)) < 0) {
345
0
                return code;
346
0
            }
347
6.13M
            pdfi_unread_byte(ctx, s, (byte)c);
348
6.13M
            Buffer[index] = 0x00;
349
6.13M
            break;
350
6.13M
        }
351
1.41G
        if (++index > 255)
352
45.2k
            return_error(gs_error_syntaxerror);
353
1.41G
    } while(1);
354
355
308M
    if (real && (!malformed || (malformed && recovered)))
356
134M
        code = pdfi_object_alloc(ctx, PDF_REAL, 0, (pdf_obj **)&num);
357
173M
    else
358
173M
        code = pdfi_object_alloc(ctx, PDF_INT, 0, (pdf_obj **)&num);
359
308M
    if (code < 0)
360
0
        return code;
361
362
308M
    if ((malformed && !recovered) || (!real && doubleneg)) {
363
1.58M
        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.58M
        num->value.i = 0;
367
307M
    } else if (has_exponent) {
368
407k
        float f, exp;
369
407k
        char *p = (char *)strstr((const char *)Buffer, "e");
370
371
407k
        if (p == NULL)
372
38.6k
            p = (char *)strstr((const char *)Buffer, "E");
373
374
407k
        if (p == NULL) {
375
3.11k
            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
3.11k
            num->value.d = 0;
379
403k
        } else {
380
403k
            p++;
381
382
403k
            if (sscanf((char *)p, "%g", &exp) != 1 || exp > 38) {
383
371k
                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
371k
                num->value.d = 0;
387
371k
            } else {
388
32.6k
                if (sscanf((char *)Buffer, "%g", &f) == 1) {
389
32.0k
                    num->value.d = f;
390
32.0k
                } else {
391
581
                    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
581
                    num->value.d = 0;
395
581
                }
396
32.6k
            }
397
403k
        }
398
306M
    } else if (real) {
399
134M
        num->value.d = acrobat_compatible_atof((char *)Buffer);
400
172M
    } else {
401
        /* The doubleneg case is taken care of above. */
402
172M
        num->value.i = negative ? (int64_t)int_val * -1 : (int64_t)int_val;
403
172M
    }
404
308M
    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
308M
    num->indirect_num = indirect_num;
411
308M
    num->indirect_gen = indirect_gen;
412
413
308M
    code = pdfi_push(ctx, (pdf_obj *)num);
414
415
308M
exit:
416
308M
    if (code < 0)
417
947
        pdfi_free_object((pdf_obj *)num);
418
419
308M
    return code;
420
308M
}
421
422
static int pdfi_read_name(pdf_context *ctx, pdf_c_stream *s, uint32_t indirect_num, uint32_t indirect_gen)
423
86.5M
{
424
86.5M
    char *Buffer, *NewBuf = NULL;
425
86.5M
    unsigned short index = 0;
426
86.5M
    short bytes = 0;
427
86.5M
    uint32_t size = 256;
428
86.5M
    pdf_name *name = NULL;
429
86.5M
    int code;
430
431
86.5M
    Buffer = (char *)gs_alloc_bytes(ctx->memory, size, "pdfi_read_name");
432
86.5M
    if (Buffer == NULL)
433
0
        return_error(gs_error_VMerror);
434
435
627M
    do {
436
627M
        int c = pdfi_read_byte(ctx, s);
437
627M
        if (c < 0)
438
10.2k
            break;
439
440
627M
        if (iswhite((char)c)) {
441
56.8M
            Buffer[index] = 0x00;
442
56.8M
            break;
443
570M
        } else if (isdelimiter((char)c)) {
444
29.7M
            pdfi_unread_byte(ctx, s, (char)c);
445
29.7M
            Buffer[index] = 0x00;
446
29.7M
            break;
447
29.7M
        }
448
540M
        Buffer[index] = (char)c;
449
450
        /* Check for and convert escaped name characters */
451
540M
        if (c == '#') {
452
290k
            byte NumBuf[2];
453
454
290k
            bytes = pdfi_read_bytes(ctx, (byte *)&NumBuf, 1, 2, s);
455
290k
            if (bytes < 2 || (!ishex(NumBuf[0]) || !ishex(NumBuf[1]))) {
456
139k
                pdfi_set_warning(ctx, 0, NULL, W_PDF_BAD_NAME_ESCAPE, "pdfi_read_name", NULL);
457
139k
                pdfi_unread(ctx, s, (byte *)NumBuf, bytes);
458
                /* This leaves the name buffer with a # in it, rather than anything sane! */
459
139k
            }
460
151k
            else
461
151k
                Buffer[index] = (fromhex(NumBuf[0]) << 4) + fromhex(NumBuf[1]);
462
290k
        }
463
464
        /* If we ran out of memory, increase the buffer size */
465
540M
        if (index++ >= size - 1) {
466
50.1k
            NewBuf = (char *)gs_alloc_bytes(ctx->memory, (size_t)size + 256, "pdfi_read_name");
467
50.1k
            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
50.1k
            memcpy(NewBuf, Buffer, size);
472
50.1k
            gs_free_object(ctx->memory, Buffer, "pdfi_read_name");
473
50.1k
            Buffer = NewBuf;
474
50.1k
            size += 256;
475
50.1k
        }
476
540M
    } while(1);
477
478
86.5M
    code = pdfi_object_alloc(ctx, PDF_NAME, index, (pdf_obj **)&name);
479
86.5M
    if (code < 0) {
480
0
        gs_free_object(ctx->memory, Buffer, "pdfi_read_name error");
481
0
        return code;
482
0
    }
483
86.5M
    memcpy(name->data, Buffer, index);
484
86.5M
    name->indirect_num = indirect_num;
485
86.5M
    name->indirect_gen = indirect_gen;
486
487
86.5M
    if (ctx->args.pdfdebug)
488
0
        outprintf(ctx->memory, " /%s", Buffer);
489
490
86.5M
    gs_free_object(ctx->memory, Buffer, "pdfi_read_name");
491
492
86.5M
    code = pdfi_push(ctx, (pdf_obj *)name);
493
494
86.5M
    if (code < 0)
495
0
        pdfi_free_object((pdf_obj *)name);
496
497
86.5M
    return code;
498
86.5M
}
499
500
static int pdfi_read_hexstring(pdf_context *ctx, pdf_c_stream *s, uint32_t indirect_num, uint32_t indirect_gen)
501
3.98M
{
502
3.98M
    char *Buffer, *NewBuf = NULL;
503
3.98M
    unsigned short index = 0;
504
3.98M
    uint32_t size = 256;
505
3.98M
    pdf_string *string = NULL;
506
3.98M
    int code, hex0, hex1;
507
508
3.98M
    Buffer = (char *)gs_alloc_bytes(ctx->memory, size, "pdfi_read_hexstring");
509
3.98M
    if (Buffer == NULL)
510
0
        return_error(gs_error_VMerror);
511
512
3.98M
    if (ctx->args.pdfdebug)
513
0
        outprintf(ctx->memory, " <");
514
515
151M
    do {
516
151M
        do {
517
151M
            hex0 = pdfi_read_byte(ctx, s);
518
151M
            if (hex0 < 0)
519
770
                break;
520
151M
        } while(iswhite(hex0));
521
151M
        if (hex0 < 0)
522
770
            break;
523
524
151M
        if (hex0 == '>')
525
3.63M
            break;
526
527
147M
        if (ctx->args.pdfdebug)
528
0
            outprintf(ctx->memory, "%c", (char)hex0);
529
530
147M
        do {
531
147M
            hex1 = pdfi_read_byte(ctx, s);
532
147M
            if (hex1 < 0)
533
749
                break;
534
147M
        } while(iswhite(hex1));
535
147M
        if (hex1 < 0)
536
749
            break;
537
538
147M
        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
46.2k
            hex1 = 0x30;
544
46.2k
            if (!ishex(hex0) || !ishex(hex1)) {
545
2.47k
                code = gs_note_error(gs_error_syntaxerror);
546
2.47k
                goto exit;
547
2.47k
            }
548
43.8k
            Buffer[index] = (fromhex(hex0) << 4) + fromhex(hex1);
549
43.8k
            if (ctx->args.pdfdebug)
550
0
                outprintf(ctx->memory, "%c", hex1);
551
43.8k
            break;
552
46.2k
        }
553
554
147M
        if (!ishex(hex0) || !ishex(hex1)) {
555
304k
            code = gs_note_error(gs_error_syntaxerror);
556
304k
            goto exit;
557
304k
        }
558
559
147M
        if (ctx->args.pdfdebug)
560
0
            outprintf(ctx->memory, "%c", (char)hex1);
561
562
147M
        Buffer[index] = (fromhex(hex0) << 4) + fromhex(hex1);
563
564
147M
        if (index++ >= size - 1) {
565
501k
            NewBuf = (char *)gs_alloc_bytes(ctx->memory, (size_t)size + 256, "pdfi_read_hexstring");
566
501k
            if (NewBuf == NULL) {
567
0
                code = gs_note_error(gs_error_VMerror);
568
0
                goto exit;
569
0
            }
570
501k
            memcpy(NewBuf, Buffer, size);
571
501k
            gs_free_object(ctx->memory, Buffer, "pdfi_read_hexstring");
572
501k
            Buffer = NewBuf;
573
501k
            size += 256;
574
501k
        }
575
147M
    } while(1);
576
577
3.67M
    if (ctx->args.pdfdebug)
578
0
        outprintf(ctx->memory, ">");
579
580
3.67M
    code = pdfi_object_alloc(ctx, PDF_STRING, index, (pdf_obj **)&string);
581
3.67M
    if (code < 0)
582
0
        goto exit;
583
3.67M
    memcpy(string->data, Buffer, index);
584
3.67M
    string->indirect_num = indirect_num;
585
3.67M
    string->indirect_gen = indirect_gen;
586
587
3.67M
    if (ctx->encryption.is_encrypted && ctx->encryption.decrypt_strings) {
588
2.33k
        code = pdfi_decrypt_string(ctx, string);
589
2.33k
        if (code < 0)
590
0
            return code;
591
2.33k
    }
592
593
3.67M
    code = pdfi_push(ctx, (pdf_obj *)string);
594
3.67M
    if (code < 0)
595
0
        pdfi_free_object((pdf_obj *)string);
596
597
3.98M
 exit:
598
3.98M
    gs_free_object(ctx->memory, Buffer, "pdfi_read_hexstring");
599
3.98M
    return code;
600
3.67M
}
601
602
static int pdfi_read_string(pdf_context *ctx, pdf_c_stream *s, uint32_t indirect_num, uint32_t indirect_gen)
603
15.5M
{
604
15.5M
    char *Buffer, *NewBuf = NULL;
605
15.5M
    unsigned short index = 0;
606
15.5M
    uint32_t size = 256;
607
15.5M
    pdf_string *string = NULL;
608
15.5M
    int c, code, nesting = 0;
609
15.5M
    bool escape = false, skip_lf = false, exit_loop = false;
610
611
15.5M
    Buffer = (char *)gs_alloc_bytes(ctx->memory, size, "pdfi_read_string");
612
15.5M
    if (Buffer == NULL)
613
0
        return_error(gs_error_VMerror);
614
615
795M
    do {
616
795M
        if (index >= size - 1) {
617
1.79M
            NewBuf = (char *)gs_alloc_bytes(ctx->memory, (size_t)size + 256, "pdfi_read_string");
618
1.79M
            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.79M
            memcpy(NewBuf, Buffer, size);
623
1.79M
            gs_free_object(ctx->memory, Buffer, "pdfi_read_string");
624
1.79M
            Buffer = NewBuf;
625
1.79M
            size += 256;
626
1.79M
        }
627
628
795M
        c = pdfi_read_byte(ctx, s);
629
630
795M
        if (c < 0) {
631
22.1k
            if (nesting > 0 && (code = pdfi_set_error_stop(ctx, gs_note_error(gs_error_syntaxerror), NULL, E_PDF_UNESCAPEDSTRING, "pdfi_read_string", NULL)) < 0) {
632
0
                gs_free_object(ctx->memory, Buffer, "pdfi_read_string error");
633
0
                return code;
634
0
            }
635
22.1k
            Buffer[index] = 0x00;
636
22.1k
            break;
637
22.1k
        }
638
639
795M
        if (skip_lf) {
640
3.51M
            skip_lf = false;
641
3.51M
            if (c == 0x0a)
642
1.18M
                continue;
643
3.51M
        }
644
794M
        Buffer[index] = (char)c;
645
646
794M
        if (escape) {
647
3.35M
            escape = false;
648
3.35M
            switch (Buffer[index]) {
649
58.1k
                case 0x0d:
650
58.1k
                    skip_lf = true;
651
70.0k
                case 0x0a:
652
70.0k
                    continue;
653
75.6k
                case 'n':
654
75.6k
                    Buffer[index] = 0x0a;
655
75.6k
                    break;
656
79.4k
                case 'r':
657
79.4k
                    Buffer[index] = 0x0d;
658
79.4k
                    break;
659
20.1k
                case 't':
660
20.1k
                    Buffer[index] = 0x09;
661
20.1k
                    break;
662
23.4k
                case 'b':
663
23.4k
                    Buffer[index] = 0x08;
664
23.4k
                    break;
665
25.4k
                case 'f':
666
25.4k
                    Buffer[index] = 0x0c;
667
25.4k
                    break;
668
172k
                case '(':
669
347k
                case ')':
670
454k
                case '\\':
671
454k
                    break;
672
650k
                case '0':
673
667k
                case '1':
674
984k
                case '2':
675
1.20M
                case '3':
676
1.22M
                case '4':
677
1.23M
                case '5':
678
1.24M
                case '6':
679
1.25M
                case '7':
680
1.25M
                {
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.25M
                    int c1 = pdfi_read_byte(ctx, s);
685
1.25M
                    c -= '0';
686
1.25M
                    if (c1 < 0) {
687
                        /* Nothing to do, or unread */
688
1.25M
                    } else if (c1 < '0' || c1 > '7') {
689
84.0k
                        pdfi_unread_byte(ctx, s, (char)c1);
690
1.16M
                    } else {
691
1.16M
                        c = c*8 + c1 - '0';
692
1.16M
                        c1 = pdfi_read_byte(ctx, s);
693
1.16M
                        if (c1 < 0) {
694
                            /* Nothing to do, or unread */
695
1.16M
                        } else if (c1 < '0' || c1 > '7') {
696
30.3k
                            pdfi_unread_byte(ctx, s, (char)c1);
697
30.3k
                        } else
698
1.13M
                            c = c*8 + c1 - '0';
699
1.16M
                    }
700
1.25M
                    Buffer[index] = c;
701
1.25M
                    break;
702
1.24M
                }
703
1.35M
                default:
704
                    /* PDF Reference, literal strings, if the character following a
705
                     * escape \ character is not recognised, then it is ignored.
706
                     */
707
1.35M
                    escape = false;
708
1.35M
                    index++;
709
1.35M
                    continue;
710
3.35M
            }
711
790M
        } else {
712
790M
            switch(Buffer[index]) {
713
3.45M
                case 0x0d:
714
3.45M
                    Buffer[index] = 0x0a;
715
3.45M
                    skip_lf = true;
716
3.45M
                    break;
717
18.5M
                case ')':
718
18.5M
                    if (nesting == 0) {
719
15.5M
                        Buffer[index] = 0x00;
720
15.5M
                        exit_loop = true;
721
15.5M
                    } else
722
2.96M
                        nesting--;
723
18.5M
                    break;
724
3.35M
                case '\\':
725
3.35M
                    escape = true;
726
3.35M
                    continue;
727
3.57M
                case '(':
728
3.57M
                    nesting++;
729
3.57M
                    break;
730
761M
                default:
731
761M
                    break;
732
790M
            }
733
790M
        }
734
735
789M
        if (exit_loop)
736
15.5M
            break;
737
738
773M
        index++;
739
779M
    } while(1);
740
741
15.5M
    code = pdfi_object_alloc(ctx, PDF_STRING, index, (pdf_obj **)&string);
742
15.5M
    if (code < 0) {
743
0
        gs_free_object(ctx->memory, Buffer, "pdfi_read_name error");
744
0
        return code;
745
0
    }
746
15.5M
    memcpy(string->data, Buffer, index);
747
15.5M
    string->indirect_num = indirect_num;
748
15.5M
    string->indirect_gen = indirect_gen;
749
750
15.5M
    gs_free_object(ctx->memory, Buffer, "pdfi_read_string");
751
752
15.5M
    if (ctx->encryption.is_encrypted && ctx->encryption.decrypt_strings) {
753
14.7k
        code = pdfi_decrypt_string(ctx, string);
754
14.7k
        if (code < 0)
755
0
            return code;
756
14.7k
    }
757
758
15.5M
    if (ctx->args.pdfdebug) {
759
0
        int i;
760
0
        outprintf(ctx->memory, " (");
761
0
        for (i=0;i<string->length;i++)
762
0
            outprintf(ctx->memory, "%c", string->data[i]);
763
0
        outprintf(ctx->memory, ")");
764
0
    }
765
766
15.5M
    code = pdfi_push(ctx, (pdf_obj *)string);
767
15.5M
    if (code < 0) {
768
0
        pdfi_free_object((pdf_obj *)string);
769
0
        pdfi_set_error(ctx, code, NULL, 0, "pdfi_read_string", NULL);
770
0
    }
771
772
15.5M
    return code;
773
15.5M
}
774
775
int pdfi_read_dict(pdf_context *ctx, pdf_c_stream *s, uint32_t indirect_num, uint32_t indirect_gen)
776
8.73k
{
777
8.73k
    int code, depth;
778
779
8.73k
    code = pdfi_read_token(ctx, s, indirect_num, indirect_gen);
780
8.73k
    if (code < 0)
781
14
        return code;
782
8.72k
    if (code == 0)
783
0
        return_error(gs_error_syntaxerror);
784
785
8.72k
    if (pdfi_type_of(ctx->stack_top[-1]) != PDF_DICT_MARK)
786
19
        return_error(gs_error_typecheck);
787
8.70k
    depth = pdfi_count_stack(ctx);
788
789
142k
    do {
790
142k
        code = pdfi_read_token(ctx, s, indirect_num, indirect_gen);
791
142k
        if (code < 0)
792
129
            return code;
793
141k
        if (code == 0)
794
16
            return_error(gs_error_syntaxerror);
795
141k
    } while(pdfi_count_stack(ctx) > depth);
796
8.55k
    return 0;
797
8.70k
}
798
799
int pdfi_skip_comment(pdf_context *ctx, pdf_c_stream *s)
800
1.78M
{
801
1.78M
    int c;
802
803
1.78M
    if (ctx->args.pdfdebug)
804
0
        outprintf (ctx->memory, " %%");
805
806
45.7M
    do {
807
45.7M
        c = pdfi_read_byte(ctx, s);
808
45.7M
        if (c < 0)
809
9.59k
            break;
810
811
45.7M
        if (ctx->args.pdfdebug)
812
0
            outprintf (ctx->memory, "%c", (char)c);
813
814
45.7M
    } while (c != 0x0a && c != 0x0d);
815
816
1.78M
    return 0;
817
1.78M
}
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
126M
#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.93M
{
831
3.93M
    byte Buffer[256];
832
3.93M
    int code, index = 0;
833
3.93M
    int c;
834
3.93M
    void *t;
835
836
3.93M
    pdfi_skip_white(ctx, s);
837
838
24.4M
    do {
839
24.4M
        c = pdfi_read_byte(ctx, s);
840
24.4M
        if (c < 0)
841
25.6k
            break;
842
843
24.4M
        if (iswhite(c) || isdelimiter(c)) {
844
3.91M
            pdfi_unread_byte(ctx, s, (byte)c);
845
3.91M
            break;
846
3.91M
        }
847
20.5M
        Buffer[index] = (byte)c;
848
20.5M
        index++;
849
20.5M
    } while (index < 255);
850
851
3.93M
    if (index >= 255 || index == 0) {
852
34.7k
        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
34.7k
        return TOKEN_INVALID_KEY;
856
34.7k
    }
857
858
3.90M
    Buffer[index] = 0x00;
859
3.90M
    t = (void *)bsearch((const void *)Buffer,
860
3.90M
                (const void *)pdf_token_strings[TOKEN_INVALID_KEY+1],
861
3.90M
                nelems(pdf_token_strings)-(TOKEN_INVALID_KEY+1),
862
3.90M
                sizeof(pdf_token_strings[0]),
863
3.90M
                (bsearch_comparator)&strcmp);
864
3.90M
    if (t == NULL)
865
76.7k
        return TOKEN_INVALID_KEY;
866
867
3.82M
    if (ctx->args.pdfdebug)
868
0
        outprintf(ctx->memory, " %s\n", Buffer);
869
870
3.82M
    return (((const char *)t) - pdf_token_strings[0]) / sizeof(pdf_token_strings[0]);
871
3.90M
}
872
873
static pdf_key lookup_keyword(const byte *Buffer)
874
122M
{
875
122M
    const void *t = bsearch((const void *)Buffer,
876
122M
                      (const void *)pdf_token_strings[TOKEN_INVALID_KEY+1],
877
122M
                      nelems(pdf_token_strings)-(TOKEN_INVALID_KEY+1),
878
122M
                      sizeof(pdf_token_strings[0]),
879
122M
                      (bsearch_comparator)&strcmp);
880
122M
    if (t == NULL)
881
15.0M
        return TOKEN_NOT_A_KEYWORD;
882
883
107M
    return (pdf_key)((((const char *)t) - pdf_token_strings[0]) /
884
107M
                     sizeof(pdf_token_strings[0]));
885
122M
}
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
120M
{
896
120M
    byte Buffer[256];
897
120M
    unsigned short index = 0;
898
120M
    int c, code;
899
120M
    pdf_keyword *keyword;
900
120M
    pdf_key key;
901
902
120M
    pdfi_skip_white(ctx, s);
903
904
485M
    do {
905
485M
        c = pdfi_read_byte(ctx, s);
906
485M
        if (c < 0)
907
229k
            break;
908
909
484M
        if (iswhite(c) || isdelimiter(c)) {
910
120M
            pdfi_unread_byte(ctx, s, (byte)c);
911
120M
            break;
912
120M
        }
913
364M
        Buffer[index] = (byte)c;
914
364M
        index++;
915
364M
    } while (index < 255);
916
917
120M
    if (index >= 255 || index == 0) {
918
279k
        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
279k
        key = (index >= 255 ? TOKEN_TOO_LONG : TOKEN_INVALID_KEY);
922
279k
        index = 0;
923
279k
        Buffer[0] = 0;
924
120M
    } else {
925
120M
        Buffer[index] = 0x00;
926
120M
        key = lookup_keyword(Buffer);
927
928
120M
        if (ctx->args.pdfdebug)
929
0
            outprintf(ctx->memory, " %s\n", Buffer);
930
931
120M
        switch (key) {
932
15.3M
            case TOKEN_R:
933
15.3M
            {
934
15.3M
                pdf_indirect_ref *o;
935
15.3M
                uint64_t obj_num;
936
15.3M
                uint32_t gen_num;
937
938
15.3M
                if(pdfi_count_stack(ctx) < 2) {
939
37.7k
                    pdfi_clearstack(ctx);
940
37.7k
                    return_error(gs_error_stackunderflow);
941
37.7k
                }
942
943
15.3M
                if(pdfi_type_of(ctx->stack_top[-1]) != PDF_INT || pdfi_type_of(ctx->stack_top[-2]) != PDF_INT) {
944
48.7k
                    pdfi_clearstack(ctx);
945
48.7k
                    return_error(gs_error_typecheck);
946
48.7k
                }
947
948
15.2M
                gen_num = ((pdf_num *)ctx->stack_top[-1])->value.i;
949
15.2M
                pdfi_pop(ctx, 1);
950
15.2M
                obj_num = ((pdf_num *)ctx->stack_top[-1])->value.i;
951
15.2M
                pdfi_pop(ctx, 1);
952
953
15.2M
                code = pdfi_object_alloc(ctx, PDF_INDIRECT, 0, (pdf_obj **)&o);
954
15.2M
                if (code < 0)
955
0
                    return code;
956
957
15.2M
                o->ref_generation_num = gen_num;
958
15.2M
                o->ref_object_num = obj_num;
959
15.2M
                o->indirect_num = indirect_num;
960
15.2M
                o->indirect_gen = indirect_gen;
961
962
15.2M
                code = pdfi_push(ctx, (pdf_obj *)o);
963
15.2M
                if (code < 0)
964
0
                    pdfi_free_object((pdf_obj *)o);
965
966
15.2M
                return code;
967
15.2M
            }
968
15.0M
            case TOKEN_NOT_A_KEYWORD:
969
                 /* Unexpected keyword found. We'll allocate an object for the buffer below. */
970
15.0M
                 break;
971
2.72M
            case TOKEN_STREAM:
972
2.72M
                code = pdfi_skip_eol(ctx, s);
973
2.72M
                if (code < 0)
974
0
                    return code;
975
                /* fallthrough */
976
3.35M
            case TOKEN_PDF_TRUE:
977
3.77M
            case TOKEN_PDF_FALSE:
978
3.84M
            case TOKEN_null:
979
89.9M
            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
89.9M
                return pdfi_push(ctx, (pdf_obj *)(intptr_t)key);
984
120M
        }
985
120M
    }
986
987
    /* Unexpected keyword. We can't handle this with the fast no-allocation case. */
988
15.2M
    code = pdfi_object_alloc(ctx, PDF_KEYWORD, index, (pdf_obj **)&keyword);
989
15.2M
    if (code < 0)
990
0
        return code;
991
992
15.2M
    if (index)
993
15.0M
        memcpy(keyword->data, Buffer, index);
994
995
    /* keyword->length set as part of allocation. */
996
15.2M
    keyword->indirect_num = indirect_num;
997
15.2M
    keyword->indirect_gen = indirect_gen;
998
999
15.2M
    code = pdfi_push(ctx, (pdf_obj *)keyword);
1000
15.2M
    if (code < 0)
1001
30
        pdfi_free_object((pdf_obj *)keyword);
1002
1003
15.2M
    return code;
1004
15.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
586M
{
1011
586M
    int c, code;
1012
1013
590M
rescan:
1014
590M
    pdfi_skip_white(ctx, s);
1015
1016
590M
    c = pdfi_read_byte(ctx, s);
1017
590M
    if (c == EOFC)
1018
298k
        return 0;
1019
590M
    if (c < 0)
1020
13.2k
        return_error(gs_error_ioerror);
1021
1022
590M
    switch(c) {
1023
75.6M
        case 0x30:
1024
120M
        case 0x31:
1025
156M
        case 0x32:
1026
197M
        case 0x33:
1027
230M
        case 0x34:
1028
250M
        case 0x35:
1029
269M
        case 0x36:
1030
281M
        case 0x37:
1031
288M
        case 0x38:
1032
293M
        case 0x39:
1033
293M
        case '+':
1034
307M
        case '-':
1035
308M
        case '.':
1036
308M
            pdfi_unread_byte(ctx, s, (byte)c);
1037
308M
            code = pdfi_read_num(ctx, s, indirect_num, indirect_gen);
1038
308M
            if (code < 0)
1039
50.1k
                return code;
1040
308M
            break;
1041
308M
        case '/':
1042
86.5M
            code = pdfi_read_name(ctx, s, indirect_num, indirect_gen);
1043
86.5M
            if (code < 0)
1044
0
                return code;
1045
86.5M
            return 1;
1046
0
            break;
1047
16.1M
        case '<':
1048
16.1M
            c = pdfi_read_byte(ctx, s);
1049
16.1M
            if (c < 0)
1050
346
                return (gs_error_ioerror);
1051
16.1M
            if (iswhite(c)) {
1052
51.4k
                code = pdfi_skip_white(ctx, s);
1053
51.4k
                if (code < 0)
1054
0
                    return code;
1055
51.4k
                c = pdfi_read_byte(ctx, s);
1056
51.4k
            }
1057
16.1M
            if (c == '<') {
1058
11.6M
                if (ctx->args.pdfdebug)
1059
0
                    outprintf (ctx->memory, " <<\n");
1060
11.6M
                if (ctx->object_nesting < MAX_NESTING_DEPTH) {
1061
11.0M
                    ctx->object_nesting++;
1062
11.0M
                    code = pdfi_mark_stack(ctx, PDF_DICT_MARK);
1063
11.0M
                    if (code < 0)
1064
1
                        return code;
1065
11.0M
                }
1066
530k
                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
11.6M
                return 1;
1070
11.6M
            } else if (c == '>') {
1071
31.2k
                pdfi_unread_byte(ctx, s, (byte)c);
1072
31.2k
                code = pdfi_read_hexstring(ctx, s, indirect_num, indirect_gen);
1073
31.2k
                if (code < 0)
1074
0
                    return code;
1075
31.2k
                return 1;
1076
4.53M
            } else if (ishex(c)) {
1077
3.95M
                pdfi_unread_byte(ctx, s, (byte)c);
1078
3.95M
                code = pdfi_read_hexstring(ctx, s, indirect_num, indirect_gen);
1079
3.95M
                if (code < 0)
1080
306k
                    return code;
1081
3.95M
            }
1082
582k
            else
1083
582k
                return_error(gs_error_syntaxerror);
1084
3.64M
            break;
1085
12.1M
        case '>':
1086
12.1M
            c = pdfi_read_byte(ctx, s);
1087
12.1M
            if (c < 0)
1088
619
                return (gs_error_ioerror);
1089
12.1M
            if (c == '>') {
1090
11.3M
                if (ctx->object_nesting > 0) {
1091
10.6M
                    ctx->object_nesting--;
1092
10.6M
                    code = pdfi_dict_from_stack(ctx, indirect_num, indirect_gen, false);
1093
10.6M
                    if (code < 0)
1094
368k
                        return code;
1095
10.6M
                } else {
1096
685k
                    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
685k
                    goto rescan;
1100
685k
                }
1101
10.3M
                return 1;
1102
11.3M
            } else {
1103
839k
                pdfi_unread_byte(ctx, s, (byte)c);
1104
839k
                return_error(gs_error_syntaxerror);
1105
839k
            }
1106
0
            break;
1107
15.5M
        case '(':
1108
15.5M
            code = pdfi_read_string(ctx, s, indirect_num, indirect_gen);
1109
15.5M
            if (code < 0)
1110
0
                return code;
1111
15.5M
            return 1;
1112
0
            break;
1113
14.2M
        case '[':
1114
14.2M
            if (ctx->args.pdfdebug)
1115
0
                outprintf (ctx->memory, "[");
1116
14.2M
            if (ctx->object_nesting < MAX_NESTING_DEPTH) {
1117
12.8M
                ctx->object_nesting++;
1118
12.8M
                code = pdfi_mark_stack(ctx, PDF_ARRAY_MARK);
1119
12.8M
                if (code < 0)
1120
0
                    return code;
1121
12.8M
            } else
1122
1.34M
                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
14.2M
            return 1;
1125
0
            break;
1126
13.0M
        case ']':
1127
13.0M
            if (ctx->object_nesting > 0) {
1128
12.7M
                ctx->object_nesting--;
1129
12.7M
                code = pdfi_array_from_stack(ctx, indirect_num, indirect_gen);
1130
12.7M
                if (code < 0)
1131
229k
                    return code;
1132
12.7M
            } else {
1133
302k
                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
302k
                goto rescan;
1137
302k
            }
1138
12.5M
            break;
1139
12.5M
        case '{':
1140
327k
            if (ctx->args.pdfdebug)
1141
0
                outprintf (ctx->memory, "{");
1142
327k
            code = pdfi_mark_stack(ctx, PDF_PROC_MARK);
1143
327k
            if (code < 0)
1144
0
                return code;
1145
327k
            return 1;
1146
0
            break;
1147
295k
        case '}':
1148
295k
            pdfi_clear_to_mark(ctx);
1149
295k
            goto rescan;
1150
0
            break;
1151
1.66M
        case '%':
1152
1.66M
            pdfi_skip_comment(ctx, s);
1153
1.66M
            goto rescan;
1154
0
            break;
1155
121M
        default:
1156
121M
            if (isdelimiter(c)) {
1157
679k
                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
679k
                goto rescan;
1161
679k
            }
1162
120M
            pdfi_unread_byte(ctx, s, (byte)c);
1163
120M
            code = pdfi_read_keyword(ctx, s, indirect_num, indirect_gen);
1164
120M
            if (code < 0)
1165
86.6k
                return code;
1166
120M
            return 1;
1167
0
            break;
1168
590M
    }
1169
324M
    return 1;
1170
590M
}
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
150M
{
1179
150M
    int code;
1180
150M
    *o = NULL;
1181
1182
150M
    code = pdfi_object_alloc(ctx, PDF_NAME, size, o);
1183
150M
    if (code < 0)
1184
0
        return code;
1185
1186
150M
    memcpy(((pdf_name *)*o)->data, n, size);
1187
1188
150M
    return 0;
1189
150M
}
1190
1191
static char op_table_3[5][4] = {
1192
    "BDC", "BMC", "EMC", "SCN", "scn"
1193
};
1194
1195
static char op_table_2[39][3] = {
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][2] = {
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.31M
{
1212
2.31M
    byte Buffer[256];
1213
2.31M
    pdf_key key;
1214
2.31M
    int code;
1215
1216
2.31M
    if (length > 255)
1217
0
        return_error(gs_error_rangecheck);
1218
1219
2.31M
    memcpy(Buffer, data, length);
1220
2.31M
    Buffer[length] = 0;
1221
2.31M
    key = lookup_keyword(Buffer);
1222
2.31M
    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.31M
        *pkey = (pdf_keyword *)PDF_TOKEN_AS_OBJ(key);
1226
2.31M
        return 1;
1227
2.31M
    }
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
2.20M
{
1242
2.20M
    int i;
1243
1244
13.2M
    for (i = 0; i < 5; i++) {
1245
11.0M
        if (memcmp(str, op_table_3[i], 3) == 0)
1246
7.65k
            return make_keyword_obj(ctx, str, 3, key);
1247
11.0M
    }
1248
2.19M
    return 0;
1249
2.20M
}
1250
1251
static int search_table_2(pdf_context *ctx, unsigned char *str, pdf_keyword **key)
1252
4.72M
{
1253
4.72M
    int i;
1254
1255
183M
    for (i = 0; i < 39; i++) {
1256
178M
        if (memcmp(str, op_table_2[i], 2) == 0)
1257
276k
            return make_keyword_obj(ctx, str, 2, key);
1258
178M
    }
1259
4.44M
    return 0;
1260
4.72M
}
1261
1262
static int search_table_1(pdf_context *ctx, unsigned char *str, pdf_keyword **key)
1263
4.37M
{
1264
4.37M
    int i;
1265
1266
94.7M
    for (i = 0; i < 27; i++) {
1267
92.3M
        if (memcmp(str, op_table_1[i], 1) == 0)
1268
2.03M
            return make_keyword_obj(ctx, str, 1, key);
1269
92.3M
    }
1270
2.34M
    return 0;
1271
4.37M
}
1272
1273
static int split_bogus_operator(pdf_context *ctx, pdf_c_stream *source, pdf_dict *stream_dict, pdf_dict *page_dict)
1274
8.45M
{
1275
8.45M
    int code = 0;
1276
8.45M
    pdf_keyword *keyword = (pdf_keyword *)ctx->stack_top[-1], *key1 = NULL, *key2 = NULL;
1277
8.45M
    int length = keyword->length - 6;
1278
1279
8.45M
    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.87M
        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
25
            code = make_keyword_obj(ctx, keyword->data, length, &key1);
1287
25
            if (code < 0)
1288
0
                goto error_exit;
1289
25
            pdfi_pop(ctx, 1);
1290
25
            pdfi_push(ctx, (pdf_obj *)key1);
1291
25
            pdfi_countdown(key1); /* Drop the reference returned by make_keyword_obj. */
1292
25
            code = pdfi_interpret_stream_operator(ctx, source, stream_dict, page_dict);
1293
25
            if (code < 0)
1294
15
                goto error_exit;
1295
10
            pdfi_push(ctx, PDF_TOKEN_AS_OBJ(TOKEN_ENDOBJ));
1296
10
            return 0;
1297
2.87M
        } else {
1298
2.87M
            length = keyword->length - 9;
1299
2.87M
            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
3
                code = make_keyword_obj(ctx, keyword->data, length, &key1);
1303
3
                if (code < 0)
1304
0
                    goto error_exit;
1305
3
                pdfi_pop(ctx, 1);
1306
3
                pdfi_push(ctx, (pdf_obj *)key1);
1307
3
                pdfi_countdown(key1); /* Drop the reference returned by make_keyword_obj. */
1308
3
                code = pdfi_interpret_stream_operator(ctx, source, stream_dict, page_dict);
1309
3
                if (code < 0)
1310
0
                    goto error_exit;
1311
3
                pdfi_push(ctx, PDF_TOKEN_AS_OBJ(TOKEN_ENDSTREAM));
1312
3
                return 0;
1313
2.87M
            } else {
1314
2.87M
                pdfi_clearstack(ctx);
1315
2.87M
                return 0;
1316
2.87M
            }
1317
2.87M
        }
1318
2.87M
    }
1319
1320
5.58M
    if (keyword->length > 3) {
1321
1.74M
        code = search_table_3(ctx, keyword->data, &key1);
1322
1.74M
        if (code < 0)
1323
0
            goto error_exit;
1324
1325
1.74M
        if (code > 0) {
1326
6.42k
            switch (keyword->length - 3) {
1327
4.95k
                case 1:
1328
4.95k
                    code = search_table_1(ctx, &keyword->data[3], &key2);
1329
4.95k
                    break;
1330
798
                case 2:
1331
798
                    code = search_table_2(ctx, &keyword->data[3], &key2);
1332
798
                    break;
1333
679
                case 3:
1334
679
                    code = search_table_3(ctx, &keyword->data[3], &key2);
1335
679
                    break;
1336
0
                default:
1337
0
                    goto error_exit;
1338
6.42k
            }
1339
6.42k
        }
1340
1.74M
        if (code < 0)
1341
0
            goto error_exit;
1342
1.74M
        if (code > 0)
1343
1.25k
            goto match;
1344
1.74M
    }
1345
5.58M
    pdfi_countdown(key1);
1346
5.58M
    pdfi_countdown(key2);
1347
5.58M
    key1 = NULL;
1348
5.58M
    key2 = NULL;
1349
1350
5.58M
    if (keyword->length > 5 || keyword->length < 2)
1351
1.44M
        goto error_exit;
1352
1353
4.13M
    code = search_table_2(ctx, keyword->data, &key1);
1354
4.13M
    if (code < 0)
1355
0
        goto error_exit;
1356
1357
4.13M
    if (code > 0) {
1358
237k
        switch(keyword->length - 2) {
1359
88.2k
            case 1:
1360
88.2k
                code = search_table_1(ctx, &keyword->data[2], &key2);
1361
88.2k
                break;
1362
90.2k
            case 2:
1363
90.2k
                code = search_table_2(ctx, &keyword->data[2], &key2);
1364
90.2k
                break;
1365
59.0k
            case 3:
1366
59.0k
                code = search_table_3(ctx, &keyword->data[2], &key2);
1367
59.0k
                break;
1368
0
            default:
1369
0
                goto error_exit;
1370
237k
        }
1371
237k
        if (code < 0)
1372
0
            goto error_exit;
1373
237k
        if (code > 0)
1374
42.8k
            goto match;
1375
237k
    }
1376
4.09M
    pdfi_countdown(key1);
1377
4.09M
    pdfi_countdown(key2);
1378
4.09M
    key1 = NULL;
1379
4.09M
    key2 = NULL;
1380
1381
4.09M
    if (keyword->length > 4)
1382
641k
        goto error_exit;
1383
1384
3.45M
    code = search_table_1(ctx, keyword->data, &key1);
1385
3.45M
    if (code <= 0)
1386
1.72M
        goto error_exit;
1387
1388
1.73M
    switch(keyword->length - 1) {
1389
833k
        case 1:
1390
833k
            code = search_table_1(ctx, &keyword->data[1], &key2);
1391
833k
            break;
1392
498k
        case 2:
1393
498k
            code = search_table_2(ctx, &keyword->data[1], &key2);
1394
498k
            break;
1395
399k
        case 3:
1396
399k
            code = search_table_3(ctx, &keyword->data[1], &key2);
1397
399k
            break;
1398
0
        default:
1399
0
            goto error_exit;
1400
1.73M
    }
1401
1.73M
    if (code <= 0)
1402
1.43M
        goto error_exit;
1403
1404
340k
match:
1405
340k
    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
340k
    pdfi_push(ctx, (pdf_obj *)key1);
1410
340k
    code = pdfi_interpret_stream_operator(ctx, source, stream_dict, page_dict);
1411
340k
    if (code < 0)
1412
256k
        goto error_exit;
1413
1414
84.2k
    pdfi_push(ctx, (pdf_obj *)key2);
1415
84.2k
    code = pdfi_interpret_stream_operator(ctx, source, stream_dict, page_dict);
1416
1417
84.2k
    pdfi_countdown(key1);
1418
84.2k
    pdfi_countdown(key2);
1419
84.2k
    pdfi_clearstack(ctx);
1420
84.2k
    return code;
1421
1422
5.50M
error_exit:
1423
5.50M
    pdfi_set_error(ctx, code, NULL, E_PDF_TOKENERROR, "split_bogus_operator", NULL);
1424
5.50M
    pdfi_countdown(key1);
1425
5.50M
    pdfi_countdown(key2);
1426
5.50M
    pdfi_clearstack(ctx);
1427
5.50M
    return code;
1428
340k
}
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
80.0M
{
1433
80.0M
    pdf_obj *keyword = ctx->stack_top[-1];
1434
80.0M
    int code = 0;
1435
1436
80.0M
    if (keyword < PDF_TOKEN_AS_OBJ(TOKEN__LAST_KEY))
1437
71.5M
    {
1438
71.5M
        switch((uintptr_t)keyword) {
1439
18.0k
            case TOKEN_b:           /* closepath, fill, stroke */
1440
18.0k
                pdfi_pop(ctx, 1);
1441
18.0k
                code = pdfi_b(ctx);
1442
18.0k
                break;
1443
44.5k
            case TOKEN_B:           /* fill, stroke */
1444
44.5k
                pdfi_pop(ctx, 1);
1445
44.5k
                code = pdfi_B(ctx);
1446
44.5k
                break;
1447
489
            case TOKEN_bstar:       /* closepath, eofill, stroke */
1448
489
                pdfi_pop(ctx, 1);
1449
489
                code = pdfi_b_star(ctx);
1450
489
                break;
1451
1.88k
            case TOKEN_Bstar:       /* eofill, stroke */
1452
1.88k
                pdfi_pop(ctx, 1);
1453
1.88k
                code = pdfi_B_star(ctx);
1454
1.88k
                break;
1455
223k
            case TOKEN_BI:       /* begin inline image */
1456
223k
                pdfi_pop(ctx, 1);
1457
223k
                code = pdfi_BI(ctx);
1458
223k
                break;
1459
336k
            case TOKEN_BDC:   /* begin marked content sequence with property list */
1460
336k
                pdfi_pop(ctx, 1);
1461
336k
                code = pdfi_op_BDC(ctx, stream_dict, page_dict);
1462
336k
                break;
1463
18.3k
            case TOKEN_BMC:   /* begin marked content sequence */
1464
18.3k
                pdfi_pop(ctx, 1);
1465
18.3k
                code = pdfi_op_BMC(ctx);
1466
18.3k
                break;
1467
1.84M
            case TOKEN_BT:       /* begin text */
1468
1.84M
                pdfi_pop(ctx, 1);
1469
1.84M
                code = pdfi_BT(ctx);
1470
1.84M
                break;
1471
49.5k
            case TOKEN_BX:       /* begin compatibility section */
1472
49.5k
                pdfi_pop(ctx, 1);
1473
49.5k
                break;
1474
10.4M
            case TOKEN_c:           /* curveto */
1475
10.4M
                pdfi_pop(ctx, 1);
1476
10.4M
                code = pdfi_curveto(ctx);
1477
10.4M
                break;
1478
2.46M
            case TOKEN_cm:       /* concat */
1479
2.46M
                pdfi_pop(ctx, 1);
1480
2.46M
                code = pdfi_concat(ctx);
1481
2.46M
                break;
1482
30.0k
            case TOKEN_CS:       /* set stroke colour space */
1483
30.0k
                pdfi_pop(ctx, 1);
1484
30.0k
                code = pdfi_setstrokecolor_space(ctx, stream_dict, page_dict);
1485
30.0k
                break;
1486
235k
            case TOKEN_cs:       /* set non-stroke colour space */
1487
235k
                pdfi_pop(ctx, 1);
1488
235k
                code = pdfi_setfillcolor_space(ctx, stream_dict, page_dict);
1489
235k
                break;
1490
797k
            case TOKEN_d:           /* set dash params */
1491
797k
                pdfi_pop(ctx, 1);
1492
797k
                code = pdfi_setdash(ctx);
1493
797k
                break;
1494
3.65k
            case TOKEN_d0:       /* set type 3 font glyph width */
1495
3.65k
                pdfi_pop(ctx, 1);
1496
3.65k
                code = pdfi_d0(ctx);
1497
3.65k
                break;
1498
38.7k
            case TOKEN_d1:       /* set type 3 font glyph width and bounding box */
1499
38.7k
                pdfi_pop(ctx, 1);
1500
38.7k
                code = pdfi_d1(ctx);
1501
38.7k
                break;
1502
271k
            case TOKEN_Do:       /* invoke named XObject */
1503
271k
                pdfi_pop(ctx, 1);
1504
271k
                code = pdfi_Do(ctx, stream_dict, page_dict);
1505
271k
                break;
1506
815
            case TOKEN_DP:       /* define marked content point with property list */
1507
815
                pdfi_pop(ctx, 1);
1508
815
                code = pdfi_op_DP(ctx, stream_dict, page_dict);
1509
815
                break;
1510
219k
            case TOKEN_EI:       /* end inline image */
1511
219k
                pdfi_pop(ctx, 1);
1512
219k
                code = pdfi_EI(ctx);
1513
219k
                break;
1514
1.81M
            case TOKEN_ET:       /* end text */
1515
1.81M
                pdfi_pop(ctx, 1);
1516
1.81M
                code = pdfi_ET(ctx);
1517
1.81M
                break;
1518
348k
            case TOKEN_EMC:   /* end marked content sequence */
1519
348k
                pdfi_pop(ctx, 1);
1520
348k
                code = pdfi_op_EMC(ctx);
1521
348k
                break;
1522
47.0k
            case TOKEN_EX:       /* end compatibility section */
1523
47.0k
                pdfi_pop(ctx, 1);
1524
47.0k
                break;
1525
2.28M
            case TOKEN_f:           /* fill */
1526
2.28M
                pdfi_pop(ctx, 1);
1527
2.28M
                code = pdfi_fill(ctx);
1528
2.28M
                break;
1529
17.0k
            case TOKEN_F:           /* fill (obselete operator) */
1530
17.0k
                pdfi_pop(ctx, 1);
1531
17.0k
                code = pdfi_fill(ctx);
1532
17.0k
                break;
1533
53.1k
            case TOKEN_fstar:       /* eofill */
1534
53.1k
                pdfi_pop(ctx, 1);
1535
53.1k
                code = pdfi_eofill(ctx);
1536
53.1k
                break;
1537
508k
            case TOKEN_G:           /* setgray for stroke */
1538
508k
                pdfi_pop(ctx, 1);
1539
508k
                code = pdfi_setgraystroke(ctx);
1540
508k
                break;
1541
616k
            case TOKEN_g:           /* setgray for non-stroke */
1542
616k
                pdfi_pop(ctx, 1);
1543
616k
                code = pdfi_setgrayfill(ctx);
1544
616k
                break;
1545
358k
            case TOKEN_gs:       /* set graphics state from dictionary */
1546
358k
                pdfi_pop(ctx, 1);
1547
358k
                code = pdfi_setgstate(ctx, stream_dict, page_dict);
1548
358k
                break;
1549
471k
            case TOKEN_h:           /* closepath */
1550
471k
                pdfi_pop(ctx, 1);
1551
471k
                code = pdfi_closepath(ctx);
1552
471k
                break;
1553
165k
            case TOKEN_i:           /* setflat */
1554
165k
                pdfi_pop(ctx, 1);
1555
165k
                code = pdfi_setflat(ctx);
1556
165k
                break;
1557
223k
            case TOKEN_ID:       /* begin inline image data */
1558
223k
                pdfi_pop(ctx, 1);
1559
223k
                code = pdfi_ID(ctx, stream_dict, page_dict, source);
1560
223k
                break;
1561
786k
            case TOKEN_j:           /* setlinejoin */
1562
786k
                pdfi_pop(ctx, 1);
1563
786k
                code = pdfi_setlinejoin(ctx);
1564
786k
                break;
1565
919k
            case TOKEN_J:           /* setlinecap */
1566
919k
                pdfi_pop(ctx, 1);
1567
919k
                code = pdfi_setlinecap(ctx);
1568
919k
                break;
1569
47.3k
            case TOKEN_K:           /* setcmyk for non-stroke */
1570
47.3k
                pdfi_pop(ctx, 1);
1571
47.3k
                code = pdfi_setcmykstroke(ctx);
1572
47.3k
                break;
1573
147k
            case TOKEN_k:           /* setcmyk for non-stroke */
1574
147k
                pdfi_pop(ctx, 1);
1575
147k
                code = pdfi_setcmykfill(ctx);
1576
147k
                break;
1577
11.4M
            case TOKEN_l:           /* lineto */
1578
11.4M
                pdfi_pop(ctx, 1);
1579
11.4M
                code = pdfi_lineto(ctx);
1580
11.4M
                break;
1581
6.02M
            case TOKEN_m:           /* moveto */
1582
6.02M
                pdfi_pop(ctx, 1);
1583
6.02M
                code = pdfi_moveto(ctx);
1584
6.02M
                break;
1585
43.7k
            case TOKEN_M:           /* setmiterlimit */
1586
43.7k
                pdfi_pop(ctx, 1);
1587
43.7k
                code = pdfi_setmiterlimit(ctx);
1588
43.7k
                break;
1589
2.53k
            case TOKEN_MP:       /* define marked content point */
1590
2.53k
                pdfi_pop(ctx, 1);
1591
2.53k
                code = pdfi_op_MP(ctx);
1592
2.53k
                break;
1593
1.18M
            case TOKEN_n:           /* newpath */
1594
1.18M
                pdfi_pop(ctx, 1);
1595
1.18M
                code = pdfi_newpath(ctx);
1596
1.18M
                break;
1597
2.95M
            case TOKEN_q:           /* gsave */
1598
2.95M
                pdfi_pop(ctx, 1);
1599
2.95M
                code = pdfi_op_q(ctx);
1600
2.95M
                break;
1601
2.87M
            case TOKEN_Q:           /* grestore */
1602
2.87M
                pdfi_pop(ctx, 1);
1603
2.87M
                code = pdfi_op_Q(ctx);
1604
2.87M
                break;
1605
53.2k
            case TOKEN_r:       /* non-standard set rgb colour for non-stroke */
1606
53.2k
                pdfi_pop(ctx, 1);
1607
53.2k
                code = pdfi_setrgbfill_array(ctx);
1608
53.2k
                break;
1609
2.70M
            case TOKEN_re:       /* append rectangle */
1610
2.70M
                pdfi_pop(ctx, 1);
1611
2.70M
                code = pdfi_rectpath(ctx);
1612
2.70M
                break;
1613
860k
            case TOKEN_RG:       /* set rgb colour for stroke */
1614
860k
                pdfi_pop(ctx, 1);
1615
860k
                code = pdfi_setrgbstroke(ctx);
1616
860k
                break;
1617
934k
            case TOKEN_rg:       /* set rgb colour for non-stroke */
1618
934k
                pdfi_pop(ctx, 1);
1619
934k
                code = pdfi_setrgbfill(ctx);
1620
934k
                break;
1621
92.1k
            case TOKEN_ri:       /* set rendering intent */
1622
92.1k
                pdfi_pop(ctx, 1);
1623
92.1k
                code = pdfi_ri(ctx);
1624
92.1k
                break;
1625
80.5k
            case TOKEN_s:           /* closepath, stroke */
1626
80.5k
                pdfi_pop(ctx, 1);
1627
80.5k
                code = pdfi_closepath_stroke(ctx);
1628
80.5k
                break;
1629
2.78M
            case TOKEN_S:           /* stroke */
1630
2.78M
                pdfi_pop(ctx, 1);
1631
2.78M
                code = pdfi_stroke(ctx);
1632
2.78M
                break;
1633
37.2k
            case TOKEN_SC:       /* set colour for stroke */
1634
37.2k
                pdfi_pop(ctx, 1);
1635
37.2k
                code = pdfi_setstrokecolor(ctx);
1636
37.2k
                break;
1637
156k
            case TOKEN_sc:       /* set colour for non-stroke */
1638
156k
                pdfi_pop(ctx, 1);
1639
156k
                code = pdfi_setfillcolor(ctx);
1640
156k
                break;
1641
13.2k
            case TOKEN_SCN:   /* set special colour for stroke */
1642
13.2k
                pdfi_pop(ctx, 1);
1643
13.2k
                code = pdfi_setcolorN(ctx, stream_dict, page_dict, false);
1644
13.2k
                break;
1645
124k
            case TOKEN_scn:   /* set special colour for non-stroke */
1646
124k
                pdfi_pop(ctx, 1);
1647
124k
                code = pdfi_setcolorN(ctx, stream_dict, page_dict, true);
1648
124k
                break;
1649
63.5k
            case TOKEN_sh:       /* fill with sahding pattern */
1650
63.5k
                pdfi_pop(ctx, 1);
1651
63.5k
                code = pdfi_shading(ctx, stream_dict, page_dict);
1652
63.5k
                break;
1653
142k
            case TOKEN_Tstar:       /* Move to start of next text line */
1654
142k
                pdfi_pop(ctx, 1);
1655
142k
                code = pdfi_T_star(ctx);
1656
142k
                break;
1657
745k
            case TOKEN_Tc:       /* set character spacing */
1658
745k
                pdfi_pop(ctx, 1);
1659
745k
                code = pdfi_Tc(ctx);
1660
745k
                break;
1661
1.28M
            case TOKEN_Td:       /* move text position */
1662
1.28M
                pdfi_pop(ctx, 1);
1663
1.28M
                code = pdfi_Td(ctx);
1664
1.28M
                break;
1665
404k
            case TOKEN_TD:       /* Move text position, set leading */
1666
404k
                pdfi_pop(ctx, 1);
1667
404k
                code = pdfi_TD(ctx);
1668
404k
                break;
1669
1.22M
            case TOKEN_Tf:       /* set font and size */
1670
1.22M
                pdfi_pop(ctx, 1);
1671
1.22M
                code = pdfi_Tf(ctx, stream_dict, page_dict);
1672
1.22M
                break;
1673
1.67M
            case TOKEN_Tj:       /* show text */
1674
1.67M
                pdfi_pop(ctx, 1);
1675
1.67M
                code = pdfi_Tj(ctx);
1676
1.67M
                break;
1677
1.90M
            case TOKEN_TJ:       /* show text with individual glyph positioning */
1678
1.90M
                pdfi_pop(ctx, 1);
1679
1.90M
                code = pdfi_TJ(ctx);
1680
1.90M
                break;
1681
12.5k
            case TOKEN_TL:       /* set text leading */
1682
12.5k
                pdfi_pop(ctx, 1);
1683
12.5k
                code = pdfi_TL(ctx);
1684
12.5k
                break;
1685
1.77M
            case TOKEN_Tm:       /* set text matrix */
1686
1.77M
                pdfi_pop(ctx, 1);
1687
1.77M
                code = pdfi_Tm(ctx);
1688
1.77M
                break;
1689
621k
            case TOKEN_Tr:       /* set text rendering mode */
1690
621k
                pdfi_pop(ctx, 1);
1691
621k
                code = pdfi_Tr(ctx);
1692
621k
                break;
1693
4.09k
            case TOKEN_Ts:       /* set text rise */
1694
4.09k
                pdfi_pop(ctx, 1);
1695
4.09k
                code = pdfi_Ts(ctx);
1696
4.09k
                break;
1697
156k
            case TOKEN_Tw:       /* set word spacing */
1698
156k
                pdfi_pop(ctx, 1);
1699
156k
                code = pdfi_Tw(ctx);
1700
156k
                break;
1701
97.7k
            case TOKEN_Tz:       /* set text matrix */
1702
97.7k
                pdfi_pop(ctx, 1);
1703
97.7k
                code = pdfi_Tz(ctx);
1704
97.7k
                break;
1705
158k
            case TOKEN_v:           /* append curve (initial point replicated) */
1706
158k
                pdfi_pop(ctx, 1);
1707
158k
                code = pdfi_v_curveto(ctx);
1708
158k
                break;
1709
2.15M
            case TOKEN_w:           /* setlinewidth */
1710
2.15M
                pdfi_pop(ctx, 1);
1711
2.15M
                code = pdfi_setlinewidth(ctx);
1712
2.15M
                break;
1713
608k
            case TOKEN_W:           /* clip */
1714
608k
                pdfi_pop(ctx, 1);
1715
608k
                ctx->clip_active = true;
1716
608k
                ctx->do_eoclip = false;
1717
608k
                break;
1718
56.5k
            case TOKEN_Wstar:       /* eoclip */
1719
56.5k
                pdfi_pop(ctx, 1);
1720
56.5k
                ctx->clip_active = true;
1721
56.5k
                ctx->do_eoclip = true;
1722
56.5k
                break;
1723
177k
            case TOKEN_y:           /* append curve (final point replicated) */
1724
177k
                pdfi_pop(ctx, 1);
1725
177k
                code = pdfi_y_curveto(ctx);
1726
177k
                break;
1727
18.4k
            case TOKEN_APOSTROPHE:          /* move to next line and show text */
1728
18.4k
                pdfi_pop(ctx, 1);
1729
18.4k
                code = pdfi_singlequote(ctx);
1730
18.4k
                break;
1731
6.51k
            case TOKEN_QUOTE:           /* set word and character spacing, move to next line, show text */
1732
6.51k
                pdfi_pop(ctx, 1);
1733
6.51k
                code = pdfi_doublequote(ctx);
1734
6.51k
                break;
1735
3.94k
            default:
1736
                /* Shouldn't we return an error here? Original code didn't seem to. */
1737
3.94k
                break;
1738
71.5M
        }
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
71.5M
        if (code > 0)
1744
0
            code = 0;
1745
71.5M
        return code;
1746
71.5M
    } 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
8.45M
        code = split_bogus_operator(ctx, source, stream_dict, page_dict);
1753
8.45M
        if (code < 0)
1754
311k
            return code;
1755
8.14M
        if (pdfi_count_stack(ctx) > 0) {
1756
13
            keyword = ctx->stack_top[-1];
1757
13
            if (keyword != PDF_TOKEN_AS_OBJ(TOKEN_NOT_A_KEYWORD))
1758
13
                return REPAIRED_KEYWORD;
1759
13
        }
1760
8.14M
    }
1761
8.14M
    return 0;
1762
80.0M
}
1763
1764
void local_save_stream_state(pdf_context *ctx, stream_save *local_save)
1765
639k
{
1766
    /* copy the 'save_stream' data from the context to a local structure */
1767
639k
    local_save->stream_offset = ctx->current_stream_save.stream_offset;
1768
639k
    local_save->gsave_level = ctx->current_stream_save.gsave_level;
1769
639k
    local_save->stack_count = ctx->current_stream_save.stack_count;
1770
639k
    local_save->group_depth = ctx->current_stream_save.group_depth;
1771
639k
}
1772
1773
void cleanup_context_interpretation(pdf_context *ctx, stream_save *local_save)
1774
639k
{
1775
639k
    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
639k
    if (ctx->current_stream_save.group_depth != local_save->group_depth) {
1780
12
        pdfi_set_warning(ctx, 0, NULL, W_PDF_GROUPERROR, "pdfi_cleanup_context_interpretation", NULL);
1781
24
        while (ctx->current_stream_save.group_depth > local_save->group_depth)
1782
12
            pdfi_trans_end_group(ctx);
1783
12
    }
1784
639k
    if (ctx->pgs->level > ctx->current_stream_save.gsave_level)
1785
21.6k
        pdfi_set_warning(ctx, 0, NULL, W_PDF_TOOMANYq, "pdfi_cleanup_context_interpretation", NULL);
1786
639k
    if (pdfi_count_stack(ctx) > ctx->current_stream_save.stack_count)
1787
7.71k
        pdfi_set_warning(ctx, 0, NULL, W_PDF_STACKGARBAGE, "pdfi_cleanup_context_interpretation", NULL);
1788
845k
    while (ctx->pgs->level > ctx->current_stream_save.gsave_level)
1789
206k
        pdfi_grestore(ctx);
1790
639k
    pdfi_clearstack(ctx);
1791
639k
}
1792
1793
void local_restore_stream_state(pdf_context *ctx, stream_save *local_save)
1794
639k
{
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
639k
    ctx->current_stream_save.stream_offset = local_save->stream_offset;
1800
639k
    ctx->current_stream_save.gsave_level = local_save->gsave_level;
1801
639k
    ctx->current_stream_save.stack_count = local_save->stack_count;
1802
639k
    ctx->current_stream_save.group_depth = local_save->group_depth;
1803
639k
}
1804
1805
void initialise_stream_save(pdf_context *ctx)
1806
639k
{
1807
    /* Set up the values in the context to the current values */
1808
639k
    ctx->current_stream_save.stream_offset = pdfi_tell(ctx->main_stream);
1809
639k
    ctx->current_stream_save.gsave_level = ctx->pgs->level;
1810
639k
    ctx->current_stream_save.stack_count = pdfi_count_total_stack(ctx);
1811
639k
}
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
306k
{
1817
306k
    int code = 0, code1 = 0;
1818
306k
    gs_gstate *DefaultQState = NULL;
1819
    /* Save any existing Default* colour spaces */
1820
306k
    gs_color_space *PageDefaultGray = ctx->page.DefaultGray_cs;
1821
306k
    gs_color_space *PageDefaultRGB = ctx->page.DefaultRGB_cs;
1822
306k
    gs_color_space *PageDefaultCMYK = ctx->page.DefaultCMYK_cs;
1823
1824
306k
    ctx->page.DefaultGray_cs = NULL;
1825
306k
    ctx->page.DefaultRGB_cs = NULL;
1826
306k
    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
306k
    code = pdfi_setup_DefaultSpaces(ctx, stream_obj->stream_dict);
1835
306k
    if (code < 0)
1836
0
        goto exit;
1837
1838
    /* If no Default* space found, try using the Page level ones (if any) */
1839
306k
    if (ctx->page.DefaultGray_cs == NULL) {
1840
306k
        ctx->page.DefaultGray_cs = PageDefaultGray;
1841
306k
        rc_increment(PageDefaultGray);
1842
306k
    }
1843
306k
    if (ctx->page.DefaultRGB_cs == NULL) {
1844
306k
        ctx->page.DefaultRGB_cs = PageDefaultRGB;
1845
306k
        rc_increment(PageDefaultRGB);
1846
306k
    }
1847
306k
    if (ctx->page.DefaultCMYK_cs == NULL) {
1848
306k
        ctx->page.DefaultCMYK_cs = PageDefaultCMYK;
1849
306k
        rc_increment(PageDefaultCMYK);
1850
306k
    }
1851
1852
306k
    code = pdfi_copy_DefaultQState(ctx, &DefaultQState);
1853
306k
    if (code < 0)
1854
0
        goto exit;
1855
1856
306k
    code = pdfi_set_DefaultQState(ctx, ctx->pgs);
1857
306k
    if (code < 0)
1858
0
        goto exit;
1859
1860
306k
    code = pdfi_interpret_inner_content_stream(ctx, stream_obj, page_dict, stoponerror, desc);
1861
1862
306k
    code1 = pdfi_restore_DefaultQState(ctx, &DefaultQState);
1863
306k
    if (code >= 0)
1864
306k
        code = code1;
1865
1866
306k
exit:
1867
306k
    if (DefaultQState != NULL) {
1868
0
        gs_gstate_free(DefaultQState);
1869
0
        DefaultQState = NULL;
1870
0
    }
1871
1872
    /* Count down any Default* colour spaces */
1873
306k
    rc_decrement(ctx->page.DefaultGray_cs, "pdfi_run_context");
1874
306k
    rc_decrement(ctx->page.DefaultRGB_cs, "pdfi_run_context");
1875
306k
    rc_decrement(ctx->page.DefaultCMYK_cs, "pdfi_run_context");
1876
1877
    /* And restore the page level ones (if any) */
1878
306k
    ctx->page.DefaultGray_cs = PageDefaultGray;
1879
306k
    ctx->page.DefaultRGB_cs = PageDefaultRGB;
1880
306k
    ctx->page.DefaultCMYK_cs = PageDefaultCMYK;
1881
1882
#if DEBUG_CONTEXT
1883
    dbgmprintf(ctx->memory, "pdfi_run_context END\n");
1884
#endif
1885
306k
    return code;
1886
306k
}
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
340k
{
1897
340k
    int code = 0;
1898
340k
    bool saved_stoponerror = ctx->args.pdfstoponerror;
1899
340k
    stream_save local_entry_save;
1900
1901
340k
    local_save_stream_state(ctx, &local_entry_save);
1902
340k
    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
340k
    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
340k
    if (code < 0)
1930
340k
        dbgmprintf1(ctx->memory, "ERROR: inner_stream: code %d when rendering stream\n", code);
1931
1932
340k
    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
340k
    cleanup_context_interpretation(ctx, &local_entry_save);
1942
340k
    local_restore_stream_state(ctx, &local_entry_save);
1943
340k
    if (code < 0)
1944
7.29k
        code = pdfi_set_error_stop(ctx, code, NULL, 0, "pdfi_interpret_inner_content", NULL);
1945
340k
    return code;
1946
340k
}
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
34.0k
{
1956
34.0k
    int code = 0;
1957
34.0k
    pdf_c_stream *stream = NULL;
1958
34.0k
    pdf_stream *stream_obj = NULL;
1959
1960
34.0k
    if (content_length == 0)
1961
0
        return 0;
1962
1963
34.0k
    code = pdfi_open_memory_stream_from_memory(ctx, content_length,
1964
34.0k
                                               content_data, &stream, true);
1965
34.0k
    if (code < 0)
1966
0
        goto exit;
1967
1968
34.0k
    code = pdfi_obj_dict_to_stream(ctx, stream_dict, &stream_obj, false);
1969
34.0k
    if (code < 0)
1970
0
        return code;
1971
1972
    /* NOTE: stream gets closed in here */
1973
34.0k
    code = pdfi_interpret_inner_content(ctx, stream, stream_obj, page_dict, stoponerror, desc);
1974
34.0k
    pdfi_countdown(stream_obj);
1975
34.0k
 exit:
1976
34.0k
    return code;
1977
34.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.9k
{
1986
17.9k
    uint32_t length = (uint32_t)strlen(content_string);
1987
17.9k
    bool decrypt_strings;
1988
17.9k
    int code;
1989
1990
17.9k
    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.9k
    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.9k
    decrypt_strings = ctx->encryption.decrypt_strings;
2003
17.9k
    ctx->encryption.decrypt_strings = false;
2004
17.9k
    code = pdfi_interpret_inner_content_buffer(ctx, (byte *)content_string, length,
2005
17.9k
                                               stream_dict, page_dict, stoponerror, desc);
2006
17.9k
    ctx->encryption.decrypt_strings = decrypt_strings;
2007
2008
17.9k
    return code;
2009
17.9k
}
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
16.0k
{
2018
16.0k
    return pdfi_interpret_inner_content_buffer(ctx, content_string->data, content_string->length,
2019
16.0k
                                               stream_dict, page_dict, stoponerror, desc);
2020
16.0k
}
2021
2022
/* Interpret inner content from a stream_dict
2023
 */
2024
int
2025
pdfi_interpret_inner_content_stream(pdf_context *ctx, pdf_stream *stream_obj,
2026
                                    pdf_dict *page_dict, bool stoponerror, const char *desc)
2027
306k
{
2028
306k
    return pdfi_interpret_inner_content(ctx, NULL, stream_obj, page_dict, stoponerror, desc);
2029
306k
}
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
491k
{
2040
491k
    int code;
2041
491k
    pdf_c_stream *stream = NULL, *SubFile_stream = NULL;
2042
491k
    pdf_keyword *keyword;
2043
491k
    pdf_stream *s = ctx->current_stream;
2044
491k
    pdf_obj_type type;
2045
491k
    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
681k
    while (s != NULL && pdfi_type_of(s) == PDF_STREAM) {
2055
190k
        if (s->object_num > 0) {
2056
189k
            if (s->object_num == stream_obj->object_num) {
2057
279
                pdf_dict *d = NULL;
2058
279
                bool known = false;
2059
2060
279
                code = pdfi_dict_from_obj(ctx, (pdf_obj *)stream_obj, &d);
2061
279
                if (code >= 0) {
2062
279
                    code = pdfi_dict_known(ctx, d, "Parent", &known);
2063
279
                    if (code >= 0 && known)
2064
64
                        (void)pdfi_dict_delete(ctx, d, "Parent");
2065
279
                }
2066
279
                pdfi_set_error(ctx, 0, NULL, E_PDF_CIRCULARREF, "pdfi_interpret_content_stream", "Aborting stream");
2067
279
                return_error(gs_error_circular_reference);
2068
279
            }
2069
189k
        }
2070
189k
        s = (pdf_stream *)s->parent_obj;
2071
189k
    }
2072
2073
491k
    if (content_stream != NULL) {
2074
76.7k
        stream = content_stream;
2075
414k
    } else {
2076
414k
        code = pdfi_seek(ctx, ctx->main_stream, pdfi_stream_offset(ctx, stream_obj), SEEK_SET);
2077
414k
        if (code < 0)
2078
0
            return code;
2079
2080
414k
        if (stream_obj->length_valid) {
2081
407k
            if (stream_obj->Length == 0)
2082
2.62k
                return 0;
2083
405k
            code = pdfi_apply_SubFileDecode_filter(ctx, stream_obj->Length, NULL, ctx->main_stream, &SubFile_stream, false);
2084
405k
        }
2085
7.02k
        else
2086
7.02k
            code = pdfi_apply_SubFileDecode_filter(ctx, 0, EODString, ctx->main_stream, &SubFile_stream, false);
2087
412k
        if (code < 0)
2088
0
            return code;
2089
2090
412k
        code = pdfi_filter(ctx, stream_obj, SubFile_stream, &stream, false);
2091
412k
        if (code < 0) {
2092
605
            pdfi_close_file(ctx, SubFile_stream);
2093
605
            return code;
2094
605
        }
2095
412k
    }
2096
2097
488k
    pdfi_set_stream_parent(ctx, stream_obj, ctx->current_stream);
2098
488k
    ctx->current_stream = stream_obj;
2099
2100
290M
    do {
2101
290M
        code = pdfi_read_token(ctx, stream, stream_obj->object_num, stream_obj->generation_num);
2102
290M
        if (code < 0) {
2103
770k
            if (code == gs_error_ioerror || code == gs_error_VMerror || ctx->args.pdfstoponerror) {
2104
14.9k
                if (code == gs_error_ioerror) {
2105
14.9k
                    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.9k
                } 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.9k
                goto exit;
2110
14.9k
            }
2111
755k
            continue;
2112
770k
        }
2113
2114
289M
        if (pdfi_count_stack(ctx) <= 0) {
2115
256k
            if(stream->eof == true)
2116
231k
                break;
2117
256k
        }
2118
2119
289M
repaired_keyword:
2120
289M
        type = pdfi_type_of(ctx->stack_top[-1]);
2121
289M
        if (type == PDF_FAST_KEYWORD) {
2122
71.1M
            keyword = (pdf_keyword *)ctx->stack_top[-1];
2123
2124
71.1M
            switch((uintptr_t)keyword) {
2125
42.7k
                case TOKEN_ENDSTREAM:
2126
42.7k
                    pdfi_pop(ctx,1);
2127
42.7k
                    goto exit;
2128
0
                    break;
2129
160
                case TOKEN_ENDOBJ:
2130
160
                    pdfi_clearstack(ctx);
2131
160
                    code = pdfi_set_error_stop(ctx, gs_note_error(gs_error_syntaxerror), NULL, E_PDF_MISSINGENDSTREAM, "pdfi_interpret_content_stream", NULL);
2132
160
                    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
71.1M
                default:
2145
71.1M
                    goto execute;
2146
71.1M
            }
2147
71.1M
        }
2148
218M
        else if (type == PDF_KEYWORD)
2149
8.45M
        {
2150
79.5M
execute:
2151
79.5M
            {
2152
79.5M
                pdf_dict *stream_dict = NULL;
2153
2154
79.5M
                code = pdfi_dict_from_obj(ctx, (pdf_obj *)stream_obj, &stream_dict);
2155
79.5M
                if (code < 0)
2156
0
                    goto exit;
2157
2158
79.5M
                code = pdfi_interpret_stream_operator(ctx, stream, stream_dict, page_dict);
2159
79.5M
                if (code == REPAIRED_KEYWORD)
2160
13
                    goto repaired_keyword;
2161
2162
79.5M
                if (code < 0) {
2163
4.17M
                    if ((code = pdfi_set_error_stop(ctx, code, NULL, E_PDF_TOKENERROR, "pdf_interpret_content_stream", NULL)) < 0) {
2164
854
                        pdfi_clearstack(ctx);
2165
854
                        goto exit;
2166
854
                    }
2167
4.17M
                }
2168
79.5M
            }
2169
79.5M
        }
2170
289M
        if(stream->eof == true)
2171
197k
            break;
2172
289M
    }while(1);
2173
2174
488k
exit:
2175
488k
    ctx->current_stream = pdfi_stream_parent(ctx, stream_obj);
2176
488k
    pdfi_clear_stream_parent(ctx, stream_obj);
2177
488k
    pdfi_close_file(ctx, stream);
2178
488k
    if (SubFile_stream != NULL)
2179
411k
        pdfi_close_file(ctx, SubFile_stream);
2180
488k
    return code;
2181
488k
}