Coverage Report

Created: 2026-07-24 07:44

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
22.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
8.41M
{
63
8.41M
    int skip = pcis->pfont->data.lenIV;
64
8.41M
    ip_state_t *ipsp = &pcis->ipstack[pcis->ips_count - 1];
65
8.41M
    const byte *cip = ipsp->cs_data.bits.data;
66
8.41M
    crypt_state state = crypt_charstring_seed;
67
68
42.0M
    for (; skip > 0; ++cip, --skip)
69
33.6M
        decrypt_skip_next(*cip, state);
70
8.41M
    ipsp->ip = cip;
71
8.41M
    ipsp->dstate = state;
72
8.41M
}
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
4.33M
{
84
4.33M
    gs_type1_interp_init(pcis, NULL, NULL, NULL, NULL, false, 0, pfont);
85
4.33M
    pcis->flex_count = flex_max;
86
4.33M
    pcis->ipstack[0].cs_data = *pgd;
87
4.33M
    skip_iv(pcis);
88
4.33M
}
89
90
/* Clear the Type 1 operand stack. */
91
static inline void
92
type1_clear(gs_type1_state *pcis)
93
81.0M
{
94
81.0M
    pcis->os_count = 0;
95
81.0M
}
96
97
/* Execute a callsubr. */
98
static int
99
type1_callsubr(gs_type1_state *pcis, int index)
100
4.07M
{
101
4.07M
    gs_font_type1 *pfont = pcis->pfont;
102
4.07M
    ip_state_t *ipsp1 = &pcis->ipstack[pcis->ips_count];
103
4.07M
    int code = pfont->data.procs.subr_data(pfont, index, false,
104
4.07M
                                           &ipsp1->cs_data);
105
106
4.07M
    if (code < 0)
107
5
        return_error(code);
108
4.07M
    pcis->ips_count++;
109
4.07M
    skip_iv(pcis);
110
4.07M
    return code;
111
4.07M
}
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
20.6M
{
118
20.6M
    fixed v0 = pv[0] + lsb, v1 = v0 + pv[1];
119
20.6M
    cv_stem_hint *bot = &psht->data[0];
120
20.6M
    cv_stem_hint *orig_top = bot + psht->count;
121
20.6M
    cv_stem_hint *top = orig_top;
122
123
20.6M
    if (psht->count >= max_total_stem_hints)
124
0
        return_error(gs_error_limitcheck);
125
31.7M
    while (top > bot &&
126
27.7M
           (v0 < top[-1].v0 || (v0 == top[-1].v0 && v1 < top[-1].v1))
127
20.6M
           ) {
128
11.0M
        *top = top[-1];
129
11.0M
        top--;
130
11.0M
    }
131
20.6M
    if (top > bot && v0 == top[-1].v0 && v1 == top[-1].v1) {
132
        /* Duplicate hint, don't add it. */
133
12.9M
        memmove(top, top + 1, (char *)orig_top - (char *)top);
134
12.9M
        if (active_hints) {
135
10.3M
            uint index = top[-1].index;
136
137
10.3M
            active_hints[index >> 3] |= 0x80 >> (index & 7);
138
10.3M
        }
139
12.9M
        return 0;
140
12.9M
    }
141
7.72M
    top->v0 = v0;
142
7.72M
    top->v1 = v1;
143
7.72M
    psht->count++;
144
7.72M
    return 0;
145
20.6M
}
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
11.9k
{
150
11.9k
    int code = 0;
151
11.9k
    if (type1_stem1(pcis, psht, pv3, lsb, active_hints) < 0)
152
0
        return code;
153
11.9k
    if (type1_stem1(pcis, psht, pv3 + 2, lsb, active_hints) < 0)
154
0
        return code;
155
11.9k
    if (type1_stem1(pcis, psht, pv3 + 4, lsb, active_hints) < 0)
156
0
        return code;
157
11.9k
    return 0;
158
11.9k
}
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
92.3M
{
167
92.3M
    ip_state_t *ipsp = &pcis->ipstack[pcis->ips_count - 1];
168
92.3M
    const byte *cip, *cipe;
169
92.3M
    crypt_state state;
170
92.3M
#define CLEAR (csp = pcis->ostack - 1)
171
92.3M
    fixed *csp = (&pcis->ostack[pcis->os_count]) - 1;
172
92.3M
    const bool encrypted = pcis->pfont->data.lenIV >= 0;
173
92.3M
    int c, code, num_results, c0;
174
175
100M
 load:
176
100M
    cip = ipsp->ip;
177
100M
    cipe = ipsp->cs_data.bits.data + ipsp->cs_data.bits.size;
178
100M
    state = ipsp->dstate;
179
335M
    for (;;) {
180
335M
        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
439
            return_error(gs_error_unknownerror);
187
335M
        c0 = *cip++;
188
335M
        charstring_next(c0, state, c, encrypted);
189
335M
        if (c >= c_num1) {
190
            /* This is a number, decode it and push it on the stack. */
191
232M
            if (c < c_pos2_0) { /* 1-byte number */
192
179M
                decode_push_num1(csp, pcis->ostack, c);
193
179M
            } else if (c < cx_num4) { /* 2-byte number */
194
53.1M
                decode_push_num2(csp, pcis->ostack, c, cip, state, encrypted);
195
53.1M
            } else if (c == cx_num4) { /* 4-byte number */
196
60.2k
                long lw;
197
198
60.2k
                decode_num4(lw, cip, state, encrypted);
199
60.2k
                CS_CHECK_PUSH(csp, pcis->ostack);
200
60.2k
                *++csp = int2fixed(lw);
201
60.2k
                if (lw != fixed2long(*csp)) {
202
                    /*
203
                     * The integer was too large to handle in fixed point.
204
                     * Handle this case specially.
205
                     */
206
13
                    code = gs_type1_check_float(&state, encrypted, &cip, csp, lw);
207
13
                    if (code < 0)
208
13
                       return code;
209
13
                }
210
60.2k
            } else   /* not possible */
211
0
                return_error(gs_error_invalidfont);
212
232M
            continue;
213
232M
        }
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
102M
        switch ((char_command) c) {
231
90.3M
        default:
232
90.3M
            break;
233
90.3M
        case c_undef0:
234
24
        case c_undef2:
235
38
        case c_undef17:
236
38
            return_error(gs_error_invalidfont);
237
4.07M
        case c_callsubr:
238
4.07M
            if (csp + 1 - &pcis->ostack[0] < 1)
239
3
                return_error(gs_error_invalidfont);
240
4.07M
            code = type1_callsubr(pcis, fixed2int_var(*csp) +
241
4.07M
                                  pcis->pfont->data.subroutineNumberBias);
242
4.07M
            if (code < 0)
243
5
                return_error(code);
244
4.07M
            ipsp->ip = cip, ipsp->dstate = state;
245
4.07M
            --csp;
246
4.07M
            ++ipsp;
247
4.07M
            goto load;
248
4.07M
        case c_return:
249
4.07M
            if (pcis->ips_count > 1) {
250
4.07M
                gs_glyph_data_free(&ipsp->cs_data, "type1_next");
251
4.07M
                pcis->ips_count--;
252
4.07M
                --ipsp;
253
4.07M
            } else
254
13
                return_error(gs_error_invalidfont);
255
4.07M
            goto load;
256
4.07M
        case c_undoc15:
257
            /* See gstype1.h for information on this opcode. */
258
61
            CLEAR;
259
61
            continue;
260
4.04M
        case cx_escape:
261
4.04M
            charstring_next(*cip, state, c, encrypted);
262
4.04M
            ++cip;
263
4.04M
            switch ((char1_extended_command) c) {
264
15.6k
            default:
265
15.6k
                c += CE_OFFSET;
266
15.6k
                break;
267
45.8k
            case ce1_div:
268
45.8k
                if (csp + 1 - &pcis->ostack[0] < 1)
269
0
                    return_error(gs_error_invalidfont);
270
45.8k
                csp[-1] = float2fixed((double)csp[-1] / (double)*csp);
271
45.8k
                --csp;
272
45.8k
                continue;
273
0
            case ce1_undoc15: /* see gstype1.h */
274
0
                CLEAR;
275
0
                continue;
276
2.00M
            case ce1_callothersubr:
277
2.00M
                if (csp + 1 - &pcis->ostack[0] < 2)
278
0
                    return_error(gs_error_invalidfont);
279
2.00M
                switch (fixed2int_var(*csp)) {
280
3.57k
                case 0:
281
3.57k
                    pcis->ignore_pops = 2;
282
3.57k
                    break; /* pass to caller */
283
1.97M
                case 3:
284
1.97M
                    pcis->ignore_pops = 1;
285
1.97M
                    break; /* pass to caller */
286
0
                case 14:
287
0
                    num_results = 1; goto blend;
288
0
                case 15:
289
0
                    num_results = 2; goto blend;
290
0
                case 16:
291
0
                    num_results = 3; goto blend;
292
0
                case 17:
293
0
                    num_results = 4; goto blend;
294
0
                case 18:
295
0
                    num_results = 6;
296
0
                blend:
297
0
                    CS_CHECK_POP(csp, pcis->ostack);
298
0
                    if (!CS_CHECK_CSTACK_BOUNDS(&csp[-1 - fixed2int_var(csp[-1])], pcis->ostack))
299
0
                        return_error(gs_error_invalidfont);
300
301
0
                    code = gs_type1_blend(pcis, csp, num_results);
302
0
                    if (code < 0)
303
0
                        return code;
304
0
                    csp -= code;
305
0
                    continue;
306
28.5k
                default:
307
28.5k
                    break; /* pass to caller */
308
2.00M
                }
309
2.00M
                break;
310
2.00M
            case ce1_pop:
311
1.97M
                if (pcis->ignore_pops != 0) {
312
1.97M
                    pcis->ignore_pops--;
313
1.97M
                    continue;
314
1.97M
                }
315
4.04M
                return_error(gs_error_rangecheck);
316
4.04M
            }
317
2.02M
            break;
318
102M
        }
319
92.3M
        break;
320
102M
    }
321
92.3M
    ipsp->ip = cip, ipsp->dstate = state;
322
92.3M
    pcis->ips_count = ipsp + 1 - &pcis->ipstack[0];
323
92.3M
    pcis->os_count = csp + 1 - &pcis->ostack[0];
324
92.3M
    return c;
325
100M
}
326
327
/* ------ Output ------ */
328
329
/* Put 2 or 4 bytes on a stream (big-endian). */
330
static void
331
sputc2(stream *s, int i)
332
24.7M
{
333
24.7M
    sputc(s, (byte)(i >> 8));
334
24.7M
    sputc(s, (byte)i);
335
24.7M
}
336
static void
337
sputc4(stream *s, int i)
338
22.8k
{
339
22.8k
    sputc2(s, i >> 16);
340
22.8k
    sputc2(s, i);
341
22.8k
}
342
343
/* Put a Type 2 operator on a stream. */
344
static void
345
type2_put_op(stream *s, int op)
346
22.9M
{
347
22.9M
    if (op >= CE_OFFSET) {
348
1.78k
        spputc(s, cx_escape);
349
1.78k
        spputc(s, (byte)(op - CE_OFFSET));
350
1.78k
    } else
351
22.9M
        sputc(s, (byte)op);
352
22.9M
}
353
354
/* Put a Type 2 number on a stream. */
355
static void
356
type2_put_int(stream *s, int i)
357
103M
{
358
103M
    if (i >= -107 && i <= 107)
359
78.6M
        sputc(s, (byte)(i + 139));
360
24.6M
    else if (i <= 1131 && i >= 0)
361
16.8M
        sputc2(s, (c_pos2_0 << 8) + i - 108);
362
7.77M
    else if (i >= -1131 && i < 0)
363
7.76M
        sputc2(s, (c_neg2_0 << 8) - i - 108);
364
8.02k
    else if (i >= -32768 && i <= 32767) {
365
8.02k
        spputc(s, c2_shortint);
366
8.02k
        sputc2(s, i);
367
8.02k
    } else {
368
        /*
369
         * We can't represent this number directly: compute it.
370
         * (This can be done much more efficiently in particular cases;
371
         * we'll do this if it ever seems worthwhile.)
372
         */
373
0
        type2_put_int(s, i >> 10);
374
0
        type2_put_int(s, 1024);
375
0
        type2_put_op(s, CE_OFFSET + ce2_mul);
376
0
        type2_put_int(s, i & 1023);
377
0
        type2_put_op(s, CE_OFFSET + ce2_add);
378
0
    }
379
103M
}
380
381
/* Put a fixed value on a stream. */
382
static void
383
type2_put_fixed(stream *s, fixed v)
384
103M
{
385
103M
    if (fixed_is_int(v))
386
103M
        type2_put_int(s, fixed2int_var(v));
387
22.8k
    else if (v >= int2fixed(-32768) && v < int2fixed(32768)) {
388
        /* We can represent this as a 16:16 number. */
389
22.8k
        spputc(s, cx_num4);
390
22.8k
        sputc4(s, v << (16 - _fixed_shift));
391
22.8k
    } else {
392
0
        type2_put_int(s, fixed2int_var(v));
393
0
        type2_put_fixed(s, fixed_fraction(v));
394
0
        type2_put_op(s, CE_OFFSET + ce2_add);
395
0
    }
396
103M
}
397
398
/* Put a stem hint table on a stream. */
399
static void
400
type2_put_stems(stream *s, int os_count, const cv_stem_hint_table *psht, int op)
401
3.64M
{
402
3.64M
    fixed prev = 0;
403
3.64M
    int pushed = os_count;
404
3.64M
    int i;
405
406
11.3M
    for (i = 0; i < psht->count; ++i, pushed += 2) {
407
7.72M
        fixed v0 = psht->data[i].v0;
408
7.72M
        fixed v1 = psht->data[i].v1;
409
410
7.72M
        if (pushed > ostack_size - 2) {
411
0
            type2_put_op(s, op);
412
0
            pushed = 0;
413
0
        }
414
7.72M
        type2_put_fixed(s, v0 - prev);
415
7.72M
        type2_put_fixed(s, v1 - v0);
416
7.72M
        prev = v1;
417
7.72M
    }
418
3.64M
    type2_put_op(s, op);
419
3.64M
}
420
421
/* Put out a hintmask command. */
422
static void
423
type2_put_hintmask(stream *s, const byte *mask, uint size)
424
1.48M
{
425
1.48M
    uint ignore;
426
427
1.48M
    type2_put_op(s, c2_hintmask);
428
1.48M
    sputs(s, mask, size, &ignore);
429
1.48M
}
430
431
/* ------ Main program ------ */
432
433
/*
434
 * Convert a Type 1 Charstring to (unencrypted) Type 2.
435
 * For simplicity, we expand all Subrs in-line.
436
 * We still need to optimize the output using these patterns:
437
 *  (vhcurveto hvcurveto)* (vhcurveto hrcurveto | vrcurveto) =>
438
 *    vhcurveto
439
 *  (hvcurveto vhcurveto)* (hvcurveto vrcurveto | hrcurveto) =>
440
 *    hvcurveto
441
 */
442
23.7M
#define MAX_STACK ostack_size
443
int
444
psf_convert_type1_to_type2(stream *s, const gs_glyph_data_t *pgd,
445
                           gs_font_type1 *pfont)
446
2.16M
{
447
2.16M
    gs_type1_state cis;
448
2.16M
    cv_stem_hint_table hstem_hints; /* horizontal stem hints */
449
2.16M
    cv_stem_hint_table vstem_hints; /* vertical stem hints */
450
2.16M
    bool first = true;
451
2.16M
    bool need_moveto = true;
452
2.16M
    bool replace_hints = false;
453
2.16M
    bool hints_changed = false;
454
2.16M
    bool width_on_stack = false;
455
2.16M
    enum {
456
2.16M
        dotsection_in = 0,
457
2.16M
        dotsection_out = -1
458
2.16M
    } dotsection_flag = dotsection_out;
459
2.16M
    byte active_hints[(max_total_stem_hints + 7) / 8];
460
2.16M
    byte dot_save_hints[(max_total_stem_hints + 7) / 8];
461
2.16M
    uint hintmask_size;
462
2.16M
#define HINTS_CHANGED()\
463
11.3M
  BEGIN\
464
11.3M
    hints_changed = replace_hints;\
465
11.3M
    if (hints_changed)\
466
11.3M
        CHECK_OP();   /* see below */\
467
11.3M
  END
468
2.16M
#define CHECK_HINTS_CHANGED()\
469
18.4M
  BEGIN\
470
18.4M
    if (hints_changed) {\
471
1.48M
        type2_put_hintmask(s, active_hints, hintmask_size);\
472
1.48M
        hints_changed = false;\
473
1.48M
    }\
474
18.4M
  END
475
    /*
476
     * In order to combine Type 1 operators, we usually delay writing
477
     * out operators (but not their operands).  We must keep track of
478
     * the stack depth so we don't exceed it when combining operators.
479
     */
480
2.16M
    int depth;      /* of operands on stack */
481
2.16M
    int prev_op;    /* operator to write, -1 if none */
482
2.16M
    int code = 0;
483
2.16M
#define CLEAR_OP()\
484
17.8M
  (depth = 0, prev_op = -1)
485
2.16M
#define CHECK_OP()\
486
32.6M
  BEGIN\
487
32.6M
    if (prev_op >= 0) {\
488
15.6M
        type2_put_op(s, prev_op);\
489
15.6M
        CLEAR_OP();\
490
15.6M
    }\
491
32.6M
  END
492
2.16M
    fixed mx0 = 0, my0 = 0; /* See ce1_setcurrentpoint. */
493
494
    /* Really this is to silence Coverity, but it makes sense and we do it a lot so no penatly */
495
2.16M
    memset(active_hints, 0, (max_total_stem_hints + 7) / 8);
496
497
    /* In case we do not get an sbw or hsbw op */
498
2.16M
    cis.lsb.x = cis.lsb.y = cis.width.x = cis.width.y = fixed_0;
499
500
    /*
501
     * Do a first pass to collect hints.  Note that we must also process
502
     * [h]sbw, because the hint coordinates are relative to the lsb.
503
     */
504
2.16M
    hstem_hints.count = hstem_hints.replaced_count = hstem_hints.current = 0;
505
2.16M
    vstem_hints.count = vstem_hints.replaced_count = vstem_hints.current = 0;
506
2.16M
    type1_next_init(&cis, pgd, pfont);
507
46.1M
    for (;;) {
508
46.1M
        int c = type1_next(&cis);
509
46.1M
        fixed *csp = (&cis.ostack[cis.os_count]) - 1;
510
511
46.1M
        switch (c) {
512
30.5M
        default:
513
             /* We used to treat buffer overrun as a simple invalid font, now we assume that
514
             * there is an implicit endchar, this is handled by looking for a specific error.
515
             * Part of bug #693170 where the fonts are invalid (no endchar on some glyphs).
516
             */
517
30.5M
           if (c == gs_error_unknownerror)
518
223
                break;
519
30.5M
            if (c < 0)
520
72
                return c;
521
30.5M
            type1_clear(&cis);
522
30.5M
            continue;
523
2.16M
        case c1_hsbw:
524
2.16M
            if (cis.os_count < 2)
525
4
                return_error(gs_error_invalidfont);
526
2.16M
            gs_type1_sbw(&cis, cis.ostack[0], fixed_0, cis.ostack[1], fixed_0);
527
2.16M
            goto clear;
528
6.10M
        case cx_hstem:
529
6.10M
            if (cis.os_count < 2)
530
2
                return_error(gs_error_invalidfont);
531
6.10M
            code = type1_stem1(&cis, &hstem_hints, csp - 1, cis.lsb.y, NULL);
532
6.10M
            if (code < 0)
533
0
                return code;
534
6.10M
            goto clear;
535
6.10M
        case cx_vstem:
536
4.20M
            if (cis.os_count < 2)
537
2
                return_error(gs_error_invalidfont);
538
4.20M
            code = type1_stem1(&cis, &vstem_hints, csp - 1, cis.lsb.x, NULL);
539
4.20M
            if (code < 0)
540
0
                return code;
541
4.20M
            goto clear;
542
4.20M
        case CE_OFFSET + ce1_sbw:
543
0
            if (cis.os_count < 4)
544
0
                return_error(gs_error_invalidfont);
545
0
            gs_type1_sbw(&cis, cis.ostack[0], cis.ostack[1],
546
0
                         cis.ostack[2], cis.ostack[3]);
547
0
            goto clear;
548
5.96k
        case CE_OFFSET + ce1_vstem3:
549
5.96k
            if (cis.os_count < 6)
550
0
                return_error(gs_error_invalidfont);
551
5.96k
            code = type1_stem3(&cis, &vstem_hints, csp - 5, cis.lsb.x, NULL);
552
5.96k
            if (code < 0)
553
0
                return code;
554
5.96k
            goto clear;
555
5.96k
        case CE_OFFSET + ce1_hstem3:
556
9
            if (cis.os_count < 6)
557
0
                return_error(gs_error_invalidfont);
558
9
            code = type1_stem3(&cis, &hstem_hints, csp - 5, cis.lsb.y, NULL);
559
9
            if (code < 0)
560
0
                return code;
561
12.4M
        clear:
562
12.4M
            type1_clear(&cis);
563
12.4M
            continue;
564
1.00M
        case ce1_callothersubr:
565
1.00M
            if (cis.os_count < 2)
566
1
                return_error(gs_error_invalidfont);
567
1.00M
            if (*csp == int2fixed(3))
568
986k
                replace_hints = true;
569
1.00M
            if (fixed2int(csp[-1]) < 0)
570
5
                return_error(gs_error_invalidfont);
571
1.00M
            if (cis.os_count < 2 + fixed2int(csp[-1]))
572
4
                return_error(gs_error_invalidfont);
573
1.00M
            if (*csp == int2fixed(12) || *csp == int2fixed(13))
574
0
                cis.os_count -= fixed2int(csp[-1]);
575
1.00M
            cis.os_count -= 2;
576
1.00M
            continue;
577
90
        case CE_OFFSET + ce1_dotsection:
578
90
            replace_hints = true;
579
90
            continue;
580
0
        case CE_OFFSET + ce1_seac:
581
0
            if (cis.os_count < 5)
582
0
                return_error(gs_error_invalidfont);
583
2.16M
        case cx_endchar:
584
2.16M
            break;
585
46.1M
        }
586
2.16M
        break;
587
46.1M
    }
588
    /*
589
     * Number the hints for hintmask.  We must do this even if we never
590
     * replace hints, because type1_stem# uses the index to set bits in
591
     * active_hints.
592
     */
593
2.16M
    {
594
2.16M
        int i;
595
596
6.96M
        for (i = 0; i < hstem_hints.count; ++i)
597
4.79M
            hstem_hints.data[i].index = i;
598
5.10M
        for (i = 0; i < vstem_hints.count; ++i)
599
2.93M
            vstem_hints.data[i].index = i + hstem_hints.count;
600
2.16M
    }
601
2.16M
    if (replace_hints) {
602
495k
        hintmask_size =
603
495k
            (hstem_hints.count + vstem_hints.count + 7) / 8;
604
495k
        if (hintmask_size > (max_total_stem_hints + 7) / 8)
605
0
            return_error(gs_error_invalidfont);
606
495k
        memset(active_hints, 0, hintmask_size);
607
495k
    } else
608
1.67M
        hintmask_size = 0;
609
610
    /* Do a second pass to write the result. */
611
2.16M
    type1_next_init(&cis, pgd, pfont);
612
2.16M
    CLEAR_OP();
613
46.1M
    for (;;) {
614
46.1M
        int c = type1_next(&cis);
615
46.1M
        fixed *csp = (&cis.ostack[cis.os_count]) - 1;
616
46.1M
#define POP(n)\
617
46.1M
  (csp -= (n), cis.os_count -= (n))
618
46.1M
        int i;
619
46.1M
        fixed mx, my;
620
621
46.1M
        if (need_moveto && ((c >= cx_rlineto && c <= cx_rrcurveto) ||
622
14.9M
            c == cx_vhcurveto || c == cx_hvcurveto))
623
45
        {
624
45
            mx = my = 0;
625
45
            need_moveto = false;
626
45
            CHECK_OP();
627
45
            if (first) {
628
9
                if (width_on_stack) {
629
9
                    if (cis.os_count < 1)
630
0
                        return_error(gs_error_invalidfont);
631
9
                    type2_put_fixed(s, *csp); /* width */
632
                    /* We need to move all the stored numeric values up by
633
                     * one in the stack, eliminating the width, so that later
634
                     * processing when we handle the drswing operator emits the correct
635
                     * values. This is different to the 'move' case below.
636
                     */
637
9
                    cis.os_count--;
638
54
                    for (i = 0; i < cis.os_count; ++i)
639
45
                        cis.ostack[i] = cis.ostack[i+1];
640
9
                }
641
9
                mx += cis.lsb.x + mx0, my += cis.lsb.y + my0;
642
9
                first = false;
643
9
            }
644
45
            CHECK_HINTS_CHANGED();
645
45
            if (mx == 0) {
646
36
                type2_put_fixed(s, my);
647
36
                depth = 1, prev_op = cx_vmoveto;
648
36
            } else if (my == 0) {
649
9
                type2_put_fixed(s, mx);
650
9
                depth = 1, prev_op = cx_hmoveto;
651
9
            } else {
652
0
                type2_put_fixed(s, mx);
653
0
                type2_put_fixed(s, my);
654
0
                depth = 2, prev_op = cx_rmoveto;
655
0
            }
656
45
        }
657
658
46.1M
        switch (c) {
659
448
        default:
660
             /* We used to treat buffer overrun as a simple invalid font, now we assume that
661
             * there is an implicit endchar, this is handled by looking for a specific error.
662
             * Part of bug #693170 where the fonts are invalid (no endchar on some glyphs).
663
             */
664
448
            if (c == gs_error_unknownerror) {
665
216
                type2_put_op(s, cx_endchar);
666
216
                return 0;
667
216
            }
668
232
            if (c < 0)
669
0
                return c;
670
232
            if (c >= CE_OFFSET)
671
2
                return_error(gs_error_rangecheck);
672
            /* The Type 1 use of all other operators is the same in Type 2. */
673
12.8M
        copy:
674
12.8M
            CHECK_OP();
675
12.8M
            CHECK_HINTS_CHANGED();
676
24.8M
        put:
677
105M
            for (i = 0; i < cis.os_count; ++i)
678
80.4M
                type2_put_fixed(s, cis.ostack[i]);
679
24.8M
            depth += cis.os_count;
680
24.8M
            prev_op = c;
681
24.8M
            type1_clear(&cis);
682
24.8M
            continue;
683
6.10M
        case cx_hstem:
684
6.10M
            if (cis.os_count < 2)
685
0
                return_error(gs_error_invalidfont);
686
6.10M
            code = type1_stem1(&cis, &hstem_hints, csp - 1, cis.lsb.y, active_hints);
687
6.10M
            if (code < 0)
688
0
                return code;
689
10.3M
        hint:
690
10.3M
            HINTS_CHANGED();
691
10.3M
            type1_clear(&cis);
692
10.3M
            continue;
693
4.20M
        case cx_vstem:
694
4.20M
            if (cis.os_count < 2)
695
0
                return_error(gs_error_invalidfont);
696
4.20M
            code = type1_stem1(&cis, &vstem_hints, csp - 1, cis.lsb.x, active_hints);
697
4.20M
            if (code < 0)
698
0
                return code;
699
4.20M
            goto hint;
700
4.20M
        case CE_OFFSET + ce1_vstem3:
701
5.95k
            if (cis.os_count < 6)
702
0
                return_error(gs_error_invalidfont);
703
5.95k
            code = type1_stem3(&cis, &vstem_hints, csp - 5, cis.lsb.x, active_hints);
704
5.95k
            if (code < 0)
705
0
                return code;
706
5.95k
            goto hint;
707
5.95k
        case CE_OFFSET + ce1_hstem3:
708
9
            if (cis.os_count < 6)
709
0
                return_error(gs_error_invalidfont);
710
9
            code = type1_stem3(&cis, &hstem_hints, csp - 5, cis.lsb.y, active_hints);
711
9
            if (code < 0)
712
0
                return code;
713
9
            goto hint;
714
90
        case CE_OFFSET + ce1_dotsection:
715
90
            if (dotsection_flag == dotsection_out) {
716
54
                memcpy(dot_save_hints, active_hints, hintmask_size);
717
54
                memset(active_hints, 0, hintmask_size);
718
54
                dotsection_flag = dotsection_in;
719
54
            } else {
720
36
                memcpy(active_hints, dot_save_hints, hintmask_size);
721
36
                dotsection_flag = dotsection_out;
722
36
            }
723
90
            HINTS_CHANGED();
724
90
            continue;
725
2.82M
        case c1_closepath:
726
2.82M
            need_moveto = true;
727
2.82M
            continue;
728
1.78k
        case CE_OFFSET + ce1_setcurrentpoint:
729
1.78k
            if (first) {
730
0
                if (cis.os_count < 2)
731
0
                    return_error(gs_error_invalidfont);
732
733
                /*  A workaround for fonts which use ce1_setcurrentpoint
734
                    in an illegal way for shifting a path.
735
                    See t1_hinter__setcurrentpoint for more information. */
736
0
                mx0 = csp[-1], my0 = *csp;
737
0
            }
738
1.78k
            continue;
739
485k
        case cx_vmoveto:
740
485k
            if (cis.os_count < 1)
741
0
                return_error(gs_error_invalidfont);
742
485k
            mx = 0, my = *csp;
743
485k
            POP(1); goto move;
744
138k
        case cx_hmoveto:
745
138k
            if (cis.os_count < 1)
746
1
                return_error(gs_error_invalidfont);
747
138k
            mx = *csp, my = 0;
748
138k
            POP(1); goto move;
749
2.21M
        case cx_rmoveto:
750
2.21M
            if (cis.os_count < 2)
751
0
                return_error(gs_error_invalidfont);
752
2.21M
            mx = csp[-1], my = *csp;
753
2.21M
            POP(2);
754
2.84M
        move:
755
2.84M
            need_moveto = false;
756
2.84M
            CHECK_OP();
757
2.84M
            if (first) {
758
2.01M
                if (cis.os_count)
759
13.8k
                    type2_put_fixed(s, *csp); /* width */
760
2.01M
                mx += cis.lsb.x + mx0, my += cis.lsb.y + my0;
761
2.01M
                first = false;
762
2.01M
            }
763
2.84M
            if (cis.flex_count != flex_max) {
764
                /* We're accumulating points for a flex. */
765
12.5k
                if (type1_next(&cis) != ce1_callothersubr)
766
0
                    return_error(gs_error_rangecheck);
767
12.5k
                csp = &cis.ostack[cis.os_count - 1];
768
12.5k
                if (*csp != int2fixed(2) || csp[-1] != fixed_0)
769
0
                    return_error(gs_error_rangecheck);
770
12.5k
                cis.flex_count++;
771
12.5k
                csp[-1] = mx, *csp = my;
772
12.5k
                continue;
773
12.5k
            }
774
2.84M
            CHECK_HINTS_CHANGED();
775
2.82M
            if (mx == 0) {
776
205k
                type2_put_fixed(s, my);
777
205k
                depth = 1, prev_op = cx_vmoveto;
778
2.62M
            } else if (my == 0) {
779
190k
                type2_put_fixed(s, mx);
780
190k
                depth = 1, prev_op = cx_hmoveto;
781
2.43M
            } else {
782
2.43M
                type2_put_fixed(s, mx);
783
2.43M
                type2_put_fixed(s, my);
784
2.43M
                depth = 2, prev_op = cx_rmoveto;
785
2.43M
            }
786
2.82M
            type1_clear(&cis);
787
2.82M
            continue;
788
2.16M
        case c1_hsbw:
789
2.16M
            if (cis.os_count < 2)
790
0
                return_error(gs_error_invalidfont);
791
2.16M
            gs_type1_sbw(&cis, cis.ostack[0], fixed_0, cis.ostack[1], fixed_0);
792
            /*
793
             * Leave the l.s.b. on the operand stack for the initial hint,
794
             * moveto, or endchar command.
795
             */
796
2.16M
            cis.ostack[0] = cis.ostack[1];
797
2.16M
        sbw:
798
            /* cff_write_Private doesn't write defaultWidthX
799
               when called with the Type 1 font,
800
               so the reader will assume
801
               defaultWidthX = defaultWidthX_DEFAULT
802
               Use the latter here.
803
             */
804
2.16M
            if (cis.ostack[0] == default_defaultWidthX)
805
3.52k
                cis.os_count = 0;
806
2.16M
            else {
807
2.16M
                cis.ostack[0] -= default_defaultWidthX;
808
2.16M
                cis.os_count = 1;
809
2.16M
                width_on_stack = true;
810
2.16M
            }
811
2.16M
            if (hstem_hints.count) {
812
1.97M
                if (cis.os_count)
813
1.97M
                    type2_put_fixed(s, cis.ostack[0]);
814
1.97M
                type2_put_stems(s, cis.os_count, &hstem_hints,
815
1.97M
                                (replace_hints ? c2_hstemhm : cx_hstem));
816
1.97M
                cis.os_count = 0;
817
1.97M
                width_on_stack = false;
818
1.97M
            }
819
2.16M
            if (vstem_hints.count) {
820
1.66M
                if (cis.os_count)
821
18.1k
                    type2_put_fixed(s, cis.ostack[0]);
822
1.66M
                type2_put_stems(s, cis.os_count, &vstem_hints,
823
1.66M
                                (replace_hints ? c2_vstemhm : cx_vstem));
824
1.66M
                cis.os_count = 0;
825
1.66M
                width_on_stack = false;
826
1.66M
            }
827
2.16M
            continue;
828
0
        case CE_OFFSET + ce1_seac:
829
0
            if (cis.os_count < 5)
830
0
                return_error(gs_error_invalidfont);
831
            /*
832
             * It is an undocumented feature of the Type 2 CharString
833
             * format that endchar + 4 or 5 operands is equivalent to
834
             * seac with an implicit asb operand + endchar with 0 or 1
835
             * operands.  Remove the asb argument from the stack, but
836
             * adjust the adx argument to compensate for the fact that
837
             * Type 2 CharStrings don't have any concept of l.s.b.
838
             */
839
0
            csp[-3] += cis.lsb.x - csp[-4];
840
0
            memmove(csp - 4, csp - 3, sizeof(*csp) * 4);
841
0
            POP(1);
842
            /* (falls through) */
843
2.16M
        case cx_endchar:
844
2.16M
            CHECK_OP();
845
2.32M
            for (i = 0; i < cis.os_count; ++i)
846
154k
                type2_put_fixed(s, cis.ostack[i]);
847
2.16M
            type2_put_op(s, cx_endchar);
848
2.16M
            return 0;
849
0
        case CE_OFFSET + ce1_sbw:
850
0
            if (cis.os_count < 4)
851
0
                return_error(gs_error_invalidfont);
852
0
            gs_type1_sbw(&cis, cis.ostack[0], cis.ostack[1],
853
0
                         cis.ostack[2], cis.ostack[3]);
854
0
            cis.ostack[0] = cis.ostack[2];
855
0
            goto sbw;
856
989k
        case ce1_callothersubr:
857
989k
            if (cis.os_count < 2)
858
0
                return_error(gs_error_invalidfont);
859
989k
            CHECK_OP();
860
989k
            switch (fixed2int_var(*csp)) {
861
0
            default:
862
0
                return_error(gs_error_rangecheck);
863
1.78k
            case 0:
864
                /*
865
                 * The operand stack contains: delta to reference point,
866
                 * 6 deltas for the two curves, fd, final point, 3, 0.
867
                 */
868
1.78k
                csp[-18] += csp[-16], csp[-17] += csp[-15];
869
1.78k
                memmove(csp - 16, csp - 14, sizeof(*csp) * 11);
870
1.78k
                cis.os_count -= 6, csp -= 6;
871
                /*
872
                 * We could optimize by using [h]flex[1],
873
                 * but it isn't worth the trouble.
874
                 */
875
1.78k
                c = CE_OFFSET + ce2_flex;
876
1.78k
                cis.flex_count = flex_max; /* not inside flex */
877
1.78k
                cis.ignore_pops = 2;
878
1.78k
                goto copy;
879
1.78k
            case 1:
880
1.78k
                cis.flex_count = 0;
881
1.78k
                cis.os_count -= 2;
882
1.78k
                continue;
883
            /*case 2:*/   /* detected in *moveto */
884
986k
            case 3:
885
986k
                memset(active_hints, 0, hintmask_size);
886
986k
                HINTS_CHANGED();
887
986k
                cis.ignore_pops = 1;
888
986k
                cis.os_count -= 2;
889
986k
                continue;
890
0
            case 12:
891
0
            case 13:
892
                /* Counter control is not implemented. */
893
0
                if (fixed2int(csp[-1]) < 0)
894
0
                    return_error(gs_error_invalidfont);
895
0
                if (cis.os_count < 2 + fixed2int(csp[-1]))
896
0
                    return_error(gs_error_invalidfont);
897
0
                cis.os_count -= 2 + fixed2int(csp[-1]);
898
0
                continue;
899
989k
            }
900
            /*
901
             * The remaining cases are strictly for optimization.
902
             */
903
2.45M
        case cx_rlineto:
904
2.45M
            if (cis.os_count < 2)
905
2
                return_error(gs_error_invalidfont);
906
2.45M
            if (depth > MAX_STACK - 2)
907
983
                goto copy;
908
2.45M
            switch (prev_op) {
909
563k
            case cx_rlineto:  /* rlineto+ => rlineto */
910
563k
                goto put;
911
268k
            case cx_rrcurveto:  /* rrcurveto+ rlineto => rcurveline */
912
268k
                c = c2_rcurveline;
913
268k
                goto put;
914
1.62M
            default:
915
1.62M
                goto copy;
916
2.45M
            }
917
4.84M
        case cx_hlineto:  /* hlineto (vlineto hlineto)* [vlineto] => hlineto */
918
4.84M
            if (cis.os_count < 1)
919
0
                return_error(gs_error_invalidfont);
920
4.84M
            if (depth > MAX_STACK - 1 ||
921
4.84M
                prev_op != (depth & 1 ? cx_vlineto : cx_hlineto))
922
2.50M
                goto copy;
923
2.33M
            c = prev_op;
924
2.33M
            goto put;
925
4.47M
        case cx_vlineto:  /* vlineto (hlineto vlineto)* [hlineto] => vlineto */
926
4.47M
            if (cis.os_count < 1)
927
0
                return_error(gs_error_invalidfont);
928
4.47M
            if (depth > MAX_STACK - 1 ||
929
4.47M
                prev_op != (depth & 1 ? cx_hlineto : cx_vlineto))
930
2.17M
                goto copy;
931
2.29M
            c = prev_op;
932
2.29M
            goto put;
933
2.55M
        case cx_hvcurveto: /* hvcurveto (vhcurveto hvcurveto)* => hvcurveto */
934
                                /* (vhcurveto hvcurveto)+ => vhcurveto  */
935
2.55M
            if (cis.os_count < 4)
936
1
                return_error(gs_error_invalidfont);
937
            /*
938
             * We have to check (depth & 1) because the last curve might
939
             * have 5 parameters rather than 4 (see rrcurveto below).
940
             */
941
2.55M
            if ((depth & 1) || depth > MAX_STACK - 4 ||
942
2.23M
                prev_op != (depth & 4 ? cx_vhcurveto : cx_hvcurveto))
943
1.75M
                goto copy;
944
796k
            c = prev_op;
945
796k
            goto put;
946
2.69M
        case cx_vhcurveto: /* vhcurveto (hvcurveto vhcurveto)* => vhcurveto */
947
                                /* (hvcurveto vhcurveto)+ => hvcurveto  */
948
2.69M
            if (cis.os_count < 4)
949
0
                return_error(gs_error_invalidfont);
950
            /* See above re the (depth & 1) check. */
951
2.69M
            if ((depth & 1) || depth > MAX_STACK - 4 ||
952
2.26M
                prev_op != (depth & 4 ? cx_hvcurveto : cx_vhcurveto))
953
1.24M
                goto copy;
954
1.44M
            c = prev_op;
955
1.44M
            goto put;
956
7.84M
        case cx_rrcurveto:
957
7.84M
            if (cis.os_count < 6)
958
1
                return_error(gs_error_invalidfont);
959
7.84M
            if (depth == 0) {
960
404k
                if (csp[-1] == 0) {
961
                    /* A|0 B C D 0 F rrcurveto => [A] B C D F vvcurveto */
962
75.9k
                    c = c2_vvcurveto;
963
75.9k
                    csp[-1] = csp[0];
964
75.9k
                    if (csp[-5] == 0) {
965
9
                        memmove(csp - 5, csp - 4, sizeof(*csp) * 4);
966
9
                        POP(2);
967
9
                    } else
968
75.9k
                        POP(1);
969
329k
                } else if (*csp == 0) {
970
                    /* A B|0 C D E 0 rrcurveto => [B] A C D E hhcurveto */
971
171k
                    c = c2_hhcurveto;
972
171k
                    if (csp[-4] == 0) {
973
110
                        memmove(csp - 4, csp - 3, sizeof(*csp) * 3);
974
110
                        POP(2);
975
171k
                    } else {
976
171k
                        *csp = csp[-5], csp[-5] = csp[-4], csp[-4] = *csp;
977
171k
                        POP(1);
978
171k
                    }
979
171k
                }
980
                /*
981
                 * We could also optimize:
982
                 *   0 B C D E F|0 rrcurveto => B C D E [F] vhcurveto
983
                 *   A 0 C D E|0 F rrcurveto => A C D F [E] hvcurveto
984
                 * but this gets in the way of subsequent optimization
985
                 * of multiple rrcurvetos, so we don't do it.
986
                 */
987
404k
                goto copy;
988
404k
            }
989
7.43M
            if (depth > MAX_STACK - 6)
990
3.57k
                goto copy;
991
7.43M
            switch (prev_op) {
992
71.8k
            case c2_hhcurveto:  /* hrcurveto (x1 0 x2 y2 x3 0 rrcurveto)* => */
993
                                /* hhcurveto */
994
71.8k
                if (csp[-4] == 0 && *csp == 0) {
995
0
                    memmove(csp - 4, csp - 3, sizeof(*csp) * 3);
996
0
                    c = prev_op;
997
0
                    POP(2);
998
0
                    goto put;
999
0
                }
1000
71.8k
                goto copy;
1001
71.8k
            case c2_vvcurveto:  /* rvcurveto (0 y1 x2 y2 0 y3 rrcurveto)* => */
1002
                                /* vvcurveto */
1003
28.9k
                if (csp[-5] == 0 && csp[-1] == 0) {
1004
0
                    memmove(csp - 5, csp - 4, sizeof(*csp) * 3);
1005
0
                    csp[-2] = *csp;
1006
0
                    c = prev_op;
1007
0
                    POP(2);
1008
0
                    goto put;
1009
0
                }
1010
28.9k
                goto copy;
1011
1.10M
            case cx_hvcurveto:
1012
1.10M
                if (depth & 1)
1013
286k
                    goto copy;
1014
817k
                if (!(depth & 4))
1015
399k
                    goto hrc;
1016
512k
            vrc:  /* (vhcurveto hvcurveto)+ vrcurveto => vhcurveto */
1017
                /* hvcurveto (vhcurveto hvcurveto)* vrcurveto => hvcurveto */
1018
512k
                if (csp[-5] != 0)
1019
2.80k
                    goto copy;
1020
510k
                memmove(csp - 5, csp - 4, sizeof(*csp) * 5);
1021
510k
                c = prev_op;
1022
510k
                POP(1);
1023
510k
                goto put;
1024
1.14M
            case cx_vhcurveto:
1025
1.14M
                if (depth & 1)
1026
365k
                    goto copy;
1027
781k
                if (!(depth & 4))
1028
95.2k
                    goto vrc;
1029
1.08M
            hrc:  /* (hvcurveto vhcurveto)+ hrcurveto => hvcurveto */
1030
                /* vhcurveto (hvcurveto vhcurveto)* hrcurveto => vhcurveto */
1031
1.08M
                if (csp[-4] != 0)
1032
8.88k
                    goto copy;
1033
                /* A 0 C D E F => A C D F E */
1034
1.07M
                memmove(csp - 4, csp - 3, sizeof(*csp) * 2);
1035
1.07M
                csp[-2] = *csp;
1036
1.07M
                c = prev_op;
1037
1.07M
                POP(1);
1038
1.07M
                goto put;
1039
445k
            case cx_rlineto:  /* rlineto+ rrcurveto => rlinecurve */
1040
445k
                c = c2_rlinecurve;
1041
445k
                goto put;
1042
2.28M
            case cx_rrcurveto:  /* rrcurveto+ => rrcurveto */
1043
2.28M
                goto put;
1044
2.35M
            default:
1045
2.35M
                goto copy;
1046
7.43M
            }
1047
46.1M
        }
1048
46.1M
    }
1049
2.16M
}