Coverage Report

Created: 2022-04-16 11:23

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