Coverage Report

Created: 2025-06-24 07:01

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