Coverage Report

Created: 2025-08-28 07:06

/src/ghostpdl/psi/iscan.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2001-2023 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
17
/* Token scanner for Ghostscript interpreter */
18
#include "ghost.h"
19
#include "memory_.h"
20
#include "string_.h"
21
#include "stream.h"
22
#include "ierrors.h"
23
#include "btoken.h"             /* for ref_binary_object_format */
24
#include "files.h"              /* for fptr */
25
#include "ialloc.h"
26
#include "idict.h"              /* for //name lookup */
27
#include "dstack.h"             /* ditto */
28
#include "ilevel.h"
29
#include "iname.h"
30
#include "ipacked.h"
31
#include "iparray.h"
32
#include "strimpl.h"            /* for string decoding */
33
#include "sa85d.h"              /* ditto */
34
#include "sfilter.h"            /* ditto */
35
#include "ostack.h"             /* for accumulating proc bodies; */
36
                                        /* must precede iscan.h */
37
#include "iscan.h"              /* defines interface */
38
#include "iscanbin.h"
39
#include "iscannum.h"
40
#include "istream.h"
41
#include "istruct.h"            /* for RELOC_REF_VAR */
42
#include "iutil.h"
43
#include "ivmspace.h"
44
#include "store.h"
45
#include "scanchar.h"
46
47
/*
48
 * Level 2 includes some changes in the scanner:
49
 *      - \ is always recognized in strings, regardless of the data source;
50
 *      - << and >> are legal tokens;
51
 *      - <~ introduces an ASCII85 encoded string (terminated by ~>);
52
 *      - Character codes above 127 introduce binary objects.
53
 * We explicitly enable or disable these changes based on level2_enabled.
54
 */
55
56
/* ------ Dynamic strings ------ */
57
58
/* Begin collecting a dynamically allocated string. */
59
static inline void
60
dynamic_init(da_ptr pda, gs_memory_t *mem)
61
206M
{
62
206M
    pda->is_dynamic = false;
63
206M
    pda->limit = pda->buf + sizeof(pda->buf);
64
206M
    pda->next = pda->base = pda->buf;
65
206M
    pda->memory = mem;
66
206M
}
67
68
/* Free a dynamic string. */
69
static void
70
dynamic_free(da_ptr pda)
71
1.60G
{
72
1.60G
    if (pda->is_dynamic)
73
12.3M
        gs_free_string(pda->memory, pda->base, da_size(pda), "scanner");
74
1.60G
}
75
76
/* Resize a dynamic string. */
77
/* If the allocation fails, return gs_error_VMerror; otherwise, return 0. */
78
static int
79
dynamic_resize(da_ptr pda, uint new_size)
80
220M
{
81
220M
    uint old_size = da_size(pda);
82
220M
    uint pos = pda->next - pda->base;
83
220M
    gs_memory_t *mem = pda->memory;
84
220M
    byte *base;
85
86
220M
    if (pda->is_dynamic) {
87
1.74M
        base = gs_resize_string(mem, pda->base, old_size,
88
1.74M
                                new_size, "scanner");
89
1.74M
        if (base == 0)
90
0
            return_error(gs_error_VMerror);
91
218M
    } else {                    /* switching from static to dynamic */
92
218M
        base = gs_alloc_string(mem, new_size, "scanner");
93
218M
        if (base == 0)
94
0
            return_error(gs_error_VMerror);
95
218M
        memcpy(base, pda->base, min(old_size, new_size));
96
218M
        pda->is_dynamic = true;
97
218M
    }
98
220M
    pda->base = base;
99
220M
    pda->next = base + pos;
100
220M
    pda->limit = base + new_size;
101
220M
    return 0;
102
220M
}
103
104
/* Grow a dynamic string. */
105
/* Return 0 if the allocation failed, the new 'next' ptr if OK. */
106
/* Return 0 or an error code, updating pda->next to point to the first */
107
/* available byte after growing. */
108
static int
109
dynamic_grow(da_ptr pda, byte * next, uint max_size)
110
14.0M
{
111
14.0M
    uint old_size = da_size(pda);
112
14.0M
    uint new_size = (old_size < 10 ? 20 :
113
14.0M
                     old_size >= (max_size >> 1) ? max_size :
114
3.01M
                     old_size << 1);
115
14.0M
    int code;
116
117
14.0M
    pda->next = next;
118
14.0M
    if (old_size >= max_size)
119
105
        return_error(gs_error_limitcheck);
120
14.0M
    while ((code = dynamic_resize(pda, new_size)) < 0) {
121
        /* Try trimming down the requested new size. */
122
0
        new_size -= (new_size - old_size + 1) >> 1;
123
0
        if (new_size <= old_size)
124
0
                break;
125
0
    }
126
14.0M
    return code;
127
14.0M
}
128
129
/* Ensure that a dynamic string is either on the heap or in the */
130
/* private buffer. */
131
static void
132
dynamic_save(da_ptr pda)
133
950k
{
134
950k
    if (!pda->is_dynamic && pda->base != pda->buf) {
135
38
        int len = da_size(pda);
136
137
38
        if (len > sizeof(pda->buf))
138
0
            len = sizeof(pda->buf);
139
        /* This can happen if we get a /<CR> at the end of a buffer, and the file is
140
         * not at EOF. In this case 'len' will be zero so we don't actually copy any
141
         * bytes. So this is safe on current C run-time libraries, but it's probably
142
         * best to avoid it. Coverity ID C382008
143
         */
144
38
        if (pda->base != NULL)
145
32
            memcpy(pda->buf, pda->base, len);
146
38
        pda->next = pda->buf + len;
147
38
        pda->base = pda->buf;
148
38
    }
149
950k
}
150
151
/* Finish collecting a dynamic string. */
152
static int
153
dynamic_make_string(i_ctx_t *i_ctx_p, ref * pref, da_ptr pda, byte * next)
154
205M
{
155
205M
    uint size = (pda->next = next) - pda->base;
156
205M
    int code = dynamic_resize(pda, size);
157
158
205M
    if (code < 0)
159
0
        return code;
160
205M
    make_tasv_new(pref, t_string,
161
205M
                  a_all | imemory_space((gs_ref_memory_t *) pda->memory),
162
205M
                  size, bytes, pda->base);
163
205M
    return 0;
164
205M
}
165
166
/* ------ Main scanner ------ */
167
168
/* GC procedures */
169
static
170
CLEAR_MARKS_PROC(scanner_clear_marks)
171
484
{
172
484
    scanner_state *const ssptr = vptr;
173
174
484
    r_clear_attrs(&ssptr->s_file, l_mark);
175
484
    r_clear_attrs(&ssptr->s_ss.binary.bin_array, l_mark);
176
484
    r_clear_attrs(&ssptr->s_error.object, l_mark);
177
484
}
178
static
179
1.58k
ENUM_PTRS_WITH(scanner_enum_ptrs, scanner_state *ssptr) return 0;
180
397
case 0:
181
397
    ENUM_RETURN_REF(&ssptr->s_file);
182
397
case 1:
183
397
    ENUM_RETURN_REF(&ssptr->s_error.object);
184
397
case 2:
185
397
    if (ssptr->s_scan_type == scanning_none ||
186
397
        !ssptr->s_da.is_dynamic
187
397
        )
188
372
        ENUM_RETURN(0);
189
25
    return ENUM_STRING2(ssptr->s_da.base, da_size(&ssptr->s_da));
190
397
case 3:
191
397
    if (ssptr->s_scan_type != scanning_binary)
192
397
        return 0;
193
1.58k
    ENUM_RETURN_REF(&ssptr->s_ss.binary.bin_array);
194
1.58k
ENUM_PTRS_END
195
397
static RELOC_PTRS_WITH(scanner_reloc_ptrs, scanner_state *ssptr)
196
397
{
197
397
    RELOC_REF_VAR(ssptr->s_file);
198
397
    r_clear_attrs(&ssptr->s_file, l_mark);
199
397
    if (ssptr->s_scan_type != scanning_none && ssptr->s_da.is_dynamic) {
200
25
        gs_string sda;
201
202
25
        sda.data = ssptr->s_da.base;
203
25
        sda.size = da_size(&ssptr->s_da);
204
25
        RELOC_STRING_VAR(sda);
205
25
        ssptr->s_da.limit = sda.data + sda.size;
206
25
        ssptr->s_da.next = sda.data + (ssptr->s_da.next - ssptr->s_da.base);
207
25
        ssptr->s_da.base = sda.data;
208
25
    }
209
397
    if (ssptr->s_scan_type == scanning_binary) {
210
0
        RELOC_REF_VAR(ssptr->s_ss.binary.bin_array);
211
0
        r_clear_attrs(&ssptr->s_ss.binary.bin_array, l_mark);
212
0
    }
213
397
    RELOC_REF_VAR(ssptr->s_error.object);
214
397
    r_clear_attrs(&ssptr->s_error.object, l_mark);
215
397
}
216
397
RELOC_PTRS_END
217
/* Structure type */
218
public_st_scanner_state_dynamic();
219
220
/* Initialize a scanner. */
221
void
222
gs_scanner_init_options(scanner_state *sstate, const ref *fop, int options)
223
7.24G
{
224
7.24G
    ref_assign(&sstate->s_file, fop);
225
7.24G
    sstate->s_scan_type = scanning_none;
226
7.24G
    sstate->s_pstack = 0;
227
7.24G
    sstate->s_options = options;
228
7.24G
    SCAN_INIT_ERROR(sstate);
229
7.24G
}
230
void gs_scanner_init_stream_options(scanner_state *sstate, stream *s,
231
                                 int options)
232
3.94M
{
233
    /*
234
     * The file 'object' will never be accessed, but it must be in correct
235
     * form for the GC.
236
     */
237
3.94M
    ref fobj;
238
239
3.94M
    make_file(&fobj, a_read, 0, s);
240
3.94M
    gs_scanner_init_options(sstate, &fobj, options);
241
3.94M
}
242
243
/*
244
 * Return the "error object" to be stored in $error.command instead of
245
 * --token--, if any, or <0 if no special error object is available.
246
 */
247
int
248
gs_scanner_error_object(i_ctx_t *i_ctx_p, const scanner_state *pstate,
249
                     ref *pseo)
250
23.4k
{
251
23.4k
    if (!r_has_type(&pstate->s_error.object, t__invalid)) {
252
119
        ref_assign(pseo, &pstate->s_error.object);
253
119
        return 0;
254
119
    }
255
23.2k
    if (pstate->s_error.string[0]) {
256
8.37k
        int len = strlen(pstate->s_error.string);
257
258
8.37k
        if (pstate->s_error.is_name) {
259
277
            int code = name_ref(imemory, (const byte *)pstate->s_error.string, len, pseo, 1);
260
261
277
            if (code < 0)
262
0
                return code;
263
277
            r_set_attrs(pseo, a_executable); /* Adobe compatibility */
264
277
            return 0;
265
8.10k
        } else {
266
8.10k
            byte *estr = ialloc_string(len, "gs_scanner_error_object");
267
268
8.10k
            if (estr == 0)
269
0
                return -1;              /* VMerror */
270
8.10k
            memcpy(estr, (const byte *)pstate->s_error.string, len);
271
8.10k
            make_string(pseo, a_all | icurrent_space, len, estr);
272
8.10k
            return 0;
273
8.10k
        }
274
8.37k
    }
275
14.9k
    return -1;                  /* no error object */
276
23.2k
}
277
278
/* Handle a scan_Refill return from gs_scan_token. */
279
/* This may return o_push_estack, 0 (meaning just call gs_scan_token */
280
/* again), or an error code. */
281
int
282
gs_scan_handle_refill(i_ctx_t *i_ctx_p, scanner_state * sstate,
283
                   bool save, op_proc_t cont)
284
2.26M
{
285
2.26M
    const ref *const fop = &sstate->s_file;
286
2.26M
    stream *s = fptr(fop);
287
2.26M
    uint avail = sbufavailable(s);
288
2.26M
    int status;
289
290
2.26M
    if (s->end_status == EOFC) {
291
        /* More data needed, but none available, so this is a syntax error. */
292
1.04k
        return_error(gs_error_syntaxerror);
293
1.04k
    }
294
2.26M
    status = s_process_read_buf(s);
295
2.26M
    if (sbufavailable(s) > avail)
296
179k
        return 0;
297
2.08M
    if (status == 0)
298
2.08M
        status = s->end_status;
299
2.08M
    switch (status) {
300
1.13k
        case EOFC:
301
            /* We just discovered that we're at EOF. */
302
            /* Let the caller find this out. */
303
1.13k
            return 0;
304
47
        case ERRC:
305
47
            return_error(gs_error_ioerror);
306
0
        case INTC:
307
2.08M
        case CALLC:
308
2.08M
            {
309
2.08M
                ref rstate[1];
310
2.08M
                scanner_state *pstate;
311
312
2.08M
                if (save) {
313
1.89M
                    pstate = (scanner_state *)
314
1.89M
                        ialloc_struct(scanner_state_dynamic, &st_scanner_state_dynamic,
315
1.89M
                                      "gs_scan_handle_refill");
316
1.89M
                    if (pstate == 0)
317
3
                        return_error(gs_error_VMerror);
318
1.89M
                    ((scanner_state_dynamic *)pstate)->mem = imemory;
319
1.89M
                    *pstate = *sstate;
320
1.89M
                } else
321
189k
                    pstate = sstate;
322
2.08M
                make_istruct(&rstate[0], 0, pstate);
323
2.08M
                return s_handle_read_exception(i_ctx_p, status, fop,
324
2.08M
                                               rstate, 1, cont);
325
2.08M
            }
326
2.08M
    }
327
    /* No more data available, but no exception. */
328
    /* A filter is consuming headers but returns nothing. */
329
2.01k
    return 0;
330
2.08M
}
331
332
/*
333
 * Handle a comment.  The 'saved' argument is needed only for
334
 * tracing printout.
335
 */
336
static int
337
scan_comment(i_ctx_t *i_ctx_p, ref *pref, scanner_state *pstate,
338
             const byte * base, const byte * end, bool saved)
339
4.52M
{
340
4.52M
    uint len = (uint) (end - base);
341
4.52M
    int code;
342
#ifdef DEBUG
343
    const char *sstr = (saved ? ">" : "");
344
#endif
345
346
4.52M
    if (len > 1 && (base[1] == '%' || base[1] == '!')) {
347
        /* Process as a DSC comment if requested. */
348
#ifdef DEBUG
349
        if (gs_debug_c('%')) {
350
            dmlprintf2(imemory, "[%%%%%s%c]", sstr, (len >= 3 ? '+' : '-'));
351
            debug_print_string(imemory, base, len);
352
            dmputs(imemory, "\n");
353
        }
354
#endif
355
1.84M
        if (pstate->s_options & SCAN_PROCESS_DSC_COMMENTS) {
356
1.81M
            code = scan_DSC_Comment;
357
1.81M
            goto comment;
358
1.81M
        }
359
        /* Treat as an ordinary comment. */
360
1.84M
    }
361
#ifdef DEBUG
362
    else {
363
        if (gs_debug_c('%')) {
364
            dmlprintf2(imemory, "[%% %s%c]", sstr, (len >= 2 ? '+' : '-'));
365
            debug_print_string(imemory, base, len);
366
            dmputs(imemory, "\n");
367
        }
368
    }
369
#endif
370
2.71M
    if (pstate->s_options & SCAN_PROCESS_COMMENTS) {
371
0
        code = scan_Comment;
372
0
        goto comment;
373
0
    }
374
2.71M
    return 0;
375
1.81M
 comment:
376
1.81M
    {
377
1.81M
        byte *cstr = ialloc_string(len, "scan_comment");
378
379
1.81M
        if (cstr == 0)
380
0
            return_error(gs_error_VMerror);
381
1.81M
        memcpy(cstr, base, len);
382
1.81M
        make_string(pref, a_all | icurrent_space, len, cstr);
383
1.81M
    }
384
0
    return code;
385
1.81M
}
386
387
/* Read a token from a string. */
388
/* Update the string if succesful. */
389
/* Store the error object in i_ctx_p->error_object if not. */
390
int
391
gs_scan_string_token_options(i_ctx_t *i_ctx_p, ref * pstr, ref * pref,
392
                             int options)
393
2.81M
{
394
2.81M
    stream st;
395
2.81M
    stream *s = &st;
396
2.81M
    scanner_state state;
397
2.81M
    int code;
398
399
2.81M
    if (!r_has_attr(pstr, a_read))
400
0
        return_error(gs_error_invalidaccess);
401
2.81M
    s_init(s, NULL);
402
2.81M
    sread_string(s, pstr->value.bytes, r_size(pstr));
403
2.81M
    gs_scanner_init_stream_options(&state, s, options | SCAN_FROM_STRING);
404
2.81M
    switch (code = gs_scan_token(i_ctx_p, pref, &state)) {
405
19
        default:                /* error or comment */
406
19
            if (code < 0)
407
19
                break;
408
            /* falls through */
409
2.81M
        case 0:         /* read a token */
410
2.81M
        case scan_BOS:
411
2.81M
            {
412
2.81M
                uint pos = stell(s);
413
414
2.81M
                pstr->value.bytes += pos;
415
2.81M
                r_dec_size(pstr, pos);
416
2.81M
            }
417
2.81M
            break;
418
0
        case scan_Refill:       /* error */
419
0
            code = gs_note_error(gs_error_syntaxerror);
420
159
        case scan_EOF:
421
159
            break;
422
2.81M
    }
423
2.81M
    if (code < 0)
424
19
        gs_scanner_error_object(i_ctx_p, &state, &i_ctx_p->error_object);
425
2.81M
    return code;
426
2.81M
}
427
428
/*
429
 * Read a token from a stream.  Return 0 if an ordinary token was read,
430
 * >0 for special situations (see iscan.h).
431
 * If the token required a terminating character (i.e., was a name or
432
 * number) and the next character was whitespace, read and discard
433
 * that character.  Note that the state is relevant for gs_error_VMerror
434
 * as well as for scan_Refill.
435
 */
436
int
437
gs_scan_token(i_ctx_t *i_ctx_p, ref * pref, scanner_state * pstate) /* lgtm [cpp/use-of-goto] */
438
7.24G
{
439
7.24G
    stream *const s = pstate->s_file.value.pfile;
440
7.24G
    ref *myref = pref;
441
7.24G
    int retcode = 0;
442
7.24G
    int c;
443
444
7.24G
    s_declare_inline(s, sptr, endptr);
445
7.24G
    const byte *newptr;
446
7.24G
    byte *daptr;
447
448
7.24G
#define sreturn(code)\
449
7.24G
  { retcode = gs_note_error(code); goto sret; }
450
7.24G
#define if_not_spush1()\
451
7.62G
  if ( osp < ostop ) osp++;\
452
7.62G
  else if ( (retcode = ref_stack_push(&o_stack, 1)) >= 0 )\
453
54.0k
    ;\
454
54.0k
  else
455
7.24G
#define spop1()\
456
7.24G
  if ( osp >= osbot ) osp--;\
457
250M
  else ref_stack_pop(&o_stack, 1)
458
7.24G
    int max_name_ctype =
459
7.24G
        ((ref_binary_object_format.value.intval != 0 && level2_enabled)? ctype_name : ctype_btoken);
460
461
7.24G
#define scan_sign(sign, ptr)\
462
7.24G
  switch ( *ptr ) {\
463
4.60M
    case '-': sign = -1; ptr++; break;\
464
10.1k
    case '+': sign = 1; ptr++; break;\
465
2.11G
    default: sign = 0;\
466
2.11G
  }
467
7.24G
#define refill2_back(styp,nback)\
468
7.24G
  BEGIN sptr -= nback; sstate.s_scan_type = styp; goto pause; END
469
7.24G
#define ensure2_back(styp,nback)\
470
7.24G
  if ( sptr >= endptr ) refill2_back(styp,nback)
471
7.24G
#define ensure2(styp) ensure2_back(styp, 1)
472
7.24G
#define refill2(styp) refill2_back(styp, 1)
473
7.24G
    byte s1[2];
474
7.24G
    const byte *const decoder = scan_char_decoder;
475
7.24G
    int status;
476
7.24G
    int sign;
477
7.24G
    const bool check_only = (pstate->s_options & SCAN_CHECK_ONLY) != 0;
478
7.24G
    const bool PDFScanRules = (i_ctx_p->scanner_options & SCAN_PDF_RULES) != 0;
479
    /*
480
     * The following is a hack so that ^D will be self-delimiting in PS files
481
     * (to compensate for bugs in some PostScript-generating applications)
482
     * but not in strings (to match CPSI on the CET) or PDF.
483
     */
484
7.24G
    const int ctrld = (pstate->s_options & SCAN_FROM_STRING ||
485
7.24G
                      PDFScanRules ? 0x04 : 0xffff);
486
7.24G
    scanner_state sstate;
487
488
7.24G
    sptr = endptr = NULL; /* Quiet compiler */
489
7.24G
    if (pstate->s_pstack != 0) {
490
310k
        if_not_spush1()
491
0
            return retcode;
492
310k
        myref = osp;
493
310k
    }
494
    /* Check whether we are resuming after an interruption. */
495
7.24G
    if (pstate->s_scan_type != scanning_none) {
496
979k
        sstate = *pstate;
497
979k
        if (!sstate.s_da.is_dynamic && sstate.s_da.base != sstate.s_da.buf) {
498
            /* The sstate.s_da contains some self-referencing pointers. */
499
            /* Fix them up now. */
500
322
            uint next = sstate.s_da.next - sstate.s_da.base;
501
322
            uint limit = sstate.s_da.limit - sstate.s_da.base;
502
503
322
            sstate.s_da.base = sstate.s_da.buf;
504
322
            sstate.s_da.next = sstate.s_da.buf + next;
505
322
            sstate.s_da.limit = sstate.s_da.buf + limit;
506
322
        }
507
979k
        daptr = sstate.s_da.next;
508
979k
        switch (sstate.s_scan_type) {
509
28.5k
            case scanning_binary:
510
28.5k
                retcode = (*sstate.s_ss.binary.cont)
511
28.5k
                    (i_ctx_p, myref, &sstate);
512
28.5k
                s_begin_inline(s, sptr, endptr);
513
28.5k
                if (retcode == scan_Refill)
514
28.2k
                    goto pause;
515
245
                goto sret;
516
245
            case scanning_comment:
517
0
                s_begin_inline(s, sptr, endptr);
518
0
                goto cont_comment;
519
950k
            case scanning_name:
520
950k
                goto cont_name;
521
0
            case scanning_string:
522
0
                goto cont_string;
523
0
            default:
524
0
                return_error(gs_error_Fatal);
525
979k
        }
526
979k
    }
527
7.24G
    else {
528
        /* We *may* use these in the event of returning to this function after
529
         * a interruption, but not every code path below sets them. Set them
530
         * to sane values here for safety. We can write the contents of sstate
531
         * (back) to pstate before returning.
532
         */
533
7.24G
        sstate.s_da.base = sstate.s_da.next = &(sstate.s_da.buf[0]);
534
7.24G
        sstate.s_da.limit = sstate.s_da.next;
535
7.24G
        sstate.s_da.is_dynamic = false;
536
7.24G
    }
537
    /* Fetch any state variables that are relevant even if */
538
    /* sstate.s_scan_type == scanning_none. */
539
7.24G
    sstate.s_pstack = pstate->s_pstack;
540
7.24G
    sstate.s_pdepth = pstate->s_pdepth;
541
7.24G
    ref_assign(&sstate.s_file, &pstate->s_file);
542
7.24G
    sstate.s_options = pstate->s_options;
543
7.24G
    SCAN_INIT_ERROR(&sstate);
544
7.24G
    s_begin_inline(s, sptr, endptr);
545
    /*
546
     * Loop invariants:
547
     *      If sstate.s_pstack != 0, myref = osp, and *osp is a valid slot.
548
     */
549
14.6G
  top:c = sgetc_inline(s, sptr, endptr);
550
14.6G
    if_debug1m('S', imemory, (c >= 32 && c <= 126 ? "`%c'" : c >= 0 ? "`\\%03o'" : "`%d'"), c);
551
14.6G
    switch (c) {
552
46.0M
        case ' ':
553
46.2M
        case '\f':
554
46.9M
        case '\t':
555
47.1M
        case char_CR:
556
51.6M
        case char_EOL:
557
59.5M
        case char_NULL:
558
59.5M
            goto top;
559
989k
        case 0x04:              /* see ctrld above */
560
989k
            if (c == ctrld)     /* treat as ordinary name char */
561
4
                goto begin_name;
562
            /* fall through */
563
795M
        case '[':
564
1.56G
        case ']':
565
1.56G
            s1[0] = (byte) c;
566
1.56G
            retcode = name_ref(imemory, s1, 1, myref, 1);       /* can't fail */
567
1.56G
            r_set_attrs(myref, a_executable);
568
1.56G
            break;
569
15.3M
        case '<':
570
15.3M
            if (level2_enabled) {
571
14.0M
                ensure2(scanning_none);
572
14.0M
                c = sgetc_inline(s, sptr, endptr);
573
14.0M
                switch (c) {
574
9.07M
                    case '<':
575
9.07M
                        sputback_inline(s, sptr, endptr);
576
9.07M
                        sstate.s_ss.s_name.s_name_type = 0;
577
9.07M
                        sstate.s_ss.s_name.s_try_number = false;
578
9.07M
                        goto try_funny_name;
579
980
                    case '~':
580
980
                        s_A85D_init_inline(&sstate.s_ss.a85d);
581
980
                        sstate.s_ss.st.templat = &s_A85D_template;
582
980
                        sstate.s_ss.a85d.require_eod = true;
583
                        /* If this is an inline ASCII string, interpret it normally, throw an error
584
                         * if it fails rather than ignoring it as PDF (Acrobat) does.
585
                         */
586
980
                        sstate.s_ss.a85d.pdf_rules = false;
587
980
                        goto str;
588
14.0M
                }
589
4.93M
                sputback_inline(s, sptr, endptr);
590
4.93M
            }
591
6.25M
            (void)s_AXD_init_inline(&sstate.s_ss.axd);
592
6.25M
            sstate.s_ss.st.templat = &s_AXD_template;
593
205M
          str:s_end_inline(s, sptr, endptr);
594
205M
            dynamic_init(&sstate.s_da, imemory);
595
206M
          cont_string:for (;;) {
596
206M
                stream_cursor_write w;
597
598
206M
                w.ptr = sstate.s_da.next - 1;
599
206M
                w.limit = sstate.s_da.limit - 1;
600
206M
                status = (*sstate.s_ss.st.templat->process)
601
206M
                    (&sstate.s_ss.st, &s->cursor.r, &w,
602
206M
                     s->end_status == EOFC);
603
206M
                if (!check_only)
604
206M
                    sstate.s_da.next = w.ptr + 1;
605
206M
                switch (status) {
606
750k
                    case 0:
607
750k
                        status = s->end_status;
608
750k
                        if (status < 0) {
609
3.44k
                            if (status == EOFC) {
610
3.44k
                                if (check_only) {
611
0
                                    retcode = scan_Refill;
612
0
                                    sstate.s_scan_type = scanning_string;
613
0
                                    goto suspend;
614
0
                                } else
615
3.44k
                                    sreturn(gs_error_syntaxerror);
616
0
                            }
617
0
                            break;
618
3.44k
                        }
619
747k
                        s_process_read_buf(s);
620
747k
                        continue;
621
11.2k
                    case 1:
622
11.2k
                        if (!check_only) {
623
11.2k
                            retcode = dynamic_grow(&sstate.s_da, sstate.s_da.next, max_string_size);
624
11.2k
                            if (retcode == gs_error_VMerror) {
625
0
                                sstate.s_scan_type = scanning_string;
626
0
                                goto suspend;
627
11.2k
                            } else if (retcode < 0)
628
11.2k
                                sreturn(retcode);
629
11.2k
                        }
630
11.2k
                        continue;
631
206M
                }
632
205M
                break;
633
206M
            }
634
205M
            s_begin_inline(s, sptr, endptr);
635
205M
            switch (status) {
636
2.22k
                default:
637
                    /*case ERRC: */
638
2.22k
                    sreturn(gs_error_syntaxerror);
639
0
                case INTC:
640
0
                case CALLC:
641
0
                    sstate.s_scan_type = scanning_string;
642
0
                    goto pause;
643
205M
                case EOFC:
644
205M
                    ;
645
205M
            }
646
205M
            retcode = dynamic_make_string(i_ctx_p, myref, &sstate.s_da, sstate.s_da.next);
647
205M
            if (retcode < 0) {  /* VMerror */
648
0
                sputback(s);    /* rescan ) */
649
0
                sstate.s_scan_type = scanning_string;
650
0
                goto suspend;
651
0
            }
652
205M
            break;
653
205M
        case '(':
654
198M
            sstate.s_ss.pssd.from_string =
655
198M
                ((pstate->s_options & SCAN_FROM_STRING) != 0) &&
656
198M
                !level2_enabled;
657
198M
            s_PSSD_partially_init_inline(&sstate.s_ss.pssd);
658
198M
            sstate.s_ss.st.templat = &s_PSSD_template;
659
198M
            goto str;
660
899M
        case '{':
661
899M
            if (sstate.s_pstack == 0) {  /* outermost procedure */
662
250M
                if_not_spush1() {
663
0
                    sputback_inline(s, sptr, endptr);
664
0
                    sstate.s_scan_type = scanning_none;
665
0
                    goto pause_ret;
666
0
                }
667
250M
                sstate.s_pdepth = ref_stack_count_inline(&o_stack);
668
250M
            }
669
899M
            make_int(osp, sstate.s_pstack);
670
899M
            sstate.s_pstack = ref_stack_count_inline(&o_stack);
671
899M
            if_debug3m('S', imemory, "[S{]d=%d, s=%d->%d\n",
672
899M
                       sstate.s_pdepth, (int)osp->value.intval, sstate.s_pstack);
673
899M
            goto snext;
674
9.07M
        case '>':
675
9.07M
            if (level2_enabled) {
676
9.07M
                ensure2(scanning_none);
677
9.07M
                sstate.s_ss.s_name.s_name_type = 0;
678
9.07M
                sstate.s_ss.s_name.s_try_number = false;
679
9.07M
                goto try_funny_name;
680
9.07M
            }
681
            /* falls through */
682
324
        case ')':
683
324
            sreturn(gs_error_syntaxerror);
684
894M
        case '}':
685
894M
            if (sstate.s_pstack == 0)
686
894M
                sreturn(gs_error_syntaxerror);
687
894M
            osp--;
688
894M
            {
689
894M
                uint size = ref_stack_count_inline(&o_stack) - sstate.s_pstack;
690
894M
                ref arr;
691
692
894M
                if_debug4m('S', imemory, "[S}]d=%"PRIu32", s=%"PRIu32"->%"PRIpsint", c=%"PRIu32"\n",
693
894M
                           sstate.s_pdepth, sstate.s_pstack,
694
894M
                           (sstate.s_pstack == sstate.s_pdepth ? 0 :
695
894M
                           ref_stack_index(&o_stack, size)->value.intval),
696
894M
                           size + sstate.s_pstack);
697
894M
                if (size > max_array_size)
698
894M
                    sreturn(gs_error_limitcheck);
699
894M
                myref = (sstate.s_pstack == sstate.s_pdepth ? pref : &arr);
700
894M
                if (check_only) {
701
0
                    make_empty_array(myref, 0);
702
0
                    ref_stack_pop(&o_stack, size);
703
894M
                } else if (ref_array_packing.value.boolval) {
704
869M
                    retcode = make_packed_array(myref, &o_stack, size,
705
869M
                                                idmemory, "scanner(packed)");
706
869M
                    if (retcode < 0) {  /* must be VMerror */
707
0
                        osp++;
708
0
                        sputback_inline(s, sptr, endptr);
709
0
                        sstate.s_scan_type = scanning_none;
710
0
                        goto pause_ret;
711
0
                    }
712
869M
                    r_set_attrs(myref, a_executable);
713
869M
                } else {
714
25.8M
                    retcode = ialloc_ref_array(myref,
715
25.8M
                                               a_executable + a_all, size,
716
25.8M
                                               "scanner(proc)");
717
25.8M
                    if (retcode < 0) {  /* must be VMerror */
718
0
                        osp++;
719
0
                        sputback_inline(s, sptr, endptr);
720
0
                        sstate.s_scan_type = scanning_none;
721
0
                        goto pause_ret;
722
0
                    }
723
25.8M
                    retcode = ref_stack_store(&o_stack, myref, size, 0, 1,
724
25.8M
                                              false, idmemory, "scanner");
725
25.8M
                    if (retcode < 0) {
726
0
                        ifree_ref_array(myref, "scanner(proc)");
727
0
                        sreturn(retcode);
728
0
                    }
729
25.8M
                    ref_stack_pop(&o_stack, size);
730
25.8M
                }
731
894M
                if (sstate.s_pstack == sstate.s_pdepth) {         /* This was the top-level procedure. */
732
250M
                    spop1();
733
250M
                    sstate.s_pstack = 0;
734
644M
                } else {
735
644M
                    if (osp < osbot)
736
0
                        ref_stack_pop_block(&o_stack);
737
644M
                    sstate.s_pstack = osp->value.intval;
738
644M
                    *osp = arr;
739
644M
                    goto snext;
740
644M
                }
741
894M
            }
742
250M
            break;
743
3.43G
        case '/':
744
            /*
745
             * If the last thing in the input is a '/', don't try to read
746
             * any more data.
747
             */
748
3.43G
            if (sptr >= endptr && s->end_status != EOFC) {
749
143k
                refill2(scanning_none);
750
143k
            }
751
3.43G
            c = sgetc_inline(s, sptr, endptr);
752
3.43G
            if (!PDFScanRules && (c == '/')) {
753
325M
                sstate.s_ss.s_name.s_name_type = 2;
754
325M
                c = sgetc_inline(s, sptr, endptr);
755
325M
            } else
756
3.10G
                sstate.s_ss.s_name.s_name_type = 1;
757
3.43G
            sstate.s_ss.s_name.s_try_number = false;
758
3.43G
            switch (decoder[c]) {
759
379M
                case ctype_name:
760
3.42G
                default:
761
3.42G
                    goto do_name;
762
3.42G
                case ctype_btoken:
763
3.58k
                    if (!(ref_binary_object_format.value.intval != 0 && level2_enabled))
764
0
                        goto do_name;
765
                    /* otherwise, an empty name */
766
3.99k
                case ctype_exception:
767
212k
                case ctype_space:
768
                    /*
769
                     * Amazingly enough, the Adobe implementations don't accept
770
                     * / or // followed by [, ], <<, or >>, so we do the same.
771
                     * (Older versions of our code had a ctype_other case here
772
                     * that handled these specially.)
773
                     */
774
1.20M
                case ctype_other:
775
1.20M
                    if (c == ctrld) /* see above */
776
0
                        goto do_name;
777
1.20M
                    sstate.s_da.base = sstate.s_da.limit = daptr = 0;
778
1.20M
                    sstate.s_da.is_dynamic = false;
779
1.20M
                    goto nx;
780
3.43G
            }
781
4.52M
        case '%':
782
4.52M
            {                   /* Scan as much as possible within the buffer. */
783
4.52M
                const byte *base = sptr;
784
4.52M
                const byte *end;
785
786
58.7M
                while (++sptr < endptr)         /* stop 1 char early */
787
58.7M
                    switch (*sptr) {
788
143k
                        case char_CR:
789
143k
                            end = sptr;
790
143k
                            if (sptr[1] == char_EOL)
791
18.9k
                                sptr++;
792
4.48M
                          cend: /* Check for externally processed comments. */
793
4.48M
                            retcode = scan_comment(i_ctx_p, myref, &sstate,
794
4.48M
                                                   base, end, false);
795
4.48M
                            if (retcode != 0)
796
1.79M
                                goto comment;
797
2.69M
                            goto top;
798
4.26M
                        case char_EOL:
799
4.34M
                        case '\f':
800
4.34M
                            end = sptr;
801
4.34M
                            goto cend;
802
58.7M
                    }
803
                /*
804
                 * We got to the end of the buffer while inside a comment.
805
                 * If there is a possibility that we must pass the comment
806
                 * to an external procedure, move what we have collected
807
                 * so far into a private buffer now.
808
                 */
809
34.3k
                --sptr;
810
34.3k
                sstate.s_da.buf[1] = 0;
811
34.3k
                {
812
                    /* Could be an externally processable comment. */
813
34.3k
                    uint len = sptr + 1 - base;
814
34.3k
                    if (len > sizeof(sstate.s_da.buf))
815
0
                        len = sizeof(sstate.s_da.buf);
816
817
34.3k
                    memcpy(sstate.s_da.buf, base, len);
818
34.3k
                    daptr = sstate.s_da.buf + len;
819
34.3k
                }
820
34.3k
                sstate.s_da.base = sstate.s_da.buf;
821
34.3k
                sstate.s_da.is_dynamic = false;
822
34.3k
            }
823
            /* Enter here to continue scanning a comment. */
824
            /* daptr must be set. */
825
6.03M
          cont_comment:for (;;) {
826
6.03M
                switch ((c = sgetc_inline(s, sptr, endptr))) {
827
6.01M
                    default:
828
6.01M
                        if (c < 0)
829
6.09k
                            switch (c) {
830
0
                                case INTC:
831
0
                                case CALLC:
832
0
                                    sstate.s_da.next = daptr;
833
0
                                    sstate.s_scan_type = scanning_comment;
834
0
                                    goto pause;
835
6.09k
                                case EOFC:
836
                                    /*
837
                                     * One would think that an EOF in a comment
838
                                     * should be a syntax error, but there are
839
                                     * quite a number of files that end that way.
840
                                     */
841
6.09k
                                    goto end_comment;
842
1
                                default:
843
1
                                    sreturn(gs_error_syntaxerror);
844
6.09k
                            }
845
6.00M
                        if (daptr < sstate.s_da.buf + max_comment_line)
846
612k
                            *daptr++ = c;
847
6.00M
                        continue;
848
1.99k
                    case char_CR:
849
26.0k
                    case char_EOL:
850
28.2k
                    case '\f':
851
34.3k
                      end_comment:
852
34.3k
                        retcode = scan_comment(i_ctx_p, myref, &sstate,
853
34.3k
                                               sstate.s_da.buf, daptr, true);
854
34.3k
                        if (retcode != 0)
855
18.5k
                            goto comment;
856
15.7k
                        goto top;
857
6.03M
                }
858
6.03M
            }
859
            /*NOTREACHED */
860
1.97M
        case EOFC:
861
1.97M
            if (sstate.s_pstack != 0) {
862
7.86k
                if (check_only)
863
0
                    goto pause;
864
7.86k
                sreturn(gs_error_syntaxerror);
865
0
            }
866
1.96M
            retcode = scan_EOF;
867
1.96M
            break;
868
4
        case ERRC:
869
4
            sreturn(gs_error_ioerror);
870
871
            /* Check for a Level 2 funny name (<< or >>). */
872
            /* c is '<' or '>'.  We already did an ensure2. */
873
18.1M
          try_funny_name:
874
18.1M
            {
875
18.1M
                int c1 = sgetc_inline(s, sptr, endptr);
876
877
18.1M
                if (c1 == c) {
878
18.1M
                    s1[0] = s1[1] = c;
879
18.1M
                    name_ref(imemory, s1, 2, myref, 1); /* can't fail */
880
18.1M
                    goto have_name;
881
18.1M
                }
882
122
                sputback_inline(s, sptr, endptr);
883
122
            }
884
122
            sreturn(gs_error_syntaxerror);
885
886
            /* Handle separately the names that might be a number. */
887
167M
        case '0':
888
2.05G
        case '1':
889
2.24G
        case '2':
890
2.37G
        case '3':
891
2.44G
        case '4':
892
2.47G
        case '5':
893
2.49G
        case '6':
894
2.51G
        case '7':
895
2.53G
        case '8':
896
2.54G
        case '9':
897
3.06G
        case '.':
898
3.06G
            sign = 0;
899
3.12G
    nr:     /*
900
             * Skip a leading sign, if any, by conditionally passing
901
             * sptr + 1 rather than sptr.  Also, if the last character
902
             * in the buffer is a CR, we must stop the scan 1 character
903
             * early, to be sure that we can test for CR+LF within the
904
             * buffer, by passing endptr rather than endptr + 1.
905
             */
906
3.12G
            retcode = scan_number(sptr + (sign & 1),
907
3.12G
                    endptr /*(*endptr == char_CR ? endptr : endptr + 1) */ ,
908
3.12G
                                  sign, myref, &newptr, i_ctx_p->scanner_options);
909
3.12G
            if (retcode == 1 && decoder[newptr[-1]] == ctype_space) {
910
1.00G
                sptr = newptr - 1;
911
1.00G
                if (*sptr == char_CR && sptr[1] == char_EOL)
912
2.24k
                    sptr++;
913
1.00G
                retcode = 0;
914
1.00G
                ref_mark_new(myref);
915
1.00G
                break;
916
1.00G
            }
917
2.11G
            sstate.s_ss.s_name.s_name_type = 0;
918
2.11G
            sstate.s_ss.s_name.s_try_number = true;
919
2.11G
            goto do_name;
920
10.2k
        case '+':
921
10.2k
            sign = 1;
922
10.2k
            goto nr;
923
60.7M
        case '-':
924
60.7M
            sign = -1;
925
60.7M
            if(i_ctx_p->scanner_options & SCAN_PDF_INV_NUM) {
926
0
                const byte *osptr = sptr;
927
0
                do {
928
                    /* This is slightly unpleasant: we have to bounds check the buffer,
929
                       rather than just incrementing the point until we find a non '-' character.
930
                       But we cannot differentiate between multiple '-' characters that
931
                       straddle a buffer boundary, or a token that is only one or more '-' characters.
932
                       Handling this relies on the fact that the Postscript-based PDF interpreter
933
                       always uses the "token" operator to tokenize a stream, thus we can assume
934
                       here that the current buffer contains the entire token. So if we reach
935
                       the end of the buffer without hitting a character taht is not a '-', we'll reset
936
                       the buffer pointer, and retry, treating it as a name object.
937
                     */
938
0
                    if (sptr + 1 > endptr) {
939
0
                        sptr = osptr;
940
0
                        sstate.s_ss.s_name.s_name_type = 0;
941
0
                        sstate.s_ss.s_name.s_try_number = true;
942
0
                        goto do_name;
943
0
                    }
944
0
                    if (*(sptr + 1) == '-') {
945
0
                        sptr++;
946
0
                    } else
947
0
                        break;
948
0
                } while (1);
949
0
            }
950
60.7M
            goto nr;
951
952
            /* Check for a binary object */
953
60.7M
          case 128: case 129: case 130: case 131: case 132: case 133: case 134: case 135:
954
1.30M
          case 136: case 137: case 138: case 139: case 140: case 141: case 142: case 143:
955
2.46M
          case 144: case 145: case 146: case 147: case 148: case 149: case 150: case 151:
956
2.46M
          case 152: case 153: case 154: case 155: case 156: case 157: case 158: case 159:
957
2.46M
            if ((ref_binary_object_format.value.intval != 0 && level2_enabled)) {
958
2.46M
                s_end_inline(s, sptr, endptr);
959
2.46M
                retcode = scan_binary_token(i_ctx_p, myref, &sstate);
960
2.46M
                s_begin_inline(s, sptr, endptr);
961
2.46M
                if (retcode == scan_Refill)
962
8.36k
                    goto pause;
963
2.45M
                break;
964
2.46M
            }
965
            /* Not a binary object, fall through. */
966
967
            /* The default is a name. */
968
2.97M
        default:
969
2.97M
            if (c < 0) {
970
1.13M
                dynamic_init(&sstate.s_da, name_memory(imemory));        /* sstate.s_da state must be clean */
971
1.13M
                sstate.s_scan_type = scanning_none;
972
1.13M
                goto pause;
973
1.13M
            }
974
            /* Populate the switch with enough cases to force */
975
            /* simple compilers to use a dispatch rather than tests. */
976
1.84M
        case '!':
977
2.77M
        case '"':
978
6.12M
        case '#':
979
25.8M
        case '$':
980
26.2M
        case '&':
981
27.5M
        case '\'':
982
28.0M
        case '*':
983
30.1M
        case ',':
984
79.1M
        case '=':
985
79.1M
        case ':':
986
116M
        case ';':
987
116M
        case '?':
988
116M
        case '@':
989
118M
        case 'A':
990
119M
        case 'B':
991
130M
        case 'C':
992
137M
        case 'D':
993
145M
        case 'E':
994
153M
        case 'F':
995
156M
        case 'G':
996
160M
        case 'H':
997
165M
        case 'I':
998
166M
        case 'J':
999
167M
        case 'K':
1000
174M
        case 'L':
1001
175M
        case 'M':
1002
194M
        case 'N':
1003
199M
        case 'O':
1004
209M
        case 'P':
1005
215M
        case 'Q':
1006
240M
        case 'R':
1007
257M
        case 'S':
1008
269M
        case 'T':
1009
273M
        case 'U':
1010
278M
        case 'V':
1011
280M
        case 'W':
1012
280M
        case 'X':
1013
281M
        case 'Y':
1014
282M
        case 'Z':
1015
282M
        case '\\':
1016
282M
        case '^':
1017
282M
        case '_':
1018
282M
        case '`':
1019
417M
        case 'a':
1020
481M
        case 'b':
1021
748M
        case 'c':
1022
1.37G
        case 'd':
1023
1.95G
        case 'e':
1024
2.08G
        case 'f':
1025
2.33G
        case 'g':
1026
2.34G
        case 'h':
1027
2.94G
        case 'i':
1028
2.94G
        case 'j':
1029
3.00G
        case 'k':
1030
3.12G
        case 'l':
1031
3.19G
        case 'm':
1032
3.30G
        case 'n':
1033
3.36G
        case 'o':
1034
3.89G
        case 'p':
1035
3.89G
        case 'q':
1036
4.07G
        case 'r':
1037
4.32G
        case 's':
1038
4.39G
        case 't':
1039
4.41G
        case 'u':
1040
4.42G
        case 'v':
1041
4.46G
        case 'w':
1042
4.47G
        case 'x':
1043
4.47G
        case 'y':
1044
4.48G
        case 'z':
1045
4.48G
        case '|':
1046
4.48G
        case '~':
1047
4.48G
          begin_name:
1048
            /* Common code for scanning a name. */
1049
            /* sstate.s_ss.s_name.s_try_number and sstate.s_ss.s_name.s_name_type are already set. */
1050
            /* We know c has ctype_name (or maybe ctype_btoken, */
1051
            /* or is ^D) or is a digit. */
1052
4.48G
            sstate.s_ss.s_name.s_name_type = 0;
1053
4.48G
            sstate.s_ss.s_name.s_try_number = false;
1054
10.0G
          do_name:
1055
            /* Try to scan entirely within the stream buffer. */
1056
            /* We stop 1 character early, so we don't switch buffers */
1057
            /* looking ahead if the name is terminated by \r\n. */
1058
10.0G
            sstate.s_da.base = (byte *) sptr;
1059
10.0G
            sstate.s_da.is_dynamic = false;
1060
10.0G
            {
1061
10.0G
                const byte *endp1 = endptr - 1;
1062
1063
75.8G
                do {
1064
75.8G
                    if (sptr >= endp1)  /* stop 1 early! */
1065
13.2M
                        goto dyn_name;
1066
75.8G
                }
1067
75.8G
                while (decoder[*++sptr] <= max_name_ctype || *sptr == ctrld);   /* digit or name */
1068
10.0G
            }
1069
            /* Name ended within the buffer. */
1070
10.0G
            daptr = (byte *) sptr;
1071
10.0G
            c = *sptr;
1072
10.0G
            goto nx;
1073
13.2M
          dyn_name:             /* Name extended past end of buffer. */
1074
13.2M
            s_end_inline(s, sptr, endptr);
1075
            /* Initialize the dynamic area. */
1076
            /* We have to do this before the next */
1077
            /* sgetc, which will overwrite the buffer. */
1078
13.2M
            sstate.s_da.limit = (byte *)++ sptr;
1079
13.2M
            sstate.s_da.memory = name_memory(imemory);
1080
13.2M
            retcode = dynamic_grow(&sstate.s_da, sstate.s_da.limit, name_max_string);
1081
13.2M
            if (retcode < 0) {
1082
32
                dynamic_save(&sstate.s_da);
1083
32
                if (retcode != gs_error_VMerror)
1084
32
                    sreturn(retcode);
1085
0
                sstate.s_scan_type = scanning_name;
1086
0
                goto pause_ret;
1087
32
            }
1088
13.2M
            daptr = sstate.s_da.next;
1089
            /* Enter here to continue scanning a name. */
1090
            /* daptr must be set. */
1091
14.2M
          cont_name:s_begin_inline(s, sptr, endptr);
1092
68.3M
            while (decoder[c = sgetc_inline(s, sptr, endptr)] <= max_name_ctype || c == ctrld) {
1093
54.1M
                if (daptr == sstate.s_da.limit) {
1094
782k
                    retcode = dynamic_grow(&sstate.s_da, daptr,
1095
782k
                                           name_max_string);
1096
782k
                    if (retcode < 0) {
1097
73
                        dynamic_save(&sstate.s_da);
1098
73
                        if (retcode != gs_error_VMerror)
1099
73
                            sreturn(retcode);
1100
0
                        sputback_inline(s, sptr, endptr);
1101
0
                        sstate.s_scan_type = scanning_name;
1102
0
                        goto pause_ret;
1103
73
                    }
1104
782k
                    daptr = sstate.s_da.next;
1105
782k
                }
1106
54.1M
                *daptr++ = c;
1107
54.1M
            }
1108
10.0G
          nx:switch (decoder[c]) {
1109
5.60G
                case ctype_other:
1110
5.60G
                    if (c == ctrld) /* see above */
1111
0
                        break;
1112
5.60G
                case ctype_btoken:
1113
5.60G
                    sputback_inline(s, sptr, endptr);
1114
5.60G
                    break;
1115
4.41G
                case ctype_space:
1116
                    /* Check for \r\n */
1117
4.41G
                    if (c == char_CR) {
1118
2.18M
                        if (sptr >= endptr) {   /* ensure2 *//* We have to check specially for */
1119
                            /* the case where the very last */
1120
                            /* character of a file is a CR. */
1121
3.24k
                            if (s->end_status != EOFC) {
1122
3.02k
                                sptr--;
1123
3.02k
                                goto pause_name;
1124
3.02k
                            }
1125
2.18M
                        } else if (sptr[1] == char_EOL)
1126
25.6k
                            sptr++;
1127
2.18M
                    }
1128
4.41G
                    break;
1129
4.41G
                case ctype_exception:
1130
6.84M
                    switch (c) {
1131
0
                        case INTC:
1132
947k
                        case CALLC:
1133
947k
                            goto pause_name;
1134
8
                        case ERRC:
1135
8
                            sreturn(gs_error_ioerror);
1136
5.89M
                        case EOFC:
1137
5.89M
                            break;
1138
6.84M
                    }
1139
10.0G
            }
1140
            /* Check for a number */
1141
10.0G
            if (sstate.s_ss.s_name.s_try_number) {
1142
2.11G
                const byte *base = sstate.s_da.base;
1143
1144
2.11G
                scan_sign(sign, base);
1145
2.11G
                retcode = scan_number(base, daptr, sign, myref, &newptr, i_ctx_p->scanner_options);
1146
2.11G
                if (retcode == 1) {
1147
3.47M
                    ref_mark_new(myref);
1148
3.47M
                    retcode = 0;
1149
2.11G
                } else if (retcode != gs_error_syntaxerror) {
1150
1.60G
                    dynamic_free(&sstate.s_da);
1151
1.60G
                    if (sstate.s_ss.s_name.s_name_type == 2)
1152
1.60G
                        sreturn(gs_error_syntaxerror);
1153
1.60G
                    break;      /* might be gs_error_limitcheck */
1154
1.60G
                }
1155
2.11G
            }
1156
8.42G
            if (sstate.s_da.is_dynamic) {        /* We've already allocated the string on the heap. */
1157
9.66M
                uint size = daptr - sstate.s_da.base;
1158
1159
9.66M
                retcode = name_ref(imemory, sstate.s_da.base, size, myref, -1);
1160
9.66M
                if (retcode >= 0) {
1161
8.70M
                    dynamic_free(&sstate.s_da);
1162
8.70M
                } else {
1163
955k
                    retcode = dynamic_resize(&sstate.s_da, size);
1164
955k
                    if (retcode < 0) {  /* VMerror */
1165
0
                        if (c != EOFC)
1166
0
                            sputback_inline(s, sptr, endptr);
1167
0
                        sstate.s_scan_type = scanning_name;
1168
0
                        goto pause_ret;
1169
0
                    }
1170
955k
                    retcode = name_ref(imemory, sstate.s_da.base, size, myref, 2);
1171
955k
                }
1172
8.41G
            } else {
1173
8.41G
                retcode = name_ref(imemory, sstate.s_da.base, (uint) (daptr - sstate.s_da.base),
1174
8.41G
                                   myref, !s->foreign);
1175
8.41G
            }
1176
            /* Done scanning.  Check for preceding /'s. */
1177
8.42G
            if (retcode < 0) {
1178
0
                if (retcode != gs_error_VMerror)
1179
0
                    sreturn(retcode);
1180
0
                if (!sstate.s_da.is_dynamic) {
1181
0
                    sstate.s_da.next = daptr;
1182
0
                    dynamic_save(&sstate.s_da);
1183
0
                }
1184
0
                if (c != EOFC)
1185
0
                    sputback_inline(s, sptr, endptr);
1186
0
                sstate.s_scan_type = scanning_name;
1187
0
                goto pause_ret;
1188
0
            }
1189
8.44G
          have_name:switch (sstate.s_ss.s_name.s_name_type) {
1190
5.01G
                case 0: /* ordinary executable name */
1191
5.01G
                    if (r_has_type(myref, t_name))      /* i.e., not a number */
1192
5.01G
                        r_set_attrs(myref, a_executable);
1193
8.12G
                case 1: /* quoted name */
1194
8.12G
                    break;
1195
325M
                case 2: /* immediate lookup */
1196
325M
                    {
1197
325M
                        ref *pvalue;
1198
1199
325M
                        if (!r_has_type(myref, t_name) ||
1200
325M
                            (pvalue = dict_find_name(myref)) == 0) {
1201
119
                            ref_assign(&sstate.s_error.object, myref);
1202
119
                            r_set_attrs(&sstate.s_error.object,
1203
119
                                a_executable); /* Adobe compatibility */
1204
119
                            sreturn(gs_error_undefined);
1205
0
                        }
1206
325M
                        if (sstate.s_pstack != 0 &&
1207
325M
                            r_space(pvalue) > ialloc_space(idmemory)
1208
325M
                            )
1209
325M
                            sreturn(gs_error_invalidaccess);
1210
325M
                        ref_assign_new(myref, pvalue);
1211
325M
                    }
1212
8.44G
            }
1213
14.6G
    }
1214
13.0G
  sret:if (retcode < 0) {
1215
23.3k
        s_end_inline(s, sptr, endptr);
1216
23.3k
        pstate->s_error = sstate.s_error;
1217
23.3k
        if (sstate.s_pstack != 0) {
1218
9.71k
            if (retcode == gs_error_undefined)
1219
93
                *pref = *osp;   /* return undefined name as error token */
1220
9.71k
            ref_stack_pop(&o_stack,
1221
9.71k
                          ref_stack_count(&o_stack) - (sstate.s_pdepth - 1));
1222
9.71k
        }
1223
23.3k
        return retcode;
1224
23.3k
    }
1225
    /* If we are at the top level, return the object, */
1226
    /* otherwise keep going. */
1227
13.0G
    if (sstate.s_pstack == 0) {
1228
7.24G
        s_end_inline(s, sptr, endptr);
1229
7.24G
        return retcode;
1230
7.24G
    }
1231
7.37G
  snext:if_not_spush1() {
1232
12
        s_end_inline(s, sptr, endptr);
1233
12
        sstate.s_scan_type = scanning_none;
1234
12
        goto save;
1235
12
    }
1236
7.37G
    myref = osp;
1237
7.37G
    goto top;
1238
1239
    /* Pause for an interrupt or callout. */
1240
950k
  pause_name:
1241
    /* If we're still scanning within the stream buffer, */
1242
    /* move the characters to the private buffer (sstate.s_da.buf) now. */
1243
950k
    sstate.s_da.next = daptr;
1244
950k
    dynamic_save(&sstate.s_da);
1245
950k
    sstate.s_scan_type = scanning_name;
1246
2.26M
  pause:
1247
2.26M
    retcode = scan_Refill;
1248
2.26M
  pause_ret:
1249
2.26M
    s_end_inline(s, sptr, endptr);
1250
2.26M
  suspend:
1251
2.26M
    if (sstate.s_pstack != 0)
1252
13.9k
        osp--;                  /* myref */
1253
4.08M
  save:
1254
4.08M
    *pstate = sstate;
1255
4.08M
    return retcode;
1256
1257
    /* Handle a scanned comment. */
1258
1.81M
 comment:
1259
1.81M
    if (retcode < 0)
1260
0
        goto sret;
1261
1.81M
    s_end_inline(s, sptr, endptr);
1262
1.81M
    sstate.s_scan_type = scanning_none;
1263
1.81M
    goto save;
1264
1.81M
}