Coverage Report

Created: 2026-09-14 07:34

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ghostpdl/devices/vector/gdevpsfx.c
Line
Count
Source
1
/* Copyright (C) 2001-2026 Artifex Software, Inc.
2
   All Rights Reserved.
3
4
   This software is provided AS-IS with no warranty, either express or
5
   implied.
6
7
   This software is distributed under license and may not be copied,
8
   modified or distributed except as expressly authorized under the terms
9
   of the license contained in the file LICENSE in this distribution.
10
11
   Refer to licensing information at http://www.artifex.com or contact
12
   Artifex Software, Inc.,  39 Mesa Street, Suite 108A, San Francisco,
13
   CA 94129, USA, for further information.
14
*/
15
16
17
/* Convert Type 1 Charstrings to Type 2 */
18
#include "math_.h"
19
#include "memory_.h"
20
#include "gx.h"
21
#include "gserrors.h"
22
#include "gxfixed.h"
23
#include "gxmatrix.h"   /* for gsfont.h */
24
#include "gxfont.h"
25
#include "gxfont1.h"
26
#include "gxtype1.h"
27
#include "stream.h"
28
#include "gdevpsf.h"
29
#include "gxgstate.h"
30
31
/* ------ Type 1 Charstring parsing ------ */
32
33
/*
34
 * The parsing code handles numbers on its own; it reports callsubr and
35
 * return operators to the caller, but also executes them.
36
 *
37
 * Only the following elements of the Type 1 state are used:
38
 *  ostack, os_count, ipstack, ips_count
39
 */
40
41
10.9M
#define CE_OFFSET 32    /* offset for extended opcodes */
42
43
typedef struct {
44
    fixed v0, v1;   /* coordinates */
45
    ushort index;   /* sequential index of hint */
46
} cv_stem_hint;
47
typedef struct {
48
    int count;
49
    int current;    /* cache cursor for search */
50
    /*
51
     * For dotsection and Type 1 Charstring hint replacement,
52
     * we store active hints at the bottom of the table, and
53
     * replaced hints at the top.
54
     */
55
    int replaced_count;   /* # of replaced hints at top */
56
    cv_stem_hint data[max_total_stem_hints];
57
} cv_stem_hint_table;
58
59
/* Skip over the initial bytes in a Charstring, if any. */
60
static void
61
skip_iv(gs_type1_state *pcis)
62
3.97M
{
63
3.97M
    int skip = pcis->pfont->data.lenIV;
64
3.97M
    ip_state_t *ipsp = &pcis->ipstack[pcis->ips_count - 1];
65
3.97M
    const byte *cip = ipsp->cs_data.bits.data;
66
3.97M
    crypt_state state = crypt_charstring_seed;
67
68
19.8M
    for (; skip > 0; ++cip, --skip)
69
15.8M
        decrypt_skip_next(*cip, state);
70
3.97M
    ipsp->ip = cip;
71
3.97M
    ipsp->dstate = state;
72
3.97M
}
73
74
/*
75
 * Set up for parsing a Type 1 Charstring.
76
 *
77
 * Only uses the following elements of *pfont:
78
 *  data.lenIV
79
 */
80
static void
81
type1_next_init(gs_type1_state *pcis, const gs_glyph_data_t *pgd,
82
                gs_font_type1 *pfont)
83
2.03M
{
84
2.03M
    gs_type1_interp_init(pcis, NULL, NULL, NULL, NULL, false, 0, pfont);
85
2.03M
    pcis->flex_count = flex_max;
86
2.03M
    pcis->ipstack[0].cs_data = *pgd;
87
2.03M
    skip_iv(pcis);
88
2.03M
}
89
90
/* Clear the Type 1 operand stack. */
91
static inline void
92
type1_clear(gs_type1_state *pcis)
93
38.6M
{
94
38.6M
    pcis->os_count = 0;
95
38.6M
}
96
97
/* Execute a callsubr. */
98
static int
99
type1_callsubr(gs_type1_state *pcis, int index)
100
1.93M
{
101
1.93M
    gs_font_type1 *pfont = pcis->pfont;
102
1.93M
    ip_state_t *ipsp1 = &pcis->ipstack[pcis->ips_count];
103
1.93M
    int code = pfont->data.procs.subr_data(pfont, index, false,
104
1.93M
                                           &ipsp1->cs_data);
105
106
1.93M
    if (code < 0)
107
4
        return_error(code);
108
1.93M
    pcis->ips_count++;
109
1.93M
    skip_iv(pcis);
110
1.93M
    return code;
111
1.93M
}
112
113
/* Add 1 or 3 stem hints. */
114
static int
115
type1_stem1(gs_type1_state *pcis, cv_stem_hint_table *psht, const fixed *pv,
116
            fixed lsb, byte *active_hints)
117
9.69M
{
118
9.69M
    fixed v0 = pv[0] + lsb, v1 = v0 + pv[1];
119
9.69M
    cv_stem_hint *bot = &psht->data[0];
120
9.69M
    cv_stem_hint *orig_top = bot + psht->count;
121
9.69M
    cv_stem_hint *top = orig_top;
122
123
9.69M
    if (psht->count >= max_total_stem_hints)
124
0
        return_error(gs_error_limitcheck);
125
14.8M
    while (top > bot &&
126
12.9M
           (v0 < top[-1].v0 || (v0 == top[-1].v0 && v1 < top[-1].v1))
127
9.69M
           ) {
128
5.18M
        *top = top[-1];
129
5.18M
        top--;
130
5.18M
    }
131
9.69M
    if (top > bot && v0 == top[-1].v0 && v1 == top[-1].v1) {
132
        /* Duplicate hint, don't add it. */
133
6.07M
        memmove(top, top + 1, (char *)orig_top - (char *)top);
134
6.07M
        if (active_hints) {
135
4.84M
            uint index = top[-1].index;
136
137
4.84M
            active_hints[index >> 3] |= 0x80 >> (index & 7);
138
4.84M
        }
139
6.07M
        return 0;
140
6.07M
    }
141
3.62M
    top->v0 = v0;
142
3.62M
    top->v1 = v1;
143
3.62M
    psht->count++;
144
3.62M
    return 0;
145
9.69M
}
146
static int
147
type1_stem3(gs_type1_state *pcis, cv_stem_hint_table *psht, const fixed *pv3,
148
            fixed lsb, byte *active_hints)
149
6.61k
{
150
6.61k
    int code = 0;
151
6.61k
    if (type1_stem1(pcis, psht, pv3, lsb, active_hints) < 0)
152
0
        return code;
153
6.61k
    if (type1_stem1(pcis, psht, pv3 + 2, lsb, active_hints) < 0)
154
0
        return code;
155
6.61k
    if (type1_stem1(pcis, psht, pv3 + 4, lsb, active_hints) < 0)
156
0
        return code;
157
6.61k
    return 0;
158
6.61k
}
159
160
/*
161
 * Get the next operator from a Type 1 Charstring.  This procedure handles
162
 * numbers, div, blend, pop, and callsubr/return.
163
 */
164
static int
165
type1_next(gs_type1_state *pcis)
166
43.9M
{
167
43.9M
    ip_state_t *ipsp = &pcis->ipstack[pcis->ips_count - 1];
168
43.9M
    const byte *cip, *cipe;
169
43.9M
    crypt_state state;
170
43.9M
#define CLEAR (csp = pcis->ostack - 1)
171
43.9M
    fixed *csp = (&pcis->ostack[pcis->os_count]) - 1;
172
43.9M
    const bool encrypted = pcis->pfont->data.lenIV >= 0;
173
43.9M
    int c, code, num_results, c0;
174
175
47.8M
 load:
176
47.8M
    cip = ipsp->ip;
177
47.8M
    cipe = ipsp->cs_data.bits.data + ipsp->cs_data.bits.size;
178
47.8M
    state = ipsp->dstate;
179
162M
    for (;;) {
180
162M
        if (cip >= cipe)
181
            /* We used to treat buffer overrun as a simple invalid font, now we assume that
182
             * there is an implicit endchar, so we return a particular error for later
183
             * interception. Returning an error allows any other code to continue as before.
184
             * Part of bug #693170 where the fonts are invalid (no endchar on some glyphs).
185
             */
186
128
            return_error(gs_error_unknownerror);
187
162M
        c0 = *cip++;
188
162M
        charstring_next(c0, state, c, encrypted);
189
162M
        if (c >= c_num1) {
190
            /* This is a number, decode it and push it on the stack. */
191
113M
            if (c < c_pos2_0) { /* 1-byte number */
192
88.1M
                decode_push_num1(csp, pcis->ostack, c);
193
88.1M
            } else if (c < cx_num4) { /* 2-byte number */
194
25.0M
                decode_push_num2(csp, pcis->ostack, c, cip, state, encrypted);
195
25.0M
            } else if (c == cx_num4) { /* 4-byte number */
196
34.4k
                long lw;
197
198
34.4k
                decode_num4(lw, cip, state, encrypted);
199
34.4k
                CS_CHECK_PUSH(csp, pcis->ostack);
200
34.4k
                *++csp = int2fixed(lw);
201
34.4k
                if (lw != fixed2long(*csp)) {
202
                    /*
203
                     * The integer was too large to handle in fixed point.
204
                     * Handle this case specially.
205
                     */
206
2
                    code = gs_type1_check_float(&state, encrypted, &cip, csp, lw);
207
2
                    if (code < 0)
208
2
                       return code;
209
2
                }
210
34.4k
            } else   /* not possible */
211
0
                return_error(gs_error_invalidfont);
212
113M
            continue;
213
113M
        }
214
#ifdef DEBUG
215
        if (gs_debug_c('1')) {
216
            const fixed *p;
217
218
            for (p = pcis->ostack; p <= csp; ++p)
219
                dmprintf1(pcis->pgs->memory, " %g", fixed2float(*p));
220
            if (c == cx_escape) {
221
                crypt_state cstate = state;
222
                int cn;
223
224
                charstring_next(*cip, cstate, cn, encrypted);
225
                dmprintf1(pcis->pgs->memory, " [*%d]\n", cn);
226
            } else
227
                dmprintf1(pcis->pgs->memory, " [%d]\n", c);
228
        }
229
#endif
230
48.8M
        switch ((char_command) c) {
231
43.0M
        default:
232
43.0M
            break;
233
43.0M
        case c_undef0:
234
8
        case c_undef2:
235
15
        case c_undef17:
236
15
            return_error(gs_error_invalidfont);
237
1.93M
        case c_callsubr:
238
1.93M
            if (csp + 1 - &pcis->ostack[0] < 1)
239
2
                return_error(gs_error_invalidfont);
240
            /* Check there is space available on the control stack */
241
1.93M
            CS_CHECK_IPSTACK(ipsp + 1, pcis->ipstack);
242
1.93M
            code = type1_callsubr(pcis, fixed2int_var(*csp) +
243
1.93M
                                  pcis->pfont->data.subroutineNumberBias);
244
1.93M
            if (code < 0)
245
4
                return_error(code);
246
1.93M
            ipsp->ip = cip, ipsp->dstate = state;
247
1.93M
            --csp;
248
1.93M
            ++ipsp;
249
1.93M
            goto load;
250
1.93M
        case c_return:
251
1.93M
            if (pcis->ips_count > 1) {
252
1.93M
                gs_glyph_data_free(&ipsp->cs_data, "type1_next");
253
1.93M
                pcis->ips_count--;
254
1.93M
                --ipsp;
255
1.93M
            } else
256
4
                return_error(gs_error_invalidfont);
257
1.93M
            goto load;
258
1.93M
        case c_undoc15:
259
            /* See gstype1.h for information on this opcode. */
260
1
            CLEAR;
261
1
            continue;
262
1.91M
        case cx_escape:
263
1.91M
            charstring_next(*cip, state, c, encrypted);
264
1.91M
            ++cip;
265
1.91M
            switch ((char1_extended_command) c) {
266
6.96k
            default:
267
6.96k
                c += CE_OFFSET;
268
6.96k
                break;
269
34.0k
            case ce1_div:
270
34.0k
                if (csp + 1 - &pcis->ostack[0] < 1)
271
0
                    return_error(gs_error_invalidfont);
272
34.0k
                csp[-1] = float2fixed((double)csp[-1] / (double)*csp);
273
34.0k
                --csp;
274
34.0k
                continue;
275
0
            case ce1_undoc15: /* see gstype1.h */
276
0
                CLEAR;
277
0
                continue;
278
937k
            case ce1_callothersubr:
279
937k
                if (csp + 1 - &pcis->ostack[0] < 2)
280
0
                    return_error(gs_error_invalidfont);
281
937k
                switch (fixed2int_var(*csp)) {
282
342
                case 0:
283
342
                    pcis->ignore_pops = 2;
284
342
                    break; /* pass to caller */
285
934k
                case 3:
286
934k
                    pcis->ignore_pops = 1;
287
934k
                    break; /* pass to caller */
288
0
                case 14:
289
0
                    num_results = 1; goto blend;
290
0
                case 15:
291
0
                    num_results = 2; goto blend;
292
0
                case 16:
293
0
                    num_results = 3; goto blend;
294
0
                case 17:
295
0
                    num_results = 4; goto blend;
296
0
                case 18:
297
0
                    num_results = 6;
298
0
                blend:
299
0
                    CS_CHECK_POP(csp, pcis->ostack);
300
0
                    if (!CS_CHECK_CSTACK_BOUNDS(&csp[-1 - fixed2int_var(csp[-1])], pcis->ostack))
301
0
                        return_error(gs_error_invalidfont);
302
303
0
                    code = gs_type1_blend(pcis, csp, num_results);
304
0
                    if (code < 0)
305
0
                        return code;
306
0
                    csp -= code;
307
0
                    continue;
308
2.73k
                default:
309
2.73k
                    break; /* pass to caller */
310
937k
                }
311
937k
                break;
312
937k
            case ce1_pop:
313
935k
                if (pcis->ignore_pops != 0) {
314
935k
                    pcis->ignore_pops--;
315
935k
                    continue;
316
935k
                }
317
1.91M
                return_error(gs_error_rangecheck);
318
1.91M
            }
319
944k
            break;
320
48.8M
        }
321
43.9M
        break;
322
48.8M
    }
323
43.9M
    ipsp->ip = cip, ipsp->dstate = state;
324
43.9M
    pcis->ips_count = ipsp + 1 - &pcis->ipstack[0];
325
43.9M
    pcis->os_count = csp + 1 - &pcis->ostack[0];
326
43.9M
    return c;
327
47.8M
}
328
329
/* ------ Output ------ */
330
331
/* Put 2 or 4 bytes on a stream (big-endian). */
332
static void
333
sputc2(stream *s, int i)
334
11.5M
{
335
11.5M
    sputc(s, (byte)(i >> 8));
336
11.5M
    sputc(s, (byte)i);
337
11.5M
}
338
static void
339
sputc4(stream *s, int i)
340
17.0k
{
341
17.0k
    sputc2(s, i >> 16);
342
17.0k
    sputc2(s, i);
343
17.0k
}
344
345
/* Put a Type 2 operator on a stream. */
346
static void
347
type2_put_op(stream *s, int op)
348
10.9M
{
349
10.9M
    if (op >= CE_OFFSET) {
350
171
        spputc(s, cx_escape);
351
171
        spputc(s, (byte)(op - CE_OFFSET));
352
171
    } else
353
10.9M
        sputc(s, (byte)op);
354
10.9M
}
355
356
/* Put a Type 2 number on a stream. */
357
static void
358
type2_put_int(stream *s, int i)
359
50.3M
{
360
50.3M
    if (i >= -107 && i <= 107)
361
38.8M
        sputc(s, (byte)(i + 139));
362
11.5M
    else if (i <= 1131 && i >= 0)
363
7.92M
        sputc2(s, (c_pos2_0 << 8) + i - 108);
364
3.61M
    else if (i >= -1131 && i < 0)
365
3.61M
        sputc2(s, (c_neg2_0 << 8) - i - 108);
366
819
    else if (i >= -32768 && i <= 32767) {
367
819
        spputc(s, c2_shortint);
368
819
        sputc2(s, i);
369
819
    } else {
370
        /*
371
         * We can't represent this number directly: compute it.
372
         * (This can be done much more efficiently in particular cases;
373
         * we'll do this if it ever seems worthwhile.)
374
         */
375
0
        type2_put_int(s, i >> 10);
376
0
        type2_put_int(s, 1024);
377
0
        type2_put_op(s, CE_OFFSET + ce2_mul);
378
0
        type2_put_int(s, i & 1023);
379
0
        type2_put_op(s, CE_OFFSET + ce2_add);
380
0
    }
381
50.3M
}
382
383
/* Put a fixed value on a stream. */
384
static void
385
type2_put_fixed(stream *s, fixed v)
386
50.4M
{
387
50.4M
    if (fixed_is_int(v))
388
50.3M
        type2_put_int(s, fixed2int_var(v));
389
17.0k
    else if (v >= int2fixed(-32768) && v < int2fixed(32768)) {
390
        /* We can represent this as a 16:16 number. */
391
17.0k
        spputc(s, cx_num4);
392
17.0k
        sputc4(s, v << (16 - _fixed_shift));
393
17.0k
    } else {
394
0
        type2_put_int(s, fixed2int_var(v));
395
0
        type2_put_fixed(s, fixed_fraction(v));
396
0
        type2_put_op(s, CE_OFFSET + ce2_add);
397
0
    }
398
50.4M
}
399
400
/* Put a stem hint table on a stream. */
401
static void
402
type2_put_stems(stream *s, int os_count, const cv_stem_hint_table *psht, int op)
403
1.71M
{
404
1.71M
    fixed prev = 0;
405
1.71M
    int pushed = os_count;
406
1.71M
    int i;
407
408
5.33M
    for (i = 0; i < psht->count; ++i, pushed += 2) {
409
3.62M
        fixed v0 = psht->data[i].v0;
410
3.62M
        fixed v1 = psht->data[i].v1;
411
412
3.62M
        if (pushed > ostack_size - 2) {
413
0
            type2_put_op(s, op);
414
0
            pushed = 0;
415
0
        }
416
3.62M
        type2_put_fixed(s, v0 - prev);
417
3.62M
        type2_put_fixed(s, v1 - v0);
418
3.62M
        prev = v1;
419
3.62M
    }
420
1.71M
    type2_put_op(s, op);
421
1.71M
}
422
423
/* Put out a hintmask command. */
424
static void
425
type2_put_hintmask(stream *s, const byte *mask, uint size)
426
701k
{
427
701k
    uint ignore;
428
429
701k
    type2_put_op(s, c2_hintmask);
430
701k
    sputs(s, mask, size, &ignore);
431
701k
}
432
433
/* ------ Main program ------ */
434
435
/*
436
 * Convert a Type 1 Charstring to (unencrypted) Type 2.
437
 * For simplicity, we expand all Subrs in-line.
438
 * We still need to optimize the output using these patterns:
439
 *  (vhcurveto hvcurveto)* (vhcurveto hrcurveto | vrcurveto) =>
440
 *    vhcurveto
441
 *  (hvcurveto vhcurveto)* (hvcurveto vrcurveto | hrcurveto) =>
442
 *    hvcurveto
443
 */
444
11.4M
#define MAX_STACK ostack_size
445
int
446
psf_convert_type1_to_type2(stream *s, const gs_glyph_data_t *pgd,
447
                           gs_font_type1 *pfont)
448
1.01M
{
449
1.01M
    gs_type1_state cis;
450
1.01M
    cv_stem_hint_table hstem_hints; /* horizontal stem hints */
451
1.01M
    cv_stem_hint_table vstem_hints; /* vertical stem hints */
452
1.01M
    bool first = true;
453
1.01M
    bool need_moveto = true;
454
1.01M
    bool replace_hints = false;
455
1.01M
    bool hints_changed = false;
456
1.01M
    bool width_on_stack = false;
457
1.01M
    enum {
458
1.01M
        dotsection_in = 0,
459
1.01M
        dotsection_out = -1
460
1.01M
    } dotsection_flag = dotsection_out;
461
1.01M
    byte active_hints[(max_total_stem_hints + 7) / 8];
462
1.01M
    byte dot_save_hints[(max_total_stem_hints + 7) / 8];
463
1.01M
    uint hintmask_size;
464
1.01M
#define HINTS_CHANGED()\
465
5.30M
  BEGIN\
466
5.30M
    hints_changed = replace_hints;\
467
5.30M
    if (hints_changed)\
468
5.30M
        CHECK_OP();   /* see below */\
469
5.30M
  END
470
1.01M
#define CHECK_HINTS_CHANGED()\
471
8.81M
  BEGIN\
472
8.81M
    if (hints_changed) {\
473
701k
        type2_put_hintmask(s, active_hints, hintmask_size);\
474
701k
        hints_changed = false;\
475
701k
    }\
476
8.81M
  END
477
    /*
478
     * In order to combine Type 1 operators, we usually delay writing
479
     * out operators (but not their operands).  We must keep track of
480
     * the stack depth so we don't exceed it when combining operators.
481
     */
482
1.01M
    int depth;      /* of operands on stack */
483
1.01M
    int prev_op;    /* operator to write, -1 if none */
484
1.01M
    int code = 0;
485
1.01M
#define CLEAR_OP()\
486
8.51M
  (depth = 0, prev_op = -1)
487
1.01M
#define CHECK_OP()\
488
15.4M
  BEGIN\
489
15.4M
    if (prev_op >= 0) {\
490
7.49M
        type2_put_op(s, prev_op);\
491
7.49M
        CLEAR_OP();\
492
7.49M
    }\
493
15.4M
  END
494
1.01M
    fixed mx0 = 0, my0 = 0; /* See ce1_setcurrentpoint. */
495
496
    /* Really this is to silence Coverity, but it makes sense and we do it a lot so no penatly */
497
1.01M
    memset(active_hints, 0, (max_total_stem_hints + 7) / 8);
498
499
    /* In case we do not get an sbw or hsbw op */
500
1.01M
    cis.lsb.x = cis.lsb.y = cis.width.x = cis.width.y = fixed_0;
501
502
    /*
503
     * Do a first pass to collect hints.  Note that we must also process
504
     * [h]sbw, because the hint coordinates are relative to the lsb.
505
     */
506
1.01M
    hstem_hints.count = hstem_hints.replaced_count = hstem_hints.current = 0;
507
1.01M
    vstem_hints.count = vstem_hints.replaced_count = vstem_hints.current = 0;
508
1.01M
    type1_next_init(&cis, pgd, pfont);
509
21.9M
    for (;;) {
510
21.9M
        int c = type1_next(&cis);
511
21.9M
        fixed *csp = (&cis.ostack[cis.os_count]) - 1;
512
513
21.9M
        switch (c) {
514
14.6M
        default:
515
             /* We used to treat buffer overrun as a simple invalid font, now we assume that
516
             * there is an implicit endchar, this is handled by looking for a specific error.
517
             * Part of bug #693170 where the fonts are invalid (no endchar on some glyphs).
518
             */
519
14.6M
           if (c == gs_error_unknownerror)
520
65
                break;
521
14.6M
            if (c < 0)
522
27
                return c;
523
14.6M
            type1_clear(&cis);
524
14.6M
            continue;
525
1.01M
        case c1_hsbw:
526
1.01M
            if (cis.os_count < 2)
527
4
                return_error(gs_error_invalidfont);
528
1.01M
            gs_type1_sbw(&cis, cis.ostack[0], fixed_0, cis.ostack[1], fixed_0);
529
1.01M
            goto clear;
530
2.86M
        case cx_hstem:
531
2.86M
            if (cis.os_count < 2)
532
1
                return_error(gs_error_invalidfont);
533
2.86M
            code = type1_stem1(&cis, &hstem_hints, csp - 1, cis.lsb.y, NULL);
534
2.86M
            if (code < 0)
535
0
                return code;
536
2.86M
            goto clear;
537
2.86M
        case cx_vstem:
538
1.97M
            if (cis.os_count < 2)
539
1
                return_error(gs_error_invalidfont);
540
1.97M
            code = type1_stem1(&cis, &vstem_hints, csp - 1, cis.lsb.x, NULL);
541
1.97M
            if (code < 0)
542
0
                return code;
543
1.97M
            goto clear;
544
1.97M
        case CE_OFFSET + ce1_sbw:
545
0
            if (cis.os_count < 4)
546
0
                return_error(gs_error_invalidfont);
547
0
            gs_type1_sbw(&cis, cis.ostack[0], cis.ostack[1],
548
0
                         cis.ostack[2], cis.ostack[3]);
549
0
            goto clear;
550
3.30k
        case CE_OFFSET + ce1_vstem3:
551
3.30k
            if (cis.os_count < 6)
552
0
                return_error(gs_error_invalidfont);
553
3.30k
            code = type1_stem3(&cis, &vstem_hints, csp - 5, cis.lsb.x, NULL);
554
3.30k
            if (code < 0)
555
0
                return code;
556
3.30k
            goto clear;
557
3.30k
        case CE_OFFSET + ce1_hstem3:
558
0
            if (cis.os_count < 6)
559
0
                return_error(gs_error_invalidfont);
560
0
            code = type1_stem3(&cis, &hstem_hints, csp - 5, cis.lsb.y, NULL);
561
0
            if (code < 0)
562
0
                return code;
563
5.86M
        clear:
564
5.86M
            type1_clear(&cis);
565
5.86M
            continue;
566
468k
        case ce1_callothersubr:
567
468k
            if (cis.os_count < 2)
568
0
                return_error(gs_error_invalidfont);
569
468k
            if (*csp == int2fixed(3))
570
467k
                replace_hints = true;
571
468k
            if (fixed2int(csp[-1]) < 0)
572
4
                return_error(gs_error_invalidfont);
573
468k
            if (cis.os_count < 2 + fixed2int(csp[-1]))
574
2
                return_error(gs_error_invalidfont);
575
468k
            if (*csp == int2fixed(12) || *csp == int2fixed(13))
576
0
                cis.os_count -= fixed2int(csp[-1]);
577
468k
            cis.os_count -= 2;
578
468k
            continue;
579
0
        case CE_OFFSET + ce1_dotsection:
580
0
            replace_hints = true;
581
0
            continue;
582
0
        case CE_OFFSET + ce1_seac:
583
0
            if (cis.os_count < 5)
584
0
                return_error(gs_error_invalidfont);
585
1.01M
        case cx_endchar:
586
1.01M
            break;
587
21.9M
        }
588
1.01M
        break;
589
21.9M
    }
590
    /*
591
     * Number the hints for hintmask.  We must do this even if we never
592
     * replace hints, because type1_stem# uses the index to set bits in
593
     * active_hints.
594
     */
595
1.01M
    {
596
1.01M
        int i;
597
598
3.26M
        for (i = 0; i < hstem_hints.count; ++i)
599
2.24M
            hstem_hints.data[i].index = i;
600
2.39M
        for (i = 0; i < vstem_hints.count; ++i)
601
1.37M
            vstem_hints.data[i].index = i + hstem_hints.count;
602
1.01M
    }
603
1.01M
    if (replace_hints) {
604
234k
        hintmask_size =
605
234k
            (hstem_hints.count + vstem_hints.count + 7) / 8;
606
234k
        if (hintmask_size > (max_total_stem_hints + 7) / 8)
607
0
            return_error(gs_error_invalidfont);
608
234k
        memset(active_hints, 0, hintmask_size);
609
234k
    } else
610
784k
        hintmask_size = 0;
611
612
    /* Do a second pass to write the result. */
613
1.01M
    type1_next_init(&cis, pgd, pfont);
614
1.01M
    CLEAR_OP();
615
21.9M
    for (;;) {
616
21.9M
        int c = type1_next(&cis);
617
21.9M
        fixed *csp = (&cis.ostack[cis.os_count]) - 1;
618
21.9M
#define POP(n)\
619
21.9M
  (csp -= (n), cis.os_count -= (n))
620
21.9M
        int i;
621
21.9M
        fixed mx, my;
622
623
21.9M
        if (need_moveto && ((c >= cx_rlineto && c <= cx_rrcurveto) ||
624
7.00M
            c == cx_vhcurveto || c == cx_hvcurveto))
625
27
        {
626
27
            mx = my = 0;
627
27
            need_moveto = false;
628
27
            CHECK_OP();
629
27
            if (first) {
630
0
                if (width_on_stack) {
631
0
                    if (cis.os_count < 1)
632
0
                        return_error(gs_error_invalidfont);
633
0
                    type2_put_fixed(s, *csp); /* width */
634
                    /* We need to move all the stored numeric values up by
635
                     * one in the stack, eliminating the width, so that later
636
                     * processing when we handle the drswing operator emits the correct
637
                     * values. This is different to the 'move' case below.
638
                     */
639
0
                    cis.os_count--;
640
0
                    for (i = 0; i < cis.os_count; ++i)
641
0
                        cis.ostack[i] = cis.ostack[i+1];
642
0
                }
643
0
                mx += cis.lsb.x + mx0, my += cis.lsb.y + my0;
644
0
                first = false;
645
0
            }
646
27
            CHECK_HINTS_CHANGED();
647
27
            if (mx == 0) {
648
27
                type2_put_fixed(s, my);
649
27
                depth = 1, prev_op = cx_vmoveto;
650
27
            } else if (my == 0) {
651
0
                type2_put_fixed(s, mx);
652
0
                depth = 1, prev_op = cx_hmoveto;
653
0
            } else {
654
0
                type2_put_fixed(s, mx);
655
0
                type2_put_fixed(s, my);
656
0
                depth = 2, prev_op = cx_rmoveto;
657
0
            }
658
27
        }
659
660
21.9M
        switch (c) {
661
146
        default:
662
             /* We used to treat buffer overrun as a simple invalid font, now we assume that
663
             * there is an implicit endchar, this is handled by looking for a specific error.
664
             * Part of bug #693170 where the fonts are invalid (no endchar on some glyphs).
665
             */
666
146
            if (c == gs_error_unknownerror) {
667
63
                type2_put_op(s, cx_endchar);
668
63
                return 0;
669
63
            }
670
83
            if (c < 0)
671
0
                return c;
672
83
            if (c >= CE_OFFSET)
673
0
                return_error(gs_error_rangecheck);
674
            /* The Type 1 use of all other operators is the same in Type 2. */
675
6.17M
        copy:
676
6.17M
            CHECK_OP();
677
6.17M
            CHECK_HINTS_CHANGED();
678
11.9M
        put:
679
51.6M
            for (i = 0; i < cis.os_count; ++i)
680
39.6M
                type2_put_fixed(s, cis.ostack[i]);
681
11.9M
            depth += cis.os_count;
682
11.9M
            prev_op = c;
683
11.9M
            type1_clear(&cis);
684
11.9M
            continue;
685
2.86M
        case cx_hstem:
686
2.86M
            if (cis.os_count < 2)
687
0
                return_error(gs_error_invalidfont);
688
2.86M
            code = type1_stem1(&cis, &hstem_hints, csp - 1, cis.lsb.y, active_hints);
689
2.86M
            if (code < 0)
690
0
                return code;
691
4.84M
        hint:
692
4.84M
            HINTS_CHANGED();
693
4.84M
            type1_clear(&cis);
694
4.84M
            continue;
695
1.97M
        case cx_vstem:
696
1.97M
            if (cis.os_count < 2)
697
0
                return_error(gs_error_invalidfont);
698
1.97M
            code = type1_stem1(&cis, &vstem_hints, csp - 1, cis.lsb.x, active_hints);
699
1.97M
            if (code < 0)
700
0
                return code;
701
1.97M
            goto hint;
702
1.97M
        case CE_OFFSET + ce1_vstem3:
703
3.30k
            if (cis.os_count < 6)
704
0
                return_error(gs_error_invalidfont);
705
3.30k
            code = type1_stem3(&cis, &vstem_hints, csp - 5, cis.lsb.x, active_hints);
706
3.30k
            if (code < 0)
707
0
                return code;
708
3.30k
            goto hint;
709
3.30k
        case CE_OFFSET + ce1_hstem3:
710
0
            if (cis.os_count < 6)
711
0
                return_error(gs_error_invalidfont);
712
0
            code = type1_stem3(&cis, &hstem_hints, csp - 5, cis.lsb.y, active_hints);
713
0
            if (code < 0)
714
0
                return code;
715
0
            goto hint;
716
0
        case CE_OFFSET + ce1_dotsection:
717
0
            if (dotsection_flag == dotsection_out) {
718
0
                memcpy(dot_save_hints, active_hints, hintmask_size);
719
0
                memset(active_hints, 0, hintmask_size);
720
0
                dotsection_flag = dotsection_in;
721
0
            } else {
722
0
                memcpy(active_hints, dot_save_hints, hintmask_size);
723
0
                dotsection_flag = dotsection_out;
724
0
            }
725
0
            HINTS_CHANGED();
726
0
            continue;
727
1.32M
        case c1_closepath:
728
1.32M
            need_moveto = true;
729
1.32M
            continue;
730
171
        case CE_OFFSET + ce1_setcurrentpoint:
731
171
            if (first) {
732
0
                if (cis.os_count < 2)
733
0
                    return_error(gs_error_invalidfont);
734
735
                /*  A workaround for fonts which use ce1_setcurrentpoint
736
                    in an illegal way for shifting a path.
737
                    See t1_hinter__setcurrentpoint for more information. */
738
0
                mx0 = csp[-1], my0 = *csp;
739
0
            }
740
171
            continue;
741
215k
        case cx_vmoveto:
742
215k
            if (cis.os_count < 1)
743
0
                return_error(gs_error_invalidfont);
744
215k
            mx = 0, my = *csp;
745
215k
            POP(1); goto move;
746
57.1k
        case cx_hmoveto:
747
57.1k
            if (cis.os_count < 1)
748
0
                return_error(gs_error_invalidfont);
749
57.1k
            mx = *csp, my = 0;
750
57.1k
            POP(1); goto move;
751
1.04M
        case cx_rmoveto:
752
1.04M
            if (cis.os_count < 2)
753
0
                return_error(gs_error_invalidfont);
754
1.04M
            mx = csp[-1], my = *csp;
755
1.04M
            POP(2);
756
1.32M
        move:
757
1.32M
            need_moveto = false;
758
1.32M
            CHECK_OP();
759
1.32M
            if (first) {
760
944k
                if (cis.os_count)
761
5.56k
                    type2_put_fixed(s, *csp); /* width */
762
944k
                mx += cis.lsb.x + mx0, my += cis.lsb.y + my0;
763
944k
                first = false;
764
944k
            }
765
1.32M
            if (cis.flex_count != flex_max) {
766
                /* We're accumulating points for a flex. */
767
1.19k
                if (type1_next(&cis) != ce1_callothersubr)
768
0
                    return_error(gs_error_rangecheck);
769
1.19k
                csp = &cis.ostack[cis.os_count - 1];
770
1.19k
                if (*csp != int2fixed(2) || csp[-1] != fixed_0)
771
0
                    return_error(gs_error_rangecheck);
772
1.19k
                cis.flex_count++;
773
1.19k
                csp[-1] = mx, *csp = my;
774
1.19k
                continue;
775
1.19k
            }
776
1.32M
            CHECK_HINTS_CHANGED();
777
1.32M
            if (mx == 0) {
778
92.3k
                type2_put_fixed(s, my);
779
92.3k
                depth = 1, prev_op = cx_vmoveto;
780
1.22M
            } else if (my == 0) {
781
78.9k
                type2_put_fixed(s, mx);
782
78.9k
                depth = 1, prev_op = cx_hmoveto;
783
1.14M
            } else {
784
1.14M
                type2_put_fixed(s, mx);
785
1.14M
                type2_put_fixed(s, my);
786
1.14M
                depth = 2, prev_op = cx_rmoveto;
787
1.14M
            }
788
1.32M
            type1_clear(&cis);
789
1.32M
            continue;
790
1.01M
        case c1_hsbw:
791
1.01M
            if (cis.os_count < 2)
792
0
                return_error(gs_error_invalidfont);
793
1.01M
            gs_type1_sbw(&cis, cis.ostack[0], fixed_0, cis.ostack[1], fixed_0);
794
            /*
795
             * Leave the l.s.b. on the operand stack for the initial hint,
796
             * moveto, or endchar command.
797
             */
798
1.01M
            cis.ostack[0] = cis.ostack[1];
799
1.01M
        sbw:
800
            /* cff_write_Private doesn't write defaultWidthX
801
               when called with the Type 1 font,
802
               so the reader will assume
803
               defaultWidthX = defaultWidthX_DEFAULT
804
               Use the latter here.
805
             */
806
1.01M
            if (cis.ostack[0] == default_defaultWidthX)
807
1.89k
                cis.os_count = 0;
808
1.01M
            else {
809
1.01M
                cis.ostack[0] -= default_defaultWidthX;
810
1.01M
                cis.os_count = 1;
811
1.01M
                width_on_stack = true;
812
1.01M
            }
813
1.01M
            if (hstem_hints.count) {
814
932k
                if (cis.os_count)
815
932k
                    type2_put_fixed(s, cis.ostack[0]);
816
932k
                type2_put_stems(s, cis.os_count, &hstem_hints,
817
932k
                                (replace_hints ? c2_hstemhm : cx_hstem));
818
932k
                cis.os_count = 0;
819
932k
                width_on_stack = false;
820
932k
            }
821
1.01M
            if (vstem_hints.count) {
822
782k
                if (cis.os_count)
823
6.13k
                    type2_put_fixed(s, cis.ostack[0]);
824
782k
                type2_put_stems(s, cis.os_count, &vstem_hints,
825
782k
                                (replace_hints ? c2_vstemhm : cx_vstem));
826
782k
                cis.os_count = 0;
827
782k
                width_on_stack = false;
828
782k
            }
829
1.01M
            continue;
830
0
        case CE_OFFSET + ce1_seac:
831
0
            if (cis.os_count < 5)
832
0
                return_error(gs_error_invalidfont);
833
            /*
834
             * It is an undocumented feature of the Type 2 CharString
835
             * format that endchar + 4 or 5 operands is equivalent to
836
             * seac with an implicit asb operand + endchar with 0 or 1
837
             * operands.  Remove the asb argument from the stack, but
838
             * adjust the adx argument to compensate for the fact that
839
             * Type 2 CharStrings don't have any concept of l.s.b.
840
             */
841
0
            csp[-3] += cis.lsb.x - csp[-4];
842
0
            memmove(csp - 4, csp - 3, sizeof(*csp) * 4);
843
0
            POP(1);
844
            /* (falls through) */
845
1.01M
        case cx_endchar:
846
1.01M
            CHECK_OP();
847
1.09M
            for (i = 0; i < cis.os_count; ++i)
848
73.0k
                type2_put_fixed(s, cis.ostack[i]);
849
1.01M
            type2_put_op(s, cx_endchar);
850
1.01M
            return 0;
851
0
        case CE_OFFSET + ce1_sbw:
852
0
            if (cis.os_count < 4)
853
0
                return_error(gs_error_invalidfont);
854
0
            gs_type1_sbw(&cis, cis.ostack[0], cis.ostack[1],
855
0
                         cis.ostack[2], cis.ostack[3]);
856
0
            cis.ostack[0] = cis.ostack[2];
857
0
            goto sbw;
858
467k
        case ce1_callothersubr:
859
467k
            if (cis.os_count < 2)
860
0
                return_error(gs_error_invalidfont);
861
467k
            CHECK_OP();
862
467k
            switch (fixed2int_var(*csp)) {
863
0
            default:
864
0
                return_error(gs_error_rangecheck);
865
171
            case 0:
866
                /*
867
                 * The operand stack contains: delta to reference point,
868
                 * 6 deltas for the two curves, fd, final point, 3, 0.
869
                 */
870
171
                csp[-18] += csp[-16], csp[-17] += csp[-15];
871
171
                memmove(csp - 16, csp - 14, sizeof(*csp) * 11);
872
171
                cis.os_count -= 6, csp -= 6;
873
                /*
874
                 * We could optimize by using [h]flex[1],
875
                 * but it isn't worth the trouble.
876
                 */
877
171
                c = CE_OFFSET + ce2_flex;
878
171
                cis.flex_count = flex_max; /* not inside flex */
879
171
                cis.ignore_pops = 2;
880
171
                goto copy;
881
171
            case 1:
882
171
                cis.flex_count = 0;
883
171
                cis.os_count -= 2;
884
171
                continue;
885
            /*case 2:*/   /* detected in *moveto */
886
467k
            case 3:
887
467k
                memset(active_hints, 0, hintmask_size);
888
467k
                HINTS_CHANGED();
889
467k
                cis.ignore_pops = 1;
890
467k
                cis.os_count -= 2;
891
467k
                continue;
892
0
            case 12:
893
0
            case 13:
894
                /* Counter control is not implemented. */
895
0
                if (fixed2int(csp[-1]) < 0)
896
0
                    return_error(gs_error_invalidfont);
897
0
                if (cis.os_count < 2 + fixed2int(csp[-1]))
898
0
                    return_error(gs_error_invalidfont);
899
0
                cis.os_count -= 2 + fixed2int(csp[-1]);
900
0
                continue;
901
467k
            }
902
            /*
903
             * The remaining cases are strictly for optimization.
904
             */
905
1.20M
        case cx_rlineto:
906
1.20M
            if (cis.os_count < 2)
907
1
                return_error(gs_error_invalidfont);
908
1.20M
            if (depth > MAX_STACK - 2)
909
591
                goto copy;
910
1.20M
            switch (prev_op) {
911
281k
            case cx_rlineto:  /* rlineto+ => rlineto */
912
281k
                goto put;
913
159k
            case cx_rrcurveto:  /* rrcurveto+ rlineto => rcurveline */
914
159k
                c = c2_rcurveline;
915
159k
                goto put;
916
767k
            default:
917
767k
                goto copy;
918
1.20M
            }
919
2.21M
        case cx_hlineto:  /* hlineto (vlineto hlineto)* [vlineto] => hlineto */
920
2.21M
            if (cis.os_count < 1)
921
0
                return_error(gs_error_invalidfont);
922
2.21M
            if (depth > MAX_STACK - 1 ||
923
2.21M
                prev_op != (depth & 1 ? cx_vlineto : cx_hlineto))
924
1.14M
                goto copy;
925
1.06M
            c = prev_op;
926
1.06M
            goto put;
927
2.06M
        case cx_vlineto:  /* vlineto (hlineto vlineto)* [hlineto] => vlineto */
928
2.06M
            if (cis.os_count < 1)
929
0
                return_error(gs_error_invalidfont);
930
2.06M
            if (depth > MAX_STACK - 1 ||
931
2.06M
                prev_op != (depth & 1 ? cx_hlineto : cx_vlineto))
932
1.01M
                goto copy;
933
1.04M
            c = prev_op;
934
1.04M
            goto put;
935
1.26M
        case cx_hvcurveto: /* hvcurveto (vhcurveto hvcurveto)* => hvcurveto */
936
                                /* (vhcurveto hvcurveto)+ => vhcurveto  */
937
1.26M
            if (cis.os_count < 4)
938
1
                return_error(gs_error_invalidfont);
939
            /*
940
             * We have to check (depth & 1) because the last curve might
941
             * have 5 parameters rather than 4 (see rrcurveto below).
942
             */
943
1.26M
            if ((depth & 1) || depth > MAX_STACK - 4 ||
944
1.11M
                prev_op != (depth & 4 ? cx_vhcurveto : cx_hvcurveto))
945
862k
                goto copy;
946
400k
            c = prev_op;
947
400k
            goto put;
948
1.31M
        case cx_vhcurveto: /* vhcurveto (hvcurveto vhcurveto)* => vhcurveto */
949
                                /* (hvcurveto vhcurveto)+ => hvcurveto  */
950
1.31M
            if (cis.os_count < 4)
951
0
                return_error(gs_error_invalidfont);
952
            /* See above re the (depth & 1) check. */
953
1.31M
            if ((depth & 1) || depth > MAX_STACK - 4 ||
954
1.11M
                prev_op != (depth & 4 ? cx_hvcurveto : cx_vhcurveto))
955
606k
                goto copy;
956
709k
            c = prev_op;
957
709k
            goto put;
958
3.92M
        case cx_rrcurveto:
959
3.92M
            if (cis.os_count < 6)
960
0
                return_error(gs_error_invalidfont);
961
3.92M
            if (depth == 0) {
962
191k
                if (csp[-1] == 0) {
963
                    /* A|0 B C D 0 F rrcurveto => [A] B C D F vvcurveto */
964
37.4k
                    c = c2_vvcurveto;
965
37.4k
                    csp[-1] = csp[0];
966
37.4k
                    if (csp[-5] == 0) {
967
0
                        memmove(csp - 5, csp - 4, sizeof(*csp) * 4);
968
0
                        POP(2);
969
0
                    } else
970
37.4k
                        POP(1);
971
154k
                } else if (*csp == 0) {
972
                    /* A B|0 C D E 0 rrcurveto => [B] A C D E hhcurveto */
973
82.6k
                    c = c2_hhcurveto;
974
82.6k
                    if (csp[-4] == 0) {
975
0
                        memmove(csp - 4, csp - 3, sizeof(*csp) * 3);
976
0
                        POP(2);
977
82.6k
                    } else {
978
82.6k
                        *csp = csp[-5], csp[-5] = csp[-4], csp[-4] = *csp;
979
82.6k
                        POP(1);
980
82.6k
                    }
981
82.6k
                }
982
                /*
983
                 * We could also optimize:
984
                 *   0 B C D E F|0 rrcurveto => B C D E [F] vhcurveto
985
                 *   A 0 C D E|0 F rrcurveto => A C D F [E] hvcurveto
986
                 * but this gets in the way of subsequent optimization
987
                 * of multiple rrcurvetos, so we don't do it.
988
                 */
989
191k
                goto copy;
990
191k
            }
991
3.73M
            if (depth > MAX_STACK - 6)
992
1.95k
                goto copy;
993
3.73M
            switch (prev_op) {
994
36.6k
            case c2_hhcurveto:  /* hrcurveto (x1 0 x2 y2 x3 0 rrcurveto)* => */
995
                                /* hhcurveto */
996
36.6k
                if (csp[-4] == 0 && *csp == 0) {
997
0
                    memmove(csp - 4, csp - 3, sizeof(*csp) * 3);
998
0
                    c = prev_op;
999
0
                    POP(2);
1000
0
                    goto put;
1001
0
                }
1002
36.6k
                goto copy;
1003
36.6k
            case c2_vvcurveto:  /* rvcurveto (0 y1 x2 y2 0 y3 rrcurveto)* => */
1004
                                /* vvcurveto */
1005
12.6k
                if (csp[-5] == 0 && csp[-1] == 0) {
1006
0
                    memmove(csp - 5, csp - 4, sizeof(*csp) * 3);
1007
0
                    csp[-2] = *csp;
1008
0
                    c = prev_op;
1009
0
                    POP(2);
1010
0
                    goto put;
1011
0
                }
1012
12.6k
                goto copy;
1013
574k
            case cx_hvcurveto:
1014
574k
                if (depth & 1)
1015
154k
                    goto copy;
1016
419k
                if (!(depth & 4))
1017
195k
                    goto hrc;
1018
276k
            vrc:  /* (vhcurveto hvcurveto)+ vrcurveto => vhcurveto */
1019
                /* hvcurveto (vhcurveto hvcurveto)* vrcurveto => hvcurveto */
1020
276k
                if (csp[-5] != 0)
1021
1.75k
                    goto copy;
1022
275k
                memmove(csp - 5, csp - 4, sizeof(*csp) * 5);
1023
275k
                c = prev_op;
1024
275k
                POP(1);
1025
275k
                goto put;
1026
571k
            case cx_vhcurveto:
1027
571k
                if (depth & 1)
1028
185k
                    goto copy;
1029
386k
                if (!(depth & 4))
1030
52.7k
                    goto vrc;
1031
529k
            hrc:  /* (hvcurveto vhcurveto)+ hrcurveto => hvcurveto */
1032
                /* vhcurveto (hvcurveto vhcurveto)* hrcurveto => vhcurveto */
1033
529k
                if (csp[-4] != 0)
1034
5.76k
                    goto copy;
1035
                /* A 0 C D E F => A C D F E */
1036
523k
                memmove(csp - 4, csp - 3, sizeof(*csp) * 2);
1037
523k
                csp[-2] = *csp;
1038
523k
                c = prev_op;
1039
523k
                POP(1);
1040
523k
                goto put;
1041
247k
            case cx_rlineto:  /* rlineto+ rrcurveto => rlinecurve */
1042
247k
                c = c2_rlinecurve;
1043
247k
                goto put;
1044
1.11M
            case cx_rrcurveto:  /* rrcurveto+ => rrcurveto */
1045
1.11M
                goto put;
1046
1.17M
            default:
1047
1.17M
                goto copy;
1048
3.73M
            }
1049
21.9M
        }
1050
21.9M
    }
1051
1.01M
}