Coverage Report

Created: 2025-11-16 07:40

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ghostpdl/pdf/pdf_font0.c
Line
Count
Source
1
/* Copyright (C) 2019-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
/* Include this first so that we don't get a macro redefnition of 'offsetof' */
17
#include "pdf_int.h"
18
19
/* code for type 0 (CID) font handling */
20
#include "gxfont.h"
21
#include "gxfont0.h"
22
23
#include "pdf_int.h"
24
#include "pdf_font.h"
25
#include "pdf_font0.h"
26
#include "pdf_font1C.h"
27
#include "pdf_font_types.h"
28
#include "pdf_stack.h"
29
#include "pdf_array.h"
30
#include "pdf_dict.h"
31
#include "pdf_file.h"
32
#include "pdf_cmap.h"
33
#include "pdf_deref.h"
34
35
#include "gsutil.h"        /* For gs_next_ids() */
36
37
static int
38
pdfi_font0_glyph_name(gs_font *pfont, gs_glyph index, gs_const_string *pstr)
39
0
{
40
0
    int code;
41
0
    pdf_font_type0 *pt0font = (pdf_font_type0 *)pfont->client_data;
42
0
    char gnm[64];
43
0
    pdf_context *ctx = pt0font->ctx;
44
0
    uint gindex = 0;
45
46
0
    gs_snprintf(gnm, 64, "%lu", (long)index);
47
0
    code = (*ctx->get_glyph_index)((gs_font *)pfont, (byte *)gnm, strlen(gnm), &gindex);
48
0
    if (code < 0)
49
0
        return code;
50
0
    code = (*ctx->get_glyph_name)(pfont, (gs_glyph)gindex, (gs_const_string *)pstr);
51
52
0
    return code;
53
0
}
54
55
static int
56
pdfi_font0_map_glyph_to_unicode(gs_font *font, gs_glyph glyph, int ch, ushort *u, unsigned int length)
57
1.46M
{
58
1.46M
    gs_glyph cc = glyph < GS_MIN_CID_GLYPH ? glyph : glyph - GS_MIN_CID_GLYPH;
59
1.46M
    pdf_font_type0 *pt0font = (pdf_font_type0 *)font->client_data;
60
1.46M
    int code = gs_error_undefined, i;
61
1.46M
    uchar *unicode_return = (uchar *)u;
62
1.46M
    pdf_cidfont_type2 *decfont = NULL;
63
1.46M
    pdfi_cid_subst_nwp_table_t *substnwp = pt0font->substnwp;
64
65
1.46M
    code = pdfi_array_get(pt0font->ctx, pt0font->DescendantFonts, 0, (pdf_obj **)&decfont);
66
1.46M
    if (code < 0 || pdfi_type_of(decfont) != PDF_FONT) {
67
0
        pdfi_countdown(decfont);
68
0
        return gs_error_undefined;
69
0
    }
70
71
1.46M
    code = gs_error_undefined;
72
1.46M
    while (1) { /* Loop to make retrying with a substitute CID easier */
73
        /* Favour the ToUnicode if one exists */
74
1.46M
        code = pdfi_tounicode_char_to_unicode(pt0font->ctx, (pdf_cmap *)pt0font->ToUnicode, glyph, ch, u, length);
75
76
1.46M
        if (code == gs_error_undefined && pt0font->decoding) {
77
12.6k
            const int *n;
78
79
12.6k
            if (cc / 256 < pt0font->decoding->nranges) {
80
12.6k
                n = (const int *)pt0font->decoding->ranges[cc / 256][cc % 256];
81
13.0k
                for (i = 0; i < pt0font->decoding->val_sizes; i++) {
82
13.0k
                    unsigned int cmapcc;
83
13.0k
                    if (n[i] == -1)
84
3.37k
                        break;
85
9.64k
                    cc = n[i];
86
9.64k
                    cmapcc = (unsigned int)cc;
87
9.64k
                    if (decfont->pdfi_font_type == e_pdf_cidfont_type2)
88
9.64k
                        code = pdfi_fapi_check_cmap_for_GID((gs_font *)decfont->pfont, (unsigned int)cc, &cmapcc);
89
0
                    else
90
0
                        code = 0;
91
9.64k
                    if (code >= 0 && cmapcc != 0){
92
9.26k
                        code = 0;
93
9.26k
                        break;
94
9.26k
                    }
95
9.64k
                }
96
                /* If it's a TTF derived CIDFont, we prefer a code point supported by the cmap table
97
                   but if not, use the first available one
98
                 */
99
12.6k
                if (code < 0 && n[0] != -1) {
100
0
                    cc = n[0];
101
0
                    code = 0;
102
0
                }
103
12.6k
            }
104
12.6k
            if (code >= 0) {
105
9.27k
                if (cc > 65535) {
106
0
                    code = 4;
107
0
                    if (unicode_return != NULL && length >= code) {
108
0
                        unicode_return[0] = (cc & 0xFF000000)>> 24;
109
0
                        unicode_return[1] = (cc & 0x00FF0000) >> 16;
110
0
                        unicode_return[2] = (cc & 0x0000FF00) >> 8;
111
0
                        unicode_return[3] = (cc & 0x000000FF);
112
0
                    }
113
0
                }
114
9.27k
                else {
115
9.27k
                    code = 2;
116
9.27k
                    if (unicode_return != NULL && length >= code) {
117
9.27k
                        unicode_return[0] = (cc & 0x0000FF00) >> 8;
118
9.27k
                        unicode_return[1] = (cc & 0x000000FF);
119
9.27k
                    }
120
9.27k
                }
121
9.27k
            }
122
12.6k
        }
123
        /* If we get here, and still don't have a usable code point, check for a
124
           pre-defined CID substitution, and if there's one, jump back to the start
125
           and try again.
126
         */
127
1.46M
        if (code == gs_error_undefined && substnwp) {
128
5.75k
            for (i = 0; substnwp->subst[i].s_type != 0; i++ ) {
129
5.55k
                if (cc >= substnwp->subst[i].s_scid && cc <= substnwp->subst[i].e_scid) {
130
0
                    cc = substnwp->subst[i].s_dcid + (cc - substnwp->subst[i].s_scid);
131
0
                    substnwp = NULL;
132
0
                    break;
133
0
                }
134
5.55k
                if (cc >= substnwp->subst[i].s_dcid
135
4.72k
                 && cc <= substnwp->subst[i].s_dcid + (substnwp->subst[i].e_scid - substnwp->subst[i].s_scid)) {
136
3.15k
                    cc = substnwp->subst[i].s_scid + (cc - substnwp->subst[i].s_dcid);
137
3.15k
                    substnwp = NULL;
138
3.15k
                    break;
139
3.15k
                }
140
5.55k
            }
141
3.36k
            if (substnwp == NULL)
142
3.15k
                continue;
143
3.36k
        }
144
1.46M
        break;
145
1.46M
    }
146
1.46M
    pdfi_countdown(decfont);
147
1.46M
    return (code < 0 ? 0 : code);
148
1.46M
}
149
150
int pdfi_read_type0_font(pdf_context *ctx, pdf_dict *font_dict, pdf_dict *stream_dict, pdf_dict *page_dict, pdf_font **ppdffont)
151
52.8k
{
152
52.8k
    int code, nlen;
153
52.8k
    pdf_obj *cmap = NULL;
154
52.8k
    pdf_cmap *pcmap = NULL;
155
52.8k
    pdf_array *arr = NULL;
156
52.8k
    pdf_dict *decfontdict = NULL; /* there can only be one */
157
52.8k
    pdf_name *n = NULL;
158
52.8k
    pdf_obj *basefont = NULL;
159
52.8k
    pdf_obj *tounicode = NULL;
160
52.8k
    pdf_dict *dfontdesc = NULL;
161
52.8k
    pdf_dict *fontdesc = NULL;
162
52.8k
    pdf_stream *ffile = NULL;
163
52.8k
    pdf_font *descpfont = NULL;
164
52.8k
    pdf_font_type0 *pdft0 = NULL;
165
52.8k
    gs_font_type0 *pfont0 = NULL;
166
52.8k
    pdfi_cid_decoding_t *dec = NULL;
167
52.8k
    pdfi_cid_subst_nwp_table_t *substnwp = NULL;
168
169
    /* We're supposed to have a FontDescriptor, it can be missing, and we have to carry on */
170
52.8k
    (void)pdfi_dict_get(ctx, font_dict, "FontDescriptor", (pdf_obj **)&fontdesc);
171
172
52.8k
    if (fontdesc != NULL) {
173
82
        pdf_obj *Name = NULL;
174
175
82
        code = pdfi_dict_get_type(ctx, (pdf_dict *) fontdesc, "FontName", PDF_NAME, (pdf_obj**)&Name);
176
82
        if (code < 0)
177
0
            pdfi_set_warning(ctx, 0, NULL, W_PDF_FDESC_BAD_FONTNAME, "pdfi_load_font", "");
178
82
        pdfi_countdown(Name);
179
82
    }
180
181
52.8k
    code = pdfi_dict_get(ctx, font_dict, "Encoding", &cmap);
182
52.8k
    if (code < 0) goto error;
183
184
52.4k
    if (pdfi_type_of(cmap) == PDF_CMAP) {
185
0
        pcmap = (pdf_cmap *)cmap;
186
0
        cmap = NULL;
187
0
    }
188
52.4k
    else {
189
52.4k
        code = pdfi_read_cmap(ctx, cmap, &pcmap);
190
52.4k
        pdfi_countdown(cmap);
191
52.4k
        cmap = NULL;
192
52.4k
        if (code < 0) goto error;
193
52.4k
    }
194
195
51.9k
    code = pdfi_dict_get(ctx, font_dict, "DescendantFonts", (pdf_obj **)&arr);
196
51.9k
    if (code < 0) goto error;
197
198
48.7k
    if (pdfi_type_of(arr) != PDF_ARRAY || arr->size != 1) {
199
191
        code = gs_note_error(gs_error_invalidfont);
200
191
        goto error;
201
191
    }
202
48.5k
    code = pdfi_array_get(ctx, arr, 0, (pdf_obj **)&decfontdict);
203
48.5k
    pdfi_countdown(arr);
204
48.5k
    arr = NULL;
205
48.5k
    if (code < 0) goto error;
206
33.9k
    switch (pdfi_type_of(decfontdict)) {
207
2.47k
        case PDF_FONT:
208
2.47k
            descpfont = (pdf_font *)decfontdict;
209
2.47k
            decfontdict = descpfont->PDF_font;
210
2.47k
            pdfi_countup(decfontdict);
211
2.47k
            break;
212
30.1k
        case PDF_DICT:
213
30.1k
            code = pdfi_dict_get(ctx, (pdf_dict *)decfontdict, "Type", (pdf_obj **)&n);
214
30.1k
            if (code < 0) goto error;
215
29.8k
            if (pdfi_type_of(n) != PDF_NAME || n->length != 4 || memcmp(n->data, "Font", 4) != 0) {
216
368
                pdfi_countdown(n);
217
368
                code = gs_note_error(gs_error_invalidfont);
218
368
                goto error;
219
368
            }
220
29.4k
            pdfi_countdown(n);
221
29.4k
            break;
222
1.36k
        default:
223
1.36k
            code = gs_note_error(gs_error_invalidfont);
224
1.36k
            goto error;
225
33.9k
    }
226
#if 0
227
    code = pdfi_dict_get(ctx, (pdf_dict *)decfontdict, "Subtype", (pdf_obj **)&n);
228
    if (code < 0)
229
        goto error;
230
231
    if (pdfi_type_of(n) != PDF_NAME || n->length != 12 || memcmp(n->data, "CIDFontType", 11) != 0) {
232
        pdfi_countdown(n);
233
        code = gs_note_error(gs_error_invalidfont);
234
        goto error;
235
    }
236
    /* cidftype is ignored for now, but we may need to know it when
237
       subsitutions are allowed
238
     */
239
    cidftype = n->data[11] - 48;
240
241
    pdfi_countdown(n);
242
#endif
243
244
31.9k
    code = pdfi_dict_get(ctx, font_dict, "BaseFont", (pdf_obj **)&basefont);
245
31.9k
    if (code < 0) {
246
223
        basefont = NULL;
247
223
    }
248
249
31.9k
    if (ctx->args.ignoretounicode != true) {
250
31.9k
        code = pdfi_dict_get(ctx, font_dict, "ToUnicode", (pdf_obj **)&tounicode);
251
31.9k
        if (code >= 0 && pdfi_type_of(tounicode) == PDF_STREAM) {
252
21.2k
            pdf_cmap *tu = NULL;
253
21.2k
            code = pdfi_read_cmap(ctx, tounicode, &tu);
254
21.2k
            pdfi_countdown(tounicode);
255
21.2k
            tounicode = (pdf_obj *)tu;
256
21.2k
        }
257
31.9k
        if (code < 0 || (tounicode != NULL && pdfi_type_of(tounicode) != PDF_CMAP)) {
258
10.9k
            pdfi_countdown(tounicode);
259
10.9k
            tounicode = NULL;
260
10.9k
            code = 0;
261
10.9k
        }
262
31.9k
    }
263
0
    else {
264
0
        tounicode = NULL;
265
0
    }
266
267
31.9k
    if (descpfont == NULL) {
268
29.4k
        gs_font *pf;
269
270
29.4k
        code = pdfi_load_font(ctx, stream_dict, page_dict, decfontdict, &pf, true);
271
29.4k
        if (code < 0)
272
9.45k
            goto error;
273
19.9k
        descpfont = (pdf_font *)pf->client_data;
274
19.9k
    }
275
276
22.4k
    if (descpfont->pdfi_font_type < e_pdf_cidfont_type0 || descpfont->pdfi_font_type > e_pdf_cidfont_type4) {
277
539
        code = gs_note_error(gs_error_invalidfont);
278
539
        goto error;
279
539
    }
280
281
21.9k
    if (descpfont != NULL && ((pdf_cidfont_t *)descpfont)->substitute) {
282
9.73k
        pdf_obj *csi = NULL;
283
9.73k
        pdf_string *reg = NULL, *ord = NULL;
284
9.73k
        char *r = NULL, *o = NULL;
285
9.73k
        int rlen = 0, olen = 0;
286
287
9.73k
        code = pdfi_dict_get(ctx, decfontdict, "CIDSystemInfo", (pdf_obj **)&csi);
288
9.73k
        if (code >= 0) {
289
8.17k
            (void)pdfi_dict_get(ctx, (pdf_dict *)csi, "Registry", (pdf_obj **)&reg);
290
8.17k
            (void)pdfi_dict_get(ctx, (pdf_dict *)csi, "Ordering", (pdf_obj **)&ord);
291
8.17k
            if (reg != NULL && pdfi_type_of(reg) == PDF_STRING
292
8.08k
             && ord != NULL && pdfi_type_of(ord) == PDF_STRING) {
293
8.06k
                r = (char *)reg->data;
294
8.06k
                rlen = reg->length;
295
8.06k
                o = (char *)ord->data;
296
8.06k
                olen = ord->length;
297
8.06k
            }
298
8.17k
            pdfi_countdown(csi);
299
8.17k
            pdfi_countdown(reg);
300
8.17k
            pdfi_countdown(ord);
301
8.17k
        }
302
9.73k
        if (r == NULL || o == NULL) {
303
1.67k
            r = (char *)pcmap->csi_reg.data;
304
1.67k
            rlen = pcmap->csi_reg.size;
305
1.67k
            o = (char *)pcmap->csi_ord.data;
306
1.67k
            olen = pcmap->csi_ord.size;
307
1.67k
        }
308
9.73k
        if (rlen > 0 && olen > 0)
309
9.73k
            pdfi_cidfont_cid_subst_tables(r, rlen, o, olen, &dec, &substnwp);
310
311
9.73k
        ((pdf_cidfont_t *)descpfont)->decoding = dec;
312
9.73k
        ((pdf_cidfont_t *)descpfont)->substnwp = substnwp;
313
9.73k
    }
314
    /* reference is now owned by the descendent font created above */
315
21.9k
    pdfi_countdown(decfontdict);
316
21.9k
    decfontdict = NULL;
317
21.9k
    if (code < 0) {
318
1.56k
        code = gs_note_error(gs_error_invalidfont);
319
1.56k
        goto error;
320
1.56k
    }
321
    /* If we're got this far, we have a CMap and a descendant font, let's make the Type 0 */
322
20.3k
    pdft0 = (pdf_font_type0 *)gs_alloc_bytes(ctx->memory, sizeof(pdf_font_type0), "pdfi (type0 pdf_font)");
323
20.3k
    if (pdft0 == NULL) {
324
0
        code = gs_note_error(gs_error_VMerror);
325
0
        goto error;
326
0
    }
327
328
    /* This is the only font type these entries not relevant for */
329
20.3k
    pdft0->copyright = pdft0->notice = pdft0->fullname = pdft0->familyname = NULL;
330
331
20.3k
    code = pdfi_array_alloc(ctx, 1, &arr);
332
20.3k
    if (code < 0) {
333
0
        gs_free_object(ctx->memory, pdft0, "pdfi_read_type0_font(pdft0)");
334
0
        goto error;
335
0
    }
336
20.3k
    arr->refcnt = 1;
337
20.3k
    code = pdfi_array_put(ctx, arr, 0, (pdf_obj *)descpfont);
338
20.3k
    if (code < 0) {
339
0
        gs_free_object(ctx->memory, pdft0, "pdfi_read_type0_font(pdft0)");
340
0
        goto error;
341
0
    }
342
343
20.3k
    pdft0->type = PDF_FONT;
344
20.3k
    pdft0->pdfi_font_type = e_pdf_font_type0;
345
20.3k
    pdft0->ctx = ctx;
346
#if REFCNT_DEBUG
347
    pdft0->UID = ctx->UID++;
348
    outprintf(ctx->memory, "Allocated object of type %c with UID %"PRIi64"\n", pdft0->type, pdft0->UID);
349
#endif
350
20.3k
    pdft0->refcnt = 1;
351
20.3k
    pdft0->filename = NULL;
352
20.3k
    pdft0->object_num = font_dict->object_num;
353
20.3k
    pdft0->generation_num = font_dict->generation_num;
354
20.3k
    pdft0->indirect_num = font_dict->indirect_num;
355
20.3k
    pdft0->indirect_gen = font_dict->indirect_gen;
356
20.3k
    pdft0->Encoding = (pdf_obj *)pcmap;
357
20.3k
    pdft0->ToUnicode = tounicode;
358
20.3k
    tounicode = NULL;
359
20.3k
    pdft0->DescendantFonts = arr;
360
20.3k
    pdft0->PDF_font = font_dict;
361
20.3k
    pdfi_countup(font_dict);
362
20.3k
    pdft0->FontDescriptor = fontdesc;
363
20.3k
    fontdesc = NULL;
364
20.3k
    pdft0->BaseFont = basefont;
365
20.3k
    pdft0->decoding = dec;
366
20.3k
    pdft0->substnwp = substnwp;
367
368
    /* Ownership transferred to pdft0, if we jump to error
369
     * these will now be freed by counting down pdft0.
370
     */
371
20.3k
    tounicode = NULL;
372
20.3k
    arr = NULL;
373
20.3k
    basefont = NULL;
374
375
20.3k
    pdft0->pfont = NULL; /* In case we error out */
376
377
20.3k
    pfont0 = (gs_font_type0 *)gs_alloc_struct(ctx->memory, gs_font, &st_gs_font_type0, "pdfi gs type 0 font");
378
20.3k
    if (pfont0 == NULL) {
379
0
        gs_free_object(ctx->memory, pdft0, "pdfi_read_type0_font(pdft0)");
380
0
        code = gs_note_error(gs_error_VMerror);
381
0
        goto error;
382
0
    }
383
20.3k
    gs_make_identity(&pfont0->orig_FontMatrix);
384
20.3k
    gs_make_identity(&pfont0->FontMatrix);
385
20.3k
    pfont0->next = pfont0->prev = 0;
386
20.3k
    pfont0->memory = ctx->memory;
387
20.3k
    pfont0->dir = ctx->font_dir;
388
20.3k
    pfont0->is_resource = false;
389
20.3k
    gs_notify_init(&pfont0->notify_list, ctx->memory);
390
20.3k
    pfont0->id = gs_next_ids(ctx->memory, 1);
391
20.3k
    pfont0->base = (gs_font *) pfont0;
392
20.3k
    pfont0->client_data = pdft0;
393
20.3k
    pfont0->WMode = pcmap->wmode;
394
20.3k
    pfont0->FontType = ft_composite;
395
20.3k
    pfont0->PaintType = 0;
396
20.3k
    pfont0->StrokeWidth = 0;
397
20.3k
    pfont0->is_cached = 0;
398
20.3k
    if (pdft0->BaseFont != NULL) {
399
20.3k
        pdf_name *nobj = (pdf_name *)pdft0->BaseFont;
400
20.3k
        nlen = nobj->length > gs_font_name_max ? gs_font_name_max : nobj->length;
401
402
20.3k
        memcpy(pfont0->key_name.chars, nobj->data, nlen);
403
20.3k
        pfont0->key_name.size = nlen;
404
20.3k
        memcpy(pfont0->font_name.chars, nobj->data, nlen);
405
20.3k
        pfont0->font_name.size = nlen;
406
20.3k
    }
407
35
    else {
408
35
        nlen = descpfont->pfont->key_name.size > gs_font_name_max ? gs_font_name_max : descpfont->pfont->key_name.size;
409
410
35
        memcpy(pfont0->key_name.chars, descpfont->pfont->key_name.chars, nlen);
411
35
        pfont0->key_name.size = nlen;
412
35
        memcpy(pfont0->font_name.chars, descpfont->pfont->font_name.chars, nlen);
413
35
        pfont0->font_name.size = nlen;
414
35
    }
415
416
20.3k
    if (pcmap->name.size > 0) {
417
20.2k
        if (pfont0->key_name.size + pcmap->name.size + 1 < gs_font_name_max) {
418
19.6k
            memcpy(pfont0->key_name.chars + pfont0->key_name.size, "-", 1);
419
19.6k
            memcpy(pfont0->key_name.chars + pfont0->key_name.size + 1, pcmap->name.data, pcmap->name.size);
420
19.6k
            pfont0->key_name.size += pcmap->name.size + 1;
421
19.6k
        }
422
20.2k
        if (pfont0->font_name.size + pcmap->name.size + 1 < gs_font_name_max) {
423
19.6k
            memcpy(pfont0->font_name.chars + pfont0->font_name.size, "-", 1);
424
19.6k
            memcpy(pfont0->font_name.chars + pfont0->font_name.size + 1, pcmap->name.data, pcmap->name.size);
425
19.6k
            pfont0->font_name.size += pcmap->name.size + 1;
426
19.6k
        }
427
20.2k
    }
428
20.3k
    pfont0->procs.define_font = gs_no_define_font;
429
20.3k
    pfont0->procs.make_font = gs_no_make_font;
430
20.3k
    pfont0->procs.font_info = gs_default_font_info;
431
20.3k
    pfont0->procs.same_font = gs_default_same_font;
432
20.3k
    pfont0->procs.encode_char = pdfi_encode_char;
433
20.3k
    pfont0->procs.decode_glyph = pdfi_font0_map_glyph_to_unicode;
434
20.3k
    pfont0->procs.enumerate_glyph = gs_no_enumerate_glyph;
435
20.3k
    pfont0->procs.glyph_info = gs_default_glyph_info;
436
20.3k
    pfont0->procs.glyph_outline = gs_no_glyph_outline;
437
20.3k
    pfont0->procs.glyph_name = pdfi_font0_glyph_name;
438
20.3k
    pfont0->procs.init_fstack = gs_type0_init_fstack;
439
20.3k
    pfont0->procs.next_char_glyph = gs_type0_next_char_glyph;
440
20.3k
    pfont0->procs.build_char = gs_no_build_char;
441
442
20.3k
    pfont0->data.FMapType = fmap_CMap;
443
20.3k
    pfont0->data.EscChar = 0xff;
444
20.3k
    pfont0->data.ShiftIn = 0x0f;
445
20.3k
    pfont0->data.SubsVector.data = NULL;
446
20.3k
    pfont0->data.SubsVector.size = 0;
447
20.3k
    pfont0->data.subs_size = pfont0->data.subs_width = 0;
448
449
20.3k
    pfont0->data.Encoding = (uint *)gs_alloc_bytes(ctx->memory, sizeof(uint), "pdfi_read_type0_font Encoding");
450
20.3k
    if (pfont0->data.Encoding == NULL) {
451
0
        gs_free_object(ctx->memory, pfont0, "pdfi_read_type0_font(pfont0)");
452
0
        code = gs_note_error(gs_error_VMerror);
453
0
        goto error;
454
0
    }
455
20.3k
    *pfont0->data.Encoding = 0;
456
457
20.3k
    pfont0->data.encoding_size = 1;
458
20.3k
    pfont0->data.FDepVector = (gs_font **)gs_alloc_bytes(ctx->memory, sizeof(gs_font *), "pdfi_read_type0_font FDepVector");
459
20.3k
    if (pfont0->data.FDepVector == NULL) {
460
        /* We transferred ownership of pcmap to pfont0 above, but we didn't null the pointer
461
         * so we could keep using it. We must NULL it out before returning an error to prevent
462
         * reference counting problems.
463
         */
464
0
        pcmap = NULL;
465
0
        gs_free_object(ctx->memory, pfont0, "pdfi_read_type0_font(pfont0)");
466
0
        code = gs_note_error(gs_error_VMerror);
467
0
        goto error;
468
0
    }
469
20.3k
    *pfont0->data.FDepVector = (gs_font *)descpfont->pfont;
470
20.3k
    pdfi_countdown(descpfont);
471
20.3k
    descpfont = NULL;
472
20.3k
    pfont0->data.fdep_size = 1;
473
20.3k
    pfont0->data.CMap = (gs_cmap_t *)pcmap->gscmap;
474
475
    /* NULL he pointer to prevent any reference counting problems, ownership was
476
     * transferred to pfont0, but we maintained the pointer for easy access until this
477
     * point.
478
     */
479
20.3k
    pcmap = NULL;
480
481
20.3k
    pdft0->pfont = (gs_font_base *)pfont0;
482
483
20.3k
    code = gs_definefont(ctx->font_dir, (gs_font *)pdft0->pfont);
484
20.3k
    if (code < 0) {
485
0
        gs_free_object(ctx->memory, pfont0, "pdfi_read_type0_font(pfont0)");
486
0
        code = gs_note_error(gs_error_VMerror);
487
0
        goto error;
488
0
    }
489
490
    /* object_num can be zero if the dictionary was defined inline */
491
20.3k
    if (pdft0->object_num != 0) {
492
20.3k
        (void)replace_cache_entry(ctx, (pdf_obj *)pdft0);
493
20.3k
    }
494
495
20.3k
    *ppdffont = (pdf_font *)pdft0;
496
20.3k
    return 0;
497
498
32.4k
error:
499
32.4k
    (void)pdfi_set_error_var(ctx, code, NULL, E_PDF_BADSTREAM, "pdfi_read_type0_font", "Error reading embedded Type0 font object %u\n", font_dict->object_num);
500
501
32.4k
    pdfi_countdown(arr);
502
32.4k
    pdfi_countdown(pcmap);
503
32.4k
    pdfi_countdown(tounicode);
504
32.4k
    pdfi_countdown(basefont);
505
32.4k
    pdfi_countdown(decfontdict);
506
32.4k
    pdfi_countdown(dfontdesc);
507
32.4k
    pdfi_countdown(fontdesc);
508
32.4k
    pdfi_countdown(ffile);
509
32.4k
    pdfi_countdown(descpfont);
510
32.4k
    pdfi_countdown(pdft0);
511
512
32.4k
    return code;
513
20.3k
}
514
515
int
516
pdfi_free_font_type0(pdf_obj *font)
517
20.3k
{
518
20.3k
    pdf_font_type0 *pdft0 = (pdf_font_type0 *)font;
519
20.3k
    gs_font_type0 *pfont0 = (gs_font_type0 *)pdft0->pfont;
520
20.3k
    pdfi_countdown(pdft0->PDF_font);
521
20.3k
    pdfi_countdown(pdft0->BaseFont);
522
20.3k
    pdfi_countdown(pdft0->FontDescriptor);
523
20.3k
    pdfi_countdown(pdft0->Encoding);
524
20.3k
    pdfi_countdown(pdft0->DescendantFonts);
525
20.3k
    pdfi_countdown(pdft0->ToUnicode);
526
20.3k
    pdfi_countdown(pdft0->filename);
527
20.3k
    pdfi_countdown(pdft0->copyright);
528
20.3k
    pdfi_countdown(pdft0->notice);
529
20.3k
    pdfi_countdown(pdft0->fullname);
530
20.3k
    pdfi_countdown(pdft0->familyname);
531
532
20.3k
    gs_free_object(OBJ_MEMORY(pdft0), pfont0->data.Encoding, "pdfi_free_font_type0(data.Encoding)");
533
    /* We shouldn't need to free the fonts in the FDepVector, that should happen
534
        with DescendantFonts above.
535
     */
536
20.3k
    gs_free_object(OBJ_MEMORY(pdft0), pfont0->data.FDepVector, "pdfi_free_font_type0(data.FDepVector)");
537
20.3k
    gs_free_object(OBJ_MEMORY(pdft0), pfont0, "pdfi_free_font_type0(pfont0)");
538
20.3k
    gs_free_object(OBJ_MEMORY(pdft0), pdft0, "pdfi_free_font_type0(pdft0)");
539
540
20.3k
    return 0;
541
20.3k
}