Coverage Report

Created: 2022-10-31 07:00

/src/ghostpdl/pdf/pdf_cmap.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2020-2022 Artifex Software, Inc.
2
   All Rights Reserved.
3
4
   This software is provided AS-IS with no warranty, either express or
5
   implied.
6
7
   This software is distributed under license and may not be copied,
8
   modified or distributed except as expressly authorized under the terms
9
   of the license contained in the file LICENSE in this distribution.
10
11
   Refer to licensing information at http://www.artifex.com or contact
12
   Artifex Software, Inc.,  1305 Grant Avenue - Suite 200, Novato,
13
   CA 94945, U.S.A., +1(415)492-9861, for further information.
14
*/
15
16
#include "strmio.h"
17
#include "stream.h"
18
#include "scanchar.h"
19
20
#include "pdf_int.h"
21
#include "pdf_cmap.h"
22
23
#include "pdf_stack.h"
24
#include "pdf_dict.h"
25
#include "pdf_file.h"
26
#include "pdf_fontps.h"
27
#include "pdf_deref.h"
28
29
static int pdfi_free_cmap_contents(pdf_cmap *cmap);
30
31
static int cmap_usecmap_func(gs_memory_t *mem, pdf_ps_ctx_t *s, byte *buf, byte *bufend)
32
65
{
33
65
    pdf_cmap *pdficmap = (pdf_cmap *)s->client_data;
34
65
    pdf_name *n = NULL;
35
65
    pdf_cmap *upcmap = NULL;
36
65
    int code = 0;
37
38
65
    if (pdf_ps_stack_count(s) < 1)
39
0
        return_error(gs_error_stackunderflow);
40
41
    /* If we've already got some definitions, ignore the usecmap op */
42
65
    if (pdficmap->code_space.num_ranges == 0) {
43
65
        byte *nstr = NULL;
44
65
        int len = s->cur[0].size;
45
46
65
        if (pdf_ps_obj_has_type(&(s->cur[0]), PDF_PS_OBJ_NAME)) {
47
65
            nstr = s->cur[0].val.name;
48
65
        }
49
0
        else if (pdf_ps_obj_has_type(&(s->cur[0]), PDF_PS_OBJ_STRING)) {
50
0
            nstr = s->cur[0].val.string;
51
0
        }
52
0
        else {
53
0
            code = gs_note_error(gs_error_typecheck);
54
0
        }
55
65
        if (code >= 0)
56
65
            code = pdfi_name_alloc(pdficmap->ctx, nstr, len, (pdf_obj **)&n);
57
65
        if (code >= 0) {
58
65
            pdfi_countup(n);
59
65
            code = pdfi_read_cmap(pdficmap->ctx, (pdf_obj *)n, &upcmap);
60
65
            if (code >= 0) {
61
42
                gx_code_space_range_t * ranges =
62
42
                         (gx_code_space_range_t *)gs_alloc_byte_array(mem, upcmap->code_space.num_ranges,
63
42
                          sizeof(gx_code_space_range_t), "cmap_usecmap_func(ranges)");
64
42
                if (ranges != NULL) {
65
42
                    int i;
66
42
                    memcpy(&pdficmap->code_space, &upcmap->code_space, sizeof(pdficmap->code_space));
67
114
                    for (i = 0; i < upcmap->code_space.num_ranges; i++) {
68
72
                        memcpy(&(ranges[i]), &(upcmap->code_space.ranges[i]), sizeof(ranges[i]));
69
72
                    }
70
42
                    pdficmap->code_space.ranges = ranges;
71
42
                    memcpy(&pdficmap->cmap_range, &upcmap->cmap_range, sizeof(pdficmap->cmap_range));
72
42
                    memcpy(&pdficmap->notdef_cmap_range, &upcmap->notdef_cmap_range, sizeof(pdficmap->notdef_cmap_range));
73
                    /* Once we've assumed control of these, NULL out entries for the sub-cmap. */
74
42
                    upcmap->cmap_range.ranges = NULL;
75
42
                    upcmap->notdef_cmap_range.ranges = NULL;
76
                    /* But we keep the subcmap itself because we rely on its storage */
77
42
                    pdficmap->next = upcmap;
78
42
                    pdfi_countup(upcmap);
79
42
                }
80
42
            }
81
65
        }
82
65
    }
83
65
    pdfi_countdown(upcmap);
84
65
    pdfi_countdown(n);
85
65
    if (code < 0) {
86
23
        (void)pdf_ps_stack_pop(s, 1);
87
23
        return code;
88
23
    }
89
42
    return pdf_ps_stack_pop(s, 1);
90
65
}
91
92
#if 0 /* no longer used */
93
static int cmap_pushmark_func(gs_memory_t *mem, pdf_ps_ctx_t *stack, pdf_cmap *pdficmap)
94
{
95
    return pdf_ps_stack_push_mark(stack);
96
}
97
#endif
98
99
100
static int cmap_endcodespacerange_func(gs_memory_t *mem, pdf_ps_ctx_t *s, byte *buf, byte *bufend)
101
16.7k
{
102
16.7k
    pdf_cmap *pdficmap = (pdf_cmap *)s->client_data;
103
16.7k
    int i, numranges, to_pop = pdf_ps_stack_count_to_mark(s, PDF_PS_OBJ_MARK);
104
16.7k
    gx_code_space_t *code_space = &pdficmap->code_space;
105
16.7k
    int nr = code_space->num_ranges;
106
16.7k
    gx_code_space_range_t *gcsr = code_space->ranges;
107
108
    /* increment to_pop to cover the mark object */
109
16.7k
    numranges = to_pop++;
110
16.7k
    while (numranges % 2) numranges--;
111
16.7k
    if (numranges > 200) {
112
0
        (void)pdf_ps_stack_pop(s, to_pop);
113
0
        return_error(gs_error_syntaxerror);
114
0
    }
115
116
16.7k
    if (numranges > 0
117
16.7k
     && pdf_ps_obj_has_type(&(s->cur[0]), PDF_PS_OBJ_STRING)  && s->cur[0].size <= MAX_CMAP_CODE_SIZE
118
16.7k
     && pdf_ps_obj_has_type(&(s->cur[-1]), PDF_PS_OBJ_STRING) && s->cur[-1].size <= MAX_CMAP_CODE_SIZE) {
119
120
16.6k
        code_space->num_ranges += numranges >> 1;
121
122
16.6k
        code_space->ranges = (gx_code_space_range_t *)gs_alloc_byte_array(mem, code_space->num_ranges,
123
16.6k
                          sizeof(gx_code_space_range_t), "cmap_endcodespacerange_func(ranges)");
124
16.6k
        if (code_space->ranges != NULL) {
125
16.6k
            if (nr > 0) {
126
11
                memcpy(code_space->ranges, gcsr, nr);
127
11
                gs_free_object(mem, gcsr, "cmap_endcodespacerange_func(gcsr");
128
11
            }
129
130
33.5k
            for (i = nr; i < code_space->num_ranges; i++) {
131
16.8k
                int si = i - nr;
132
16.8k
                int s1 = s->cur[-((si * 2) + 1)].size < MAX_CMAP_CODE_SIZE ? s->cur[-((si * 2) + 1)].size : MAX_CMAP_CODE_SIZE;
133
16.8k
                int s2 = s->cur[-(si * 2)].size < MAX_CMAP_CODE_SIZE ? s->cur[-(si * 2)].size : MAX_CMAP_CODE_SIZE;
134
135
16.8k
                memcpy(code_space->ranges[i].first, s->cur[-((si * 2) + 1)].val.string, s1);
136
16.8k
                memcpy(code_space->ranges[i].last, s->cur[-(si * 2)].val.string, s2);
137
16.8k
                code_space->ranges[i].size = s->cur[-(si * 2)].size;
138
16.8k
            }
139
16.6k
        }
140
0
        else {
141
0
            (void)pdf_ps_stack_pop(s, to_pop);
142
0
            return_error(gs_error_VMerror);
143
0
        }
144
16.6k
    }
145
16.7k
    return pdf_ps_stack_pop(s, to_pop);
146
16.7k
}
147
148
static int cmap_insert_map(pdfi_cmap_range_t *cmap_range, pdfi_cmap_range_map_t *pdfir)
149
480M
{
150
480M
    if (cmap_range->ranges == NULL) {
151
16.0k
        cmap_range->ranges = cmap_range->ranges_tail = pdfir;
152
16.0k
    }
153
480M
    else {
154
480M
        cmap_range->ranges_tail->next = pdfir;
155
480M
        cmap_range->ranges_tail = pdfir;
156
480M
    }
157
480M
    cmap_range->numrangemaps++;
158
480M
    return 0;
159
480M
}
160
161
static int general_endcidrange_func(gs_memory_t *mem, pdf_ps_ctx_t *s, pdf_cmap *pdficmap, pdfi_cmap_range_t *cmap_range)
162
21.5k
{
163
21.5k
    int ncodemaps, to_pop = pdf_ps_stack_count_to_mark(s, PDF_PS_OBJ_MARK);
164
21.5k
    int i, j;
165
21.5k
    pdfi_cmap_range_map_t *pdfir;
166
21.5k
    pdf_ps_stack_object_t *stobj;
167
168
    /* increment to_pop to cover the mark object */
169
21.5k
    ncodemaps = to_pop++;
170
    /* mapping should have 3 objects on the stack:
171
     * startcode, endcode and basecid
172
     */
173
21.5k
    while (ncodemaps % 3) ncodemaps--;
174
21.5k
    if (ncodemaps > 300) {
175
0
        (void)pdf_ps_stack_pop(s, to_pop);
176
0
        return_error(gs_error_syntaxerror);
177
0
    }
178
179
21.5k
    stobj = &s->cur[-ncodemaps] + 1;
180
181
1.81M
    for (i = 0; i < ncodemaps; i += 3) {
182
1.79M
        int preflen, valuelen;
183
184
1.79M
        if (pdf_ps_obj_has_type(&(stobj[i + 2]), PDF_PS_OBJ_INTEGER)
185
1.79M
        &&  pdf_ps_obj_has_type(&(stobj[i + 1]), PDF_PS_OBJ_STRING)
186
1.79M
        &&  pdf_ps_obj_has_type(&(stobj[i]), PDF_PS_OBJ_STRING)){
187
1.79M
            uint cidbase = stobj[i + 2].val.i;
188
189
            /* First, find the length of the prefix */
190
3.64M
            for (preflen = 0; preflen < stobj[i].size; preflen++) {
191
3.59M
                if(stobj[i].val.string[preflen] != stobj[i + 1].val.string[preflen]) {
192
1.73M
                    break;
193
1.73M
                }
194
3.59M
            }
195
196
1.79M
            if (preflen == stobj[i].size) {
197
56.2k
                preflen = 1;
198
56.2k
            }
199
200
1.79M
            if (preflen > MAX_CMAP_CODE_SIZE || stobj[i].size - preflen > MAX_CMAP_CODE_SIZE || stobj[i + 1].size - preflen > MAX_CMAP_CODE_SIZE
201
1.79M
                || stobj[i].size - preflen < 0 || stobj[i + 1].size - preflen < 0) {
202
7
                (void)pdf_ps_stack_pop(s, to_pop);
203
7
                return_error(gs_error_syntaxerror);
204
7
            }
205
206
            /* Find how many bytes we need for the cidbase value */
207
            /* We always store at least two bytes for the cidbase value */
208
1.79M
            for (valuelen = 16; valuelen < 32 && (cidbase >> valuelen) > 0; valuelen += 1)
209
1.79M
                DO_NOTHING;
210
211
1.79M
            valuelen = ((valuelen + 7) & ~7) >> 3;
212
213
            /* The prefix is already directly in the gx_cmap_lookup_range_t
214
             * We need to store the lower and upper character codes, after lopping the prefix
215
             * off them. The upper and lower codes must be the same number of bytes.
216
             */
217
1.79M
            j = sizeof(pdfi_cmap_range_map_t) + 2 * (stobj[i].size - preflen) + valuelen;
218
219
1.79M
            pdfir = (pdfi_cmap_range_map_t *)gs_alloc_bytes(mem, j, "cmap_endcidrange_func(pdfi_cmap_range_map_t)");
220
1.79M
            if (pdfir != NULL) {
221
1.79M
                gx_cmap_lookup_range_t *gxr = &pdfir->range;
222
1.79M
                pdfir->next = NULL;
223
1.79M
                gxr->num_entries = 1;
224
1.79M
                gxr->keys.data = (byte *)&(pdfir[1]);
225
1.79M
                gxr->values.data = gxr->keys.data + 2 * (stobj[i].size - preflen);
226
227
1.79M
                gxr->cmap = NULL;
228
1.79M
                gxr->font_index = 0;
229
1.79M
                gxr->key_is_range = true;
230
1.79M
                gxr->value_type = cmap_range == &(pdficmap->cmap_range) ? CODE_VALUE_CID : CODE_VALUE_NOTDEF;
231
1.79M
                gxr->key_prefix_size = preflen;
232
1.79M
                gxr->key_size = stobj[i].size - gxr->key_prefix_size;
233
1.79M
                memcpy(gxr->key_prefix, stobj[i].val.string, gxr->key_prefix_size);
234
235
1.79M
                memcpy(gxr->keys.data, stobj[i].val.string + gxr->key_prefix_size, stobj[i].size - gxr->key_prefix_size);
236
1.79M
                memcpy(gxr->keys.data + (stobj[i].size - gxr->key_prefix_size), stobj[i + 1].val.string + gxr->key_prefix_size, stobj[i + 1].size - gxr->key_prefix_size);
237
238
1.79M
                gxr->keys.size = (stobj[i].size - gxr->key_prefix_size) + (stobj[i + 1].size - gxr->key_prefix_size);
239
5.38M
                for (j = 0; j < valuelen; j++) {
240
3.59M
                    gxr->values.data[j] = (cidbase >> ((valuelen - 1 - j) * 8)) & 255;
241
3.59M
                }
242
1.79M
                gxr->value_size = valuelen; /* I'm not sure.... */
243
1.79M
                gxr->values.size = valuelen;
244
1.79M
                if (cmap_insert_map(cmap_range, pdfir) < 0) break;
245
1.79M
            }
246
0
            else {
247
0
                (void)pdf_ps_stack_pop(s, to_pop);
248
0
                return_error(gs_error_VMerror);
249
0
            }
250
1.79M
        }
251
1.79M
    }
252
21.5k
    return pdf_ps_stack_pop(s, to_pop);
253
21.5k
}
254
255
static int cmap_endcidrange_func(gs_memory_t *mem, pdf_ps_ctx_t *s, byte *buf, byte *bufend)
256
21.4k
{
257
21.4k
    pdf_cmap *pdficmap = (pdf_cmap *)s->client_data;
258
21.4k
    return general_endcidrange_func(mem, s, pdficmap, &pdficmap->cmap_range);
259
21.4k
}
260
261
static int cmap_endnotdefrange_func(gs_memory_t *mem, pdf_ps_ctx_t *s, byte *buf, byte *bufend)
262
79
{
263
79
    pdf_cmap *pdficmap = (pdf_cmap *)s->client_data;
264
79
    return general_endcidrange_func(mem, s, pdficmap, &pdficmap->notdef_cmap_range);
265
79
}
266
267
static int cmap_endfbrange_func(gs_memory_t *mem, pdf_ps_ctx_t *s, byte *buf, byte *bufend)
268
4.25k
{
269
4.25k
    pdf_cmap *pdficmap = (pdf_cmap *)s->client_data;
270
4.25k
    int ncodemaps, to_pop = pdf_ps_stack_count_to_mark(s, PDF_PS_OBJ_MARK);
271
4.25k
    int i, j, k;
272
4.25k
    pdfi_cmap_range_map_t *pdfir;
273
4.25k
    pdf_ps_stack_object_t *stobj;
274
275
    /* increment to_pop to cover the mark object */
276
4.25k
    ncodemaps = to_pop++;
277
    /* mapping should have 3 objects on the stack
278
     */
279
4.32k
    while (ncodemaps % 3) ncodemaps--;
280
281
4.25k
    if (ncodemaps > 300) {
282
5
        (void)pdf_ps_stack_pop(s, to_pop);
283
5
        return_error(gs_error_syntaxerror);
284
5
    }
285
286
4.25k
    stobj = &s->cur[-ncodemaps] + 1;
287
80.2k
    for (i = 0; i < ncodemaps; i += 3) {
288
        /* Lazy: to make the loop below simpler, put single
289
           values into a one element array
290
         */
291
75.9k
        if (pdf_ps_obj_has_type(&(stobj[i + 2]), PDF_PS_OBJ_STRING)) {
292
74.5k
            pdf_ps_stack_object_t *arr;
293
74.5k
            arr = (pdf_ps_stack_object_t *) gs_alloc_bytes(mem, sizeof(pdf_ps_stack_object_t), "cmap_endfbrange_func(pdf_ps_stack_object_t");
294
74.5k
            if (arr == NULL) {
295
0
                (void)pdf_ps_stack_pop(s, to_pop);
296
0
                return_error(gs_error_VMerror);
297
0
            }
298
74.5k
            else {
299
74.5k
                memcpy(arr, &(stobj[i + 2]), sizeof(pdf_ps_stack_object_t));
300
74.5k
                pdf_ps_make_array(&(stobj[i + 2]), arr, 1);
301
74.5k
            }
302
74.5k
        }
303
75.9k
    }
304
305
4.25k
    stobj = &s->cur[-ncodemaps] + 1;
306
307
78.9k
    for (i = 0; i < ncodemaps; i += 3) {
308
74.7k
        int preflen, valuelen;
309
310
74.7k
        if (pdf_ps_obj_has_type(&(stobj[i + 2]), PDF_PS_OBJ_ARRAY)
311
74.7k
        &&  pdf_ps_obj_has_type(&(stobj[i + 1]), PDF_PS_OBJ_STRING)
312
74.7k
        &&  pdf_ps_obj_has_type(&(stobj[i]), PDF_PS_OBJ_STRING)){
313
314
74.7k
            uint cidbase = 0;
315
74.7k
            int srcs = 0, srce = 0;
316
74.7k
            int kslen = stobj[i].size;
317
318
74.7k
            if (kslen > 4) {
319
25
                dprintf("CMap: value out of range\n");
320
25
                continue;
321
25
            }
322
323
196k
            for (k = 0; k < stobj[i].size; k++) {
324
121k
                srcs |= stobj[i].val.string[stobj[i].size - k - 1] << (8 * k);
325
121k
            }
326
196k
            for (k = 0; k < stobj[i + 1].size; k++) {
327
121k
                srce |= stobj[i + 1].val.string[stobj[i + 1].size - k - 1] << (8 * k);
328
121k
            }
329
330
476M
            for (k = srcs; k < srce + 1; k++) {
331
476M
                int m, size;
332
476M
                char srccode[4]; /* we only deal with up to 4 bytes */
333
476M
                char *psrccode = &(srccode[4 - kslen]);
334
335
476M
                if ((k - srcs) < stobj[i + 2].size) {
336
129k
                    if (stobj[i + 2].val.arr[k - srcs].type != PDF_PS_OBJ_STRING)
337
0
                        continue;
338
129k
                    size = stobj[i + 2].val.arr[k - srcs].size;
339
340
129k
                    cidbase = 0;
341
390k
                    for (m = 0; m < size; m++) {
342
261k
                        cidbase |= stobj[i + 2].val.arr[k - srcs].val.string[size - m - 1] << (8 * m);
343
261k
                    }
344
129k
                }
345
476M
                else {
346
476M
                    cidbase++;
347
476M
                }
348
349
1.13G
                for (m = 0; m < kslen; m++) {
350
659M
                    psrccode[m] = (k >> (8 * (kslen - m - 1))) & 0xff;
351
659M
                }
352
353
                /* Find how many bytes we need for the cidbase value */
354
                /* We always store at least two bytes for the cidbase value */
355
5.11G
                for (valuelen = 16; valuelen < 32 && (cidbase >> valuelen) > 0; valuelen += 1)
356
4.63G
                    DO_NOTHING;
357
358
476M
                preflen = kslen > 4 ? 4 : kslen;
359
360
476M
                valuelen = ((valuelen + 7) & ~7) >> 3;
361
362
                /* The prefix is already directly in the gx_cmap_lookup_range_t
363
                 * We need to store the lower and upper character codes, after lopping the prefix
364
                 * off them. The upper and lower codes must be the same number of bytes.
365
                 */
366
476M
                j = sizeof(pdfi_cmap_range_map_t) + (kslen - preflen) + valuelen;
367
368
476M
                pdfir = (pdfi_cmap_range_map_t *)gs_alloc_bytes(mem, j, "cmap_endcidrange_func(pdfi_cmap_range_map_t)");
369
476M
                if (pdfir != NULL) {
370
476M
                    gx_cmap_lookup_range_t *gxr = &pdfir->range;
371
476M
                    pdfir->next = NULL;
372
476M
                    gxr->num_entries = 1;
373
476M
                    gxr->keys.data = (byte *)&(pdfir[1]);
374
476M
                    gxr->values.data = gxr->keys.data + (kslen - preflen);
375
376
476M
                    gxr->cmap = NULL;
377
476M
                    gxr->font_index = 0;
378
476M
                    gxr->key_is_range = false;
379
476M
                    gxr->value_type = CODE_VALUE_CID;
380
476M
                    gxr->key_prefix_size = preflen;
381
476M
                    gxr->key_size = kslen - gxr->key_prefix_size;
382
476M
                    memcpy(gxr->key_prefix, psrccode, gxr->key_prefix_size);
383
384
476M
                    memcpy(gxr->keys.data, psrccode + gxr->key_prefix_size, kslen - gxr->key_prefix_size);
385
386
476M
                    gxr->keys.size = kslen - gxr->key_prefix_size;
387
2.07G
                    for (j = 0; j < valuelen; j++) {
388
1.59G
                        gxr->values.data[j] = (cidbase >> ((valuelen - 1 - j) * 8)) & 255;
389
1.59G
                    }
390
476M
                    gxr->value_size = valuelen; /* I'm not sure.... */
391
476M
                    gxr->values.size = valuelen;
392
476M
                    if (cmap_insert_map(&(pdficmap->cmap_range), pdfir) < 0) break;
393
476M
                }
394
55
                else {
395
55
                    (void)pdf_ps_stack_pop(s, to_pop);
396
55
                    return_error(gs_error_VMerror);
397
55
                }
398
476M
            }
399
74.7k
        }
400
74.7k
    }
401
4.19k
    return pdf_ps_stack_pop(s, to_pop);
402
4.25k
}
403
404
static int general_endcidchar_func(gs_memory_t *mem, pdf_ps_ctx_t *s, pdf_cmap *pdficmap, pdfi_cmap_range_t *cmap_range)
405
20.5k
{
406
20.5k
    int ncodemaps, to_pop = pdf_ps_stack_count_to_mark(s, PDF_PS_OBJ_MARK);
407
20.5k
    int i, j;
408
20.5k
    pdfi_cmap_range_map_t *pdfir;
409
20.5k
    pdf_ps_stack_object_t *stobj;
410
411
    /* increment to_pop to cover the mark object */
412
20.5k
    ncodemaps = to_pop++;
413
    /* mapping should have 2 objects on the stack:
414
     * startcode, endcode and basecid
415
     */
416
20.5k
    while (ncodemaps % 2) ncodemaps--;
417
418
20.5k
    if (ncodemaps > 200) {
419
5
        (void)pdf_ps_stack_pop(s, to_pop);
420
5
        return_error(gs_error_syntaxerror);
421
5
    }
422
423
20.5k
    stobj = &s->cur[-ncodemaps] + 1;
424
425
1.48M
    for (i = 0; i < ncodemaps; i += 2) {
426
1.46M
        int preflen = 1, valuelen;
427
428
1.46M
        if (pdf_ps_obj_has_type(&(stobj[i + 1]), PDF_PS_OBJ_INTEGER)
429
1.46M
        &&  pdf_ps_obj_has_type(&(stobj[i]), PDF_PS_OBJ_STRING)) {
430
1.46M
            uint cidbase = stobj[i + 1].val.i;
431
432
            /* Find how many bytes we need for the cidbase value */
433
            /* We always store at least two bytes for the cidbase value */
434
2.36M
            for (valuelen = 16; valuelen < 32 && (cidbase >> valuelen) > 0; valuelen += 1)
435
1.46M
                DO_NOTHING;
436
437
1.46M
            preflen = stobj[i].size > 4 ? 4 : stobj[i].size;
438
439
1.46M
            valuelen = ((valuelen + 7) & ~7) >> 3;
440
441
            /* The prefix is already directly in the gx_cmap_lookup_range_t
442
             * We need to store the lower and upper character codes, after lopping the prefix
443
             * off them. The upper and lower codes must be the same number of bytes.
444
             */
445
1.46M
            j = sizeof(pdfi_cmap_range_map_t) + (stobj[i].size - preflen) + valuelen;
446
447
1.46M
            pdfir = (pdfi_cmap_range_map_t *)gs_alloc_bytes(mem, j, "cmap_endcidrange_func(pdfi_cmap_range_map_t)");
448
1.46M
            if (pdfir != NULL) {
449
1.46M
                gx_cmap_lookup_range_t *gxr = &pdfir->range;
450
1.46M
                pdfir->next = NULL;
451
1.46M
                gxr->num_entries = 1;
452
1.46M
                gxr->keys.data = (byte *)&(pdfir[1]);
453
1.46M
                gxr->values.data = gxr->keys.data + (stobj[i].size - preflen);
454
455
1.46M
                gxr->cmap = NULL;
456
1.46M
                gxr->font_index = 0;
457
1.46M
                gxr->key_is_range = false;
458
1.46M
                gxr->value_type = cmap_range == &(pdficmap->cmap_range) ? CODE_VALUE_CID : CODE_VALUE_NOTDEF;
459
1.46M
                gxr->key_prefix_size = preflen;
460
1.46M
                gxr->key_size = stobj[i].size - gxr->key_prefix_size;
461
1.46M
                memcpy(gxr->key_prefix, stobj[i].val.string, gxr->key_prefix_size);
462
463
1.46M
                memcpy(gxr->keys.data, stobj[i].val.string + gxr->key_prefix_size, stobj[i].size - gxr->key_prefix_size);
464
465
1.46M
                gxr->keys.size = stobj[i].size - gxr->key_prefix_size;
466
4.52M
                for (j = 0; j < valuelen; j++) {
467
3.05M
                    gxr->values.data[j] = (cidbase >> ((valuelen - 1 - j) * 8)) & 255;
468
3.05M
                }
469
1.46M
                gxr->value_size = valuelen; /* I'm not sure.... */
470
1.46M
                gxr->values.size = valuelen;
471
1.46M
                if (cmap_insert_map(cmap_range, pdfir) < 0) break;
472
1.46M
            }
473
0
            else {
474
0
                (void)pdf_ps_stack_pop(s, to_pop);
475
0
                return_error(gs_error_VMerror);
476
0
            }
477
1.46M
        }
478
1.46M
    }
479
20.5k
    return pdf_ps_stack_pop(s, to_pop);
480
20.5k
}
481
482
static int cmap_endcidchar_func(gs_memory_t *mem, pdf_ps_ctx_t *s, byte *buf, byte *bufend)
483
3.26k
{
484
3.26k
    pdf_cmap *pdficmap = (pdf_cmap *)s->client_data;
485
3.26k
    return general_endcidchar_func(mem, s, pdficmap, &pdficmap->cmap_range);
486
3.26k
}
487
488
static int cmap_endnotdefchar_func(gs_memory_t *mem, pdf_ps_ctx_t *s, byte *buf, byte *bufend)
489
0
{
490
0
    pdf_cmap *pdficmap = (pdf_cmap *)s->client_data;
491
0
    return general_endcidchar_func(mem, s, pdficmap, &pdficmap->notdef_cmap_range);
492
0
}
493
494
static int cmap_endbfchar_func(gs_memory_t *mem, pdf_ps_ctx_t *s, byte *buf, byte *bufend)
495
17.3k
{
496
17.3k
    pdf_cmap *pdficmap = (pdf_cmap *)s->client_data;
497
17.3k
    int ncodemaps = pdf_ps_stack_count_to_mark(s, PDF_PS_OBJ_MARK);
498
17.3k
    pdf_ps_stack_object_t *stobj;
499
17.3k
    int i, j;
500
501
17.3k
    if (ncodemaps > 200) {
502
40
        (void)pdf_ps_stack_pop(s, ncodemaps);
503
40
        return_error(gs_error_syntaxerror);
504
40
    }
505
506
17.2k
    stobj = &s->cur[-ncodemaps] + 1;
507
508
1.19M
    for (i = 0; i < ncodemaps; i += 2) {
509
1.17M
        if (pdf_ps_obj_has_type(&(stobj[i + 1]), PDF_PS_OBJ_STRING)) {
510
1.17M
            byte *c = stobj[i + 1].val.string;
511
1.17M
            int l = stobj[i + 1].size;
512
1.17M
            unsigned int v = 0;
513
514
3.88M
            for (j = 0; j < l; j++) {
515
2.70M
                v += c[l - j - 1] << (8 * j);
516
2.70M
            }
517
1.17M
            pdf_ps_make_int(&(stobj[i + 1]), v);
518
1.17M
        }
519
67
        else {
520
67
            continue;
521
67
        }
522
1.17M
    }
523
17.2k
    return general_endcidchar_func(mem, s, pdficmap, &pdficmap->cmap_range);
524
17.3k
}
525
526
374k
#define CMAP_NAME_AND_LEN(s) PDF_PS_OPER_NAME_AND_LEN(s)
527
528
static int cmap_def_func(gs_memory_t *mem, pdf_ps_ctx_t *s, byte *buf, byte *bufend)
529
92.2k
{
530
92.2k
    int code = 0, code2 = 0;
531
92.2k
    pdf_cmap *pdficmap = (pdf_cmap *)s->client_data;
532
533
92.2k
    if (pdf_ps_stack_count(s) < 2) {
534
7.41k
        return pdf_ps_stack_pop(s, 1);
535
7.41k
    }
536
537
84.8k
    if (pdf_ps_obj_has_type(&s->cur[-1], PDF_PS_OBJ_NAME)) {
538
84.7k
        if (!memcmp(s->cur[-1].val.name, CMAP_NAME_AND_LEN("Registry"))) {
539
7.44k
            pdficmap->csi_reg.data = gs_alloc_bytes(mem, s->cur[0].size + 1, "cmap_def_func(Registry)");
540
7.44k
            if (pdficmap->csi_reg.data != NULL) {
541
7.44k
                pdficmap->csi_reg.size = s->cur[0].size;
542
7.44k
                if (pdf_ps_obj_has_type(&s->cur[0], PDF_PS_OBJ_STRING)) {
543
7.44k
                    memcpy(pdficmap->csi_reg.data, s->cur[0].val.string, s->cur[0].size);
544
7.44k
                }
545
0
                else {
546
0
                    memcpy(pdficmap->csi_reg.data, s->cur[0].val.name, s->cur[0].size);
547
0
                }
548
7.44k
                pdficmap->csi_reg.data[pdficmap->csi_reg.size] = '\0';
549
7.44k
            }
550
0
            else {
551
0
                code = gs_note_error(gs_error_VMerror);
552
0
            }
553
7.44k
        }
554
77.3k
        else if (!memcmp(s->cur[-1].val.name, CMAP_NAME_AND_LEN("Ordering"))) {
555
7.44k
            pdficmap->csi_ord.data = gs_alloc_bytes(mem, s->cur[0].size + 1, "cmap_def_func(Ordering)");
556
7.44k
            if (pdficmap->csi_ord.data != NULL) {
557
7.44k
                pdficmap->csi_ord.size = s->cur[0].size;
558
7.44k
                if (pdf_ps_obj_has_type(&s->cur[0], PDF_PS_OBJ_STRING))
559
7.44k
                    memcpy(pdficmap->csi_ord.data, s->cur[0].val.string, s->cur[0].size);
560
0
                else
561
0
                    memcpy(pdficmap->csi_ord.data, s->cur[0].val.name, s->cur[0].size);
562
7.44k
                pdficmap->csi_ord.data[pdficmap->csi_ord.size] = '\0';
563
7.44k
            }
564
0
            else {
565
0
                code = gs_note_error(gs_error_VMerror);
566
0
            }
567
7.44k
        }
568
69.8k
        else if (!memcmp(s->cur[-1].val.name, CMAP_NAME_AND_LEN("Supplement"))) {
569
16.1k
            if (pdf_ps_obj_has_type(&s->cur[0], PDF_PS_OBJ_INTEGER)) {
570
16.1k
                pdficmap->csi_supplement = s->cur[0].val.i;
571
16.1k
            }
572
1
            else {
573
1
                pdficmap->csi_supplement = 0;
574
1
            }
575
16.1k
        }
576
53.6k
        else if (!memcmp(s->cur[-1].val.name, CMAP_NAME_AND_LEN("CMapName"))) {
577
16.6k
            pdficmap->name.data = gs_alloc_bytes(mem, s->cur[0].size + 1, "cmap_def_func(CMapName)");
578
16.6k
            if (pdficmap->name.data != NULL) {
579
16.6k
                pdficmap->name.size = s->cur[0].size;
580
16.6k
                if (pdf_ps_obj_has_type(&s->cur[0], PDF_PS_OBJ_STRING))
581
0
                    memcpy(pdficmap->name.data, s->cur[0].val.string, s->cur[0].size);
582
16.6k
                else
583
16.6k
                    memcpy(pdficmap->name.data, s->cur[0].val.name, s->cur[0].size);
584
16.6k
                pdficmap->name.data[pdficmap->name.size] = '\0';
585
16.6k
            }
586
0
            else {
587
0
                code = gs_note_error(gs_error_VMerror);
588
0
            }
589
16.6k
        }
590
37.0k
        else if (!memcmp(s->cur[-1].val.name, CMAP_NAME_AND_LEN("CMapVersion"))) {
591
6.78k
            if (pdf_ps_obj_has_type(&s->cur[0], PDF_PS_OBJ_INTEGER)) {
592
84
                pdficmap->vers = (float)s->cur[0].val.i;
593
84
            }
594
6.69k
            else if (pdf_ps_obj_has_type(&s->cur[0], PDF_PS_OBJ_FLOAT)){
595
6.69k
                pdficmap->vers = s->cur[0].val.f;
596
6.69k
            }
597
0
            else {
598
0
                pdficmap->vers = (float)0;
599
0
            }
600
6.78k
        }
601
30.2k
        else if (!memcmp(s->cur[-1].val.name, CMAP_NAME_AND_LEN("CMapType"))) {
602
16.2k
            if (pdf_ps_obj_has_type(&s->cur[0], PDF_PS_OBJ_INTEGER)) {
603
16.2k
                pdficmap->cmaptype = s->cur[0].val.i;
604
16.2k
            }
605
0
            else {
606
0
                pdficmap->cmaptype = 1;
607
0
            }
608
16.2k
        }
609
13.9k
        else if (!memcmp(s->cur[-1].val.name, CMAP_NAME_AND_LEN("XUID"))) {
610
6.71k
            if (pdf_ps_obj_has_type(&s->cur[0], PDF_PS_OBJ_ARRAY)) {
611
6.71k
                int len = s->cur->size;
612
6.71k
                pdficmap->uid.xvalues = (long *)gs_alloc_bytes(mem, len * sizeof(*pdficmap->uid.xvalues), "cmap_def_func(XUID)");
613
6.71k
                if (pdficmap->uid.xvalues != NULL) {
614
6.71k
                     int i;
615
6.71k
                     pdf_ps_stack_object_t *a = s->cur->val.arr;
616
6.71k
                     pdficmap->uid.id = -len;
617
33.4k
                     for (i = 0; i < len; i++) {
618
26.7k
                         if (pdf_ps_obj_has_type(&a[i], PDF_PS_OBJ_INTEGER)) {
619
26.7k
                             pdficmap->uid.xvalues[i] = (long)a[i].val.i;
620
26.7k
                         }
621
0
                         else {
622
0
                             pdficmap->uid.xvalues[i] = 0;
623
0
                         }
624
26.7k
                     }
625
6.71k
                }
626
0
                else {
627
0
                    code = gs_note_error(gs_error_VMerror);
628
0
                }
629
6.71k
            }
630
6.71k
        }
631
7.23k
        else if (!memcmp(s->cur[-1].val.name, CMAP_NAME_AND_LEN("WMode"))) {
632
6.90k
            if (pdf_ps_obj_has_type(&s->cur[0], PDF_PS_OBJ_INTEGER)) {
633
6.90k
                pdficmap->wmode = s->cur[0].val.i;
634
6.90k
            }
635
0
            else {
636
0
                pdficmap->wmode = 0;
637
0
            }
638
6.90k
        }
639
84.7k
    }
640
641
84.8k
    code2 = pdf_ps_stack_pop(s, 2);
642
84.8k
    if (code < 0)
643
0
        return code;
644
84.8k
    else
645
84.8k
        return code2;
646
84.8k
}
647
648
static pdf_ps_oper_list_t cmap_oper_list[] =
649
{
650
  {PDF_PS_OPER_NAME_AND_LEN("usecmap"), cmap_usecmap_func},
651
  {PDF_PS_OPER_NAME_AND_LEN("usefont"), ps_pdf_null_oper_func},
652
  {PDF_PS_OPER_NAME_AND_LEN("beginusematrix"), ps_pdf_null_oper_func},
653
  {PDF_PS_OPER_NAME_AND_LEN("endusematrix"), ps_pdf_null_oper_func},
654
  {PDF_PS_OPER_NAME_AND_LEN("begincodespacerange"), pdf_ps_pop_and_pushmark_func},
655
  {PDF_PS_OPER_NAME_AND_LEN("endcodespacerange"), cmap_endcodespacerange_func},
656
  {PDF_PS_OPER_NAME_AND_LEN("begincmap"), ps_pdf_null_oper_func},
657
  {PDF_PS_OPER_NAME_AND_LEN("beginbfchar"), pdf_ps_pop_and_pushmark_func},
658
  {PDF_PS_OPER_NAME_AND_LEN("endbfchar"), cmap_endbfchar_func},
659
  {PDF_PS_OPER_NAME_AND_LEN("beginbfrange"), pdf_ps_pop_and_pushmark_func},
660
  {PDF_PS_OPER_NAME_AND_LEN("endbfrange"), cmap_endfbrange_func},
661
  {PDF_PS_OPER_NAME_AND_LEN("begincidchar"), pdf_ps_pop_and_pushmark_func},
662
  {PDF_PS_OPER_NAME_AND_LEN("endcidchar"), cmap_endcidchar_func},
663
  {PDF_PS_OPER_NAME_AND_LEN("begincidrange"), pdf_ps_pop_and_pushmark_func},
664
  {PDF_PS_OPER_NAME_AND_LEN("endcidrange"), cmap_endcidrange_func},
665
  {PDF_PS_OPER_NAME_AND_LEN("beginnotdefchar"), pdf_ps_pop_and_pushmark_func},
666
  {PDF_PS_OPER_NAME_AND_LEN("endnotdefchar"), cmap_endnotdefchar_func},
667
  {PDF_PS_OPER_NAME_AND_LEN("beginnotdefrange"), pdf_ps_pop_and_pushmark_func},
668
  {PDF_PS_OPER_NAME_AND_LEN("endnotdefrange"), cmap_endnotdefrange_func},
669
  {PDF_PS_OPER_NAME_AND_LEN("findresource"), clear_stack_oper_func},
670
  {PDF_PS_OPER_NAME_AND_LEN("dict"), pdf_ps_pop_oper_func},
671
  {PDF_PS_OPER_NAME_AND_LEN("begin"), ps_pdf_null_oper_func},
672
  {PDF_PS_OPER_NAME_AND_LEN("end"), ps_pdf_null_oper_func},
673
  {PDF_PS_OPER_NAME_AND_LEN("pop"), ps_pdf_null_oper_func},
674
  {PDF_PS_OPER_NAME_AND_LEN("def"), cmap_def_func},
675
  {PDF_PS_OPER_NAME_AND_LEN("dup"), ps_pdf_null_oper_func},
676
  {PDF_PS_OPER_NAME_AND_LEN("defineresource"), clear_stack_oper_func},
677
  {PDF_PS_OPER_NAME_AND_LEN("beginrearrangedfont"), clear_stack_oper_func}, /* we should never see this */
678
  {NULL, 0, NULL}
679
};
680
681
static int
682
pdf_cmap_open_file(pdf_context *ctx, gs_string *cmap_name, byte **buf, int64_t *buflen)
683
6.68k
{
684
6.68k
    int code = 0;
685
6.68k
    stream *s;
686
6.68k
    char fname[gp_file_name_sizeof];
687
6.68k
    const char *path_pfx = "CMap/";
688
6.68k
    fname[0] = '\0';
689
690
6.68k
    if (strlen(path_pfx) + cmap_name->size >= gp_file_name_sizeof)
691
6
        return_error(gs_error_rangecheck);
692
693
6.67k
    strncat(fname, path_pfx, strlen(path_pfx));
694
6.67k
    strncat(fname, (char *)cmap_name->data, cmap_name->size);
695
6.67k
    code = pdfi_open_resource_file(ctx, (const char *)fname, (const int)strlen(fname), &s);
696
6.67k
    if (code >= 0) {
697
6.63k
        sfseek(s, 0, SEEK_END);
698
6.63k
        *buflen = sftell(s);
699
6.63k
        sfseek(s, 0, SEEK_SET);
700
6.63k
        *buf = gs_alloc_bytes(ctx->memory, *buflen, "pdf_cmap_open_file(buf)");
701
6.63k
        if (*buf != NULL) {
702
6.63k
            sfread(*buf, 1, *buflen, s);
703
6.63k
        }
704
0
        else {
705
0
            code = gs_note_error(gs_error_VMerror);
706
0
        }
707
6.63k
        sfclose(s);
708
6.63k
    }
709
6.67k
    return code;
710
6.68k
}
711
712
static int
713
pdfi_make_gs_cmap(gs_memory_t *mem, pdf_cmap *pdficmap)
714
16.8k
{
715
16.8k
    int code = 0, i;
716
16.8k
    gs_cmap_adobe1_t *pgscmap = 0;
717
16.8k
    gx_cmap_lookup_range_t *lookups, *ndlookups = NULL;
718
16.8k
    pdfi_cmap_range_map_t *l;
719
    /* FIXME: We have to use gs_cmap_adobe1_alloc() to get the cmap procs
720
       but even if it gets passed num_ranges = 0 it still allocates
721
       a zero length array. Change gs_cmap_adobe1_alloc to work better
722
     */
723
16.8k
    if ((code = gs_cmap_adobe1_alloc(&pgscmap, pdficmap->wmode,
724
16.8k
                                     pdficmap->name.data,
725
16.8k
                                     pdficmap->name.size,
726
16.8k
                                     1,
727
16.8k
                                     0, 0, 0, 0, 0, mem)) >= 0) {
728
16.8k
        gs_free_object(mem, pgscmap->code_space.ranges, "empty ranges");
729
730
16.8k
        lookups = gs_alloc_struct_array(mem, pdficmap->cmap_range.numrangemaps,
731
16.8k
                               gx_cmap_lookup_range_t,
732
16.8k
                               &st_cmap_lookup_range_element,
733
16.8k
                               "pdfi_make_gs_cmap(lookup ranges)");
734
16.8k
        if (lookups == NULL) {
735
3
            gs_free_object(mem, pgscmap, "pdfi_make_gs_cmap(pgscmap)");
736
3
            code = gs_note_error(gs_error_VMerror);
737
3
            goto done;
738
3
        }
739
16.8k
        if (pdficmap->notdef_cmap_range.numrangemaps > 0){
740
87
            ndlookups = gs_alloc_struct_array(mem, pdficmap->notdef_cmap_range.numrangemaps,
741
87
                               gx_cmap_lookup_range_t,
742
87
                               &st_cmap_lookup_range_element,
743
87
                               "pdfi_make_gs_cmap(notdef lookup ranges)");
744
87
            if (ndlookups == NULL) {
745
0
                gs_free_object(mem, lookups, "pdfi_make_gs_cmap(lookups)");
746
0
                gs_free_object(mem, pgscmap, "pdfi_make_gs_cmap(pgscmap)");
747
0
                code = gs_note_error(gs_error_VMerror);
748
0
                goto done;
749
0
            }
750
87
        }
751
16.8k
        pgscmap->def.lookup = lookups;
752
16.8k
        pgscmap->def.num_lookup = pdficmap->cmap_range.numrangemaps;
753
16.8k
        pgscmap->notdef.lookup = ndlookups;
754
16.8k
        pgscmap->notdef.num_lookup = pdficmap->notdef_cmap_range.numrangemaps;
755
756
16.8k
        pgscmap->CIDSystemInfo[0].Registry.data = pdficmap->csi_reg.data;
757
16.8k
        pgscmap->CIDSystemInfo[0].Registry.size = pdficmap->csi_reg.size;
758
16.8k
        pgscmap->CIDSystemInfo[0].Ordering.data = pdficmap->csi_ord.data;
759
16.8k
        pgscmap->CIDSystemInfo[0].Ordering.size = pdficmap->csi_ord.size;
760
16.8k
        pgscmap->CIDSystemInfo[0].Supplement = pdficmap->csi_supplement;
761
16.8k
        memcpy(&pgscmap->code_space, &pdficmap->code_space, sizeof(pgscmap->code_space));
762
16.8k
        memcpy(&pgscmap->uid, &pdficmap->uid, sizeof(pdficmap->uid));
763
16.8k
        l = pdficmap->cmap_range.ranges;
764
24.7M
        for (i = 0; i < pdficmap->cmap_range.numrangemaps && l != NULL; i++) {
765
24.7M
            memcpy(&lookups[i], &l->range, sizeof(gx_cmap_lookup_range_t));
766
24.7M
            l = l->next;
767
24.7M
        }
768
769
16.8k
        l = pdficmap->notdef_cmap_range.ranges;
770
16.9k
        for (i = 0; i < pdficmap->notdef_cmap_range.numrangemaps && l != NULL; i++) {
771
87
            memcpy(&ndlookups[i], &l->range, sizeof(gx_cmap_lookup_range_t));
772
87
            l = l->next;
773
87
        }
774
775
16.8k
        pdficmap->gscmap = pgscmap;
776
16.8k
    }
777
778
16.8k
done:
779
16.8k
    return code;
780
16.8k
}
781
782
int
783
pdfi_read_cmap(pdf_context *ctx, pdf_obj *cmap, pdf_cmap **pcmap)
784
17.2k
{
785
17.2k
    int code = 0;
786
17.2k
    pdf_cmap pdficm[3] = {0};
787
17.2k
    pdf_cmap *pdfi_cmap = &(pdficm[1]);
788
17.2k
    byte *buf = NULL;
789
17.2k
    int64_t buflen = 0;
790
17.2k
    pdf_ps_ctx_t cmap_ctx;
791
792
17.2k
    pdfi_cmap->ctx = ctx;
793
17.2k
    switch (pdfi_type_of(cmap)) {
794
6.68k
        case PDF_NAME:
795
6.68k
        {
796
6.68k
            gs_string cmname;
797
6.68k
            pdf_name *cmapn = (pdf_name *)cmap;
798
6.68k
            cmname.data = cmapn->data;
799
6.68k
            cmname.size = cmapn->length;
800
6.68k
            code = pdf_cmap_open_file(ctx, &cmname, &buf, &buflen);
801
6.68k
            if (code < 0)
802
41
                goto error_out;
803
6.63k
            break;
804
6.68k
        }
805
10.5k
        case PDF_STREAM:
806
10.5k
        {
807
10.5k
            pdf_obj *ucmap;
808
10.5k
            pdf_cmap *upcmap = NULL;
809
10.5k
            pdf_dict *cmap_dict = NULL;
810
811
10.5k
            code = pdfi_dict_from_obj(ctx, cmap, &cmap_dict);
812
10.5k
            if (code < 0)
813
0
                goto error_out;
814
815
10.5k
            code = pdfi_dict_knownget(ctx, cmap_dict, "UseCMap", &ucmap);
816
10.5k
            if (code > 0) {
817
0
                code = pdfi_read_cmap(ctx, ucmap, &upcmap);
818
0
                pdfi_countdown(ucmap);
819
0
                if (code >= 0) {
820
0
                    gx_code_space_range_t * ranges =
821
0
                         (gx_code_space_range_t *)gs_alloc_byte_array(ctx->memory, upcmap->code_space.num_ranges,
822
0
                          sizeof(gx_code_space_range_t), "cmap_usecmap_func(ranges)");
823
0
                    if (ranges != NULL) {
824
0
                        int i;
825
0
                        memcpy(&pdfi_cmap->code_space, &upcmap->code_space, sizeof(pdfi_cmap->code_space));
826
0
                        for (i = 0; i < upcmap->code_space.num_ranges; i++) {
827
0
                            memcpy(&(ranges[i]), &(upcmap->code_space.ranges[i]), sizeof(ranges[i]));
828
0
                        }
829
0
                        pdfi_cmap->code_space.ranges = ranges;
830
0
                        memcpy(&pdfi_cmap->cmap_range, &upcmap->cmap_range, sizeof(pdfi_cmap->cmap_range));
831
0
                        memcpy(&pdfi_cmap->notdef_cmap_range, &upcmap->notdef_cmap_range, sizeof(pdfi_cmap->notdef_cmap_range));
832
                        /* Once we've assumed control of these, NULL out entries for the sub-cmap. */
833
0
                        upcmap->cmap_range.ranges = NULL;
834
0
                        upcmap->notdef_cmap_range.ranges = NULL;
835
                        /* But we keep the subcmap itself because we rely on its storage */
836
0
                        pdfi_cmap->next = upcmap;
837
0
                    }
838
0
                }
839
0
                else {
840
0
                    pdfi_countdown(upcmap);
841
0
                }
842
0
            }
843
844
10.5k
            code = pdfi_stream_to_buffer(ctx, (pdf_stream *)cmap, &buf, &buflen);
845
10.5k
            if (code < 0) {
846
23
                goto error_out;
847
23
            }
848
10.5k
            break;
849
10.5k
        }
850
10.5k
        default:
851
3
            code = gs_note_error(gs_error_typecheck);
852
3
            goto error_out;
853
17.2k
    }
854
17.1k
    pdfi_cmap->ctx = ctx;
855
17.1k
    pdfi_cmap->buf = buf;
856
17.1k
    pdfi_cmap->buflen = buflen;
857
858
    /* In case of technically invalid CMap files which do not contain a CMapType, See Bug #690737.
859
     * This makes sure we clean up the CMap contents in pdfi_free_cmap() below.
860
     */
861
17.1k
    pdfi_cmap->cmaptype = 1;
862
863
17.1k
    pdfi_pscript_stack_init(ctx, cmap_oper_list, (void *)pdfi_cmap, &cmap_ctx);
864
865
17.1k
    code = pdfi_pscript_interpret(&cmap_ctx, buf, buflen);
866
17.1k
    pdfi_pscript_stack_finit(&cmap_ctx);
867
17.1k
    if (code < 0) goto error_out;
868
869
16.8k
    code = pdfi_make_gs_cmap(ctx->memory, pdfi_cmap);
870
871
16.8k
    if (code >= 0) {
872
16.8k
        *pcmap = (pdf_cmap *)gs_alloc_bytes(ctx->memory, sizeof(pdf_cmap), "pdfi_read_cmap(*pcmap)");
873
16.8k
        if (*pcmap != NULL) {
874
16.8k
            pdfi_cmap->type = PDF_CMAP;
875
16.8k
            pdfi_cmap->ctx = ctx;
876
16.8k
            pdfi_cmap->refcnt = 1;
877
16.8k
            pdfi_cmap->object_num = cmap->object_num;
878
16.8k
            pdfi_cmap->generation_num = cmap->generation_num;
879
16.8k
            pdfi_cmap->indirect_num = cmap->indirect_num;
880
16.8k
            pdfi_cmap->indirect_gen = cmap->indirect_gen;
881
16.8k
            memcpy(*pcmap, pdfi_cmap, sizeof(pdf_cmap));
882
16.8k
            pdfi_cmap = *pcmap;
883
            /* object_num can be zero if the dictionary was defined inline */
884
16.8k
            if (pdfi_cmap->object_num != 0) {
885
10.2k
                code = replace_cache_entry(ctx, (pdf_obj *)pdfi_cmap);
886
10.2k
            }
887
16.8k
        }
888
16.8k
    }
889
3
    else {
890
3
        goto error_out;
891
3
    }
892
16.8k
    return 0;
893
894
329
error_out:
895
329
    pdfi_free_cmap_contents(pdfi_cmap);
896
329
    memset(pdfi_cmap, 0x00, sizeof(pdf_cmap));
897
329
    return code;
898
16.8k
}
899
900
static int pdfi_free_cmap_contents(pdf_cmap *cmap)
901
17.2k
{
902
17.2k
    pdfi_cmap_range_map_t *pdfir;
903
17.2k
    gs_cmap_adobe1_t *pgscmap = cmap->gscmap;
904
905
17.2k
    if (pgscmap != NULL) {
906
16.8k
        gs_free_object(OBJ_MEMORY(cmap), pgscmap->def.lookup, "pdfi_free_cmap(def.lookup)");
907
16.8k
        gs_free_object(OBJ_MEMORY(cmap), pgscmap->notdef.lookup, "pdfi_free_cmap(notdef.lookup)");
908
16.8k
        (void)gs_cmap_free((gs_cmap_t *)pgscmap, OBJ_MEMORY(cmap));
909
16.8k
    }
910
17.2k
    gs_free_object(OBJ_MEMORY(cmap), cmap->code_space.ranges, "pdfi_free_cmap(code_space.ranges");
911
17.2k
    pdfir = cmap->cmap_range.ranges;
912
480M
    while (pdfir != NULL) {
913
480M
        pdfi_cmap_range_map_t *pdfir2 = pdfir->next;
914
480M
        gs_free_object(OBJ_MEMORY(cmap), pdfir, "pdfi_free_cmap(cmap_range.ranges");
915
480M
        pdfir = pdfir2;
916
480M
    }
917
17.2k
    pdfir = cmap->notdef_cmap_range.ranges;
918
17.2k
    while (pdfir != NULL) {
919
79
        pdfi_cmap_range_map_t *pdfir2 = pdfir->next;
920
79
        gs_free_object(OBJ_MEMORY(cmap), pdfir, "pdfi_free_cmap(cmap_range.ranges");
921
79
        pdfir = pdfir2;
922
79
    }
923
17.2k
    gs_free_object(OBJ_MEMORY(cmap), cmap->csi_reg.data, "pdfi_free_cmap(csi_reg.data");
924
17.2k
    gs_free_object(OBJ_MEMORY(cmap), cmap->csi_ord.data, "pdfi_free_cmap(csi_ord.data");
925
17.2k
    gs_free_object(OBJ_MEMORY(cmap), cmap->name.data, "pdfi_free_cmap(name.data");
926
17.2k
    gs_free_object(OBJ_MEMORY(cmap), cmap->uid.xvalues, "pdfi_free_cmap(xuid.xvalues");
927
17.2k
    pdfi_countdown(cmap->next);
928
17.2k
    gs_free_object(OBJ_MEMORY(cmap), cmap->buf, "pdfi_free_cmap(cmap->buf");
929
930
17.2k
    return 0;
931
17.2k
}
932
933
int pdfi_free_cmap(pdf_obj *cmapo)
934
16.8k
{
935
16.8k
    pdf_cmap *cmap = (pdf_cmap *)cmapo;
936
    /*
937
     * Note there is some inconsistency in the various specifications regarding CMapType; the
938
     * Adobe tech note 5014 specifically says it only documents CMaps with a CmapType of 0, the
939
     * PLRM says that CMapType can be 0 or 1, and the two are equivalent, the PDF Reference Manual
940
     * doesn't say, it just refers to tech note 5014 but the example has a CMapType of 1. The PDF
941
     * Reference does describe ToUnicode CMaps which have a CMapType of 2.
942
     */
943
    /* Well it seems we have PDF files which use CMapType 2 CMaps as values for a /Encoding, which is
944
     * I believe incorrect, as these are ToUnicode CMaps....
945
     * There's nothing for it, we'll just haev to free all CMaps for now. Note for Chris when implementing
946
     * ToUnicode CMaps, we'll obviously have to rely on the context to know whether a CMap is an Encoding
947
     * or a ToUnicode, we cna't use the CmMapType, just as you suspected. :-(
948
     * See bug #696449 633_R00728_E.pdf
949
     */
950
    /*
951
     * For now, we represent ToUnicode CMaps (CMapType 2) in the same data structures as regular CMaps
952
     * (CMapType 0/1) so there is no reason (yet!) to differentiate between the two.
953
     */
954
955
16.8k
    pdfi_free_cmap_contents(cmap);
956
16.8k
    gs_free_object(OBJ_MEMORY(cmap), cmap, "pdfi_free_cmap(cmap");
957
16.8k
    return 0;
958
16.8k
}