Coverage Report

Created: 2026-07-24 07:44

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ghostpdl/pdf/pdf_cmap.c
Line
Count
Source
1
/* Copyright (C) 2020-2026 Artifex Software, Inc.
2
   All Rights Reserved.
3
4
   This software is provided AS-IS with no warranty, either express or
5
   implied.
6
7
   This software is distributed under license and may not be copied,
8
   modified or distributed except as expressly authorized under the terms
9
   of the license contained in the file LICENSE in this distribution.
10
11
   Refer to licensing information at http://www.artifex.com or contact
12
   Artifex Software, Inc.,  39 Mesa Street, Suite 108A, San Francisco,
13
   CA 94129, USA, for further information.
14
*/
15
16
#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
340
{
33
340
    pdf_cmap *pdficmap = (pdf_cmap *)s->client_data;
34
340
    pdf_name *n = NULL;
35
340
    pdf_cmap *upcmap = NULL;
36
340
    int code = 0;
37
38
340
    if (pdf_ps_stack_count(s) < 1)
39
3
        return_error(gs_error_stackunderflow);
40
41
    /* If we've already got some definitions, ignore the usecmap op */
42
337
    if (pdficmap->code_space.num_ranges == 0) {
43
337
        byte *nstr = NULL;
44
337
        int len = s->cur[0].size;
45
46
337
        if (pdf_ps_obj_has_type(&(s->cur[0]), PDF_PS_OBJ_NAME)) {
47
337
            nstr = s->cur[0].val.name;
48
337
        }
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
337
        if (code >= 0)
56
337
            code = pdfi_name_alloc(pdficmap->ctx, nstr, len, (pdf_obj **)&n);
57
337
        if (code >= 0) {
58
337
            pdfi_countup(n);
59
337
            code = pdfi_read_cmap(pdficmap->ctx, (pdf_obj *)n, &upcmap);
60
337
            if (code >= 0) {
61
319
                gx_code_space_range_t * ranges =
62
319
                         (gx_code_space_range_t *)gs_alloc_byte_array(mem, upcmap->code_space.num_ranges,
63
319
                          sizeof(gx_code_space_range_t), "cmap_usecmap_func(ranges)");
64
319
                if (ranges != NULL) {
65
319
                    int i;
66
319
                    memcpy(&pdficmap->code_space, &upcmap->code_space, sizeof(pdficmap->code_space));
67
749
                    for (i = 0; i < upcmap->code_space.num_ranges; i++) {
68
430
                        memcpy(&(ranges[i]), &(upcmap->code_space.ranges[i]), sizeof(ranges[i]));
69
430
                    }
70
319
                    pdficmap->code_space.ranges = ranges;
71
319
                    memcpy(&pdficmap->cmap_range, &upcmap->cmap_range, sizeof(pdficmap->cmap_range));
72
319
                    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
319
                    upcmap->cmap_range.ranges = NULL;
75
319
                    upcmap->notdef_cmap_range.ranges = NULL;
76
                    /* But we keep the subcmap itself because we rely on its storage */
77
319
                    pdficmap->next = upcmap;
78
319
                    pdfi_countup(upcmap);
79
319
                }
80
319
            }
81
337
        }
82
337
    }
83
337
    pdfi_countdown(upcmap);
84
337
    pdfi_countdown(n);
85
337
    if (code < 0) {
86
18
        (void)pdf_ps_stack_pop(s, 1);
87
18
        return code;
88
18
    }
89
319
    return pdf_ps_stack_pop(s, 1);
90
337
}
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
67.8k
{
102
67.8k
    pdf_cmap *pdficmap = (pdf_cmap *)s->client_data;
103
67.8k
    int i, numranges, to_pop = pdf_ps_stack_count_to_mark(s, PDF_PS_OBJ_MARK);
104
67.8k
    gx_code_space_t *code_space = &pdficmap->code_space;
105
67.8k
    int nr = code_space->num_ranges;
106
67.8k
    gx_code_space_range_t *gcsr = code_space->ranges;
107
108
    /* increment to_pop to cover the mark object */
109
67.8k
    numranges = to_pop++;
110
67.8k
    while (numranges % 2) numranges--;
111
112
    /* The following hard limit is an implementation limit */
113
67.8k
    if (numranges < 0 || numranges + 1 > PDF_PS_STACK_MAX) {
114
361
        pdfi_set_error(s->pdfi_ctx, 0, NULL, E_PDF_BAD_TYPE0_CMAP, "cmap_endcodespacerange_func", NULL);
115
361
        return_error(gs_error_syntaxerror);
116
361
    }
117
118
    /* The following "soft" limit is according to the spec */
119
67.4k
    if (numranges > 200) {
120
0
        int code;
121
0
        if ((code = pdfi_set_warning_stop(s->pdfi_ctx, gs_note_error(gs_error_syntaxerror), NULL, W_PDF_LIMITCHECK_TYPE0_CMAP, "cmap_endcodespacerange_func", NULL)) < 0) {
122
0
            (void)pdf_ps_stack_pop(s, to_pop);
123
0
            return code;
124
0
        }
125
0
    }
126
127
67.4k
    if (numranges > 0
128
67.4k
     && pdf_ps_obj_has_type(&(s->cur[0]), PDF_PS_OBJ_STRING)  && s->cur[0].size <= MAX_CMAP_CODE_SIZE
129
67.4k
     && pdf_ps_obj_has_type(&(s->cur[-1]), PDF_PS_OBJ_STRING) && s->cur[-1].size <= MAX_CMAP_CODE_SIZE) {
130
131
67.3k
        code_space->num_ranges += numranges >> 1;
132
133
67.3k
        code_space->ranges = (gx_code_space_range_t *)gs_alloc_byte_array(mem, code_space->num_ranges,
134
67.3k
                          sizeof(gx_code_space_range_t), "cmap_endcodespacerange_func(ranges)");
135
67.3k
        if (code_space->ranges != NULL) {
136
67.3k
            if (nr > 0) {
137
59
                memcpy(code_space->ranges, gcsr, nr * sizeof(gx_code_space_range_t));
138
59
                gs_free_object(mem, gcsr, "cmap_endcodespacerange_func(gcsr");
139
59
            }
140
141
135k
            for (i = nr; i < code_space->num_ranges; i++) {
142
68.1k
                int si = i - nr;
143
68.1k
                int s1;
144
68.1k
                int s2;
145
146
68.1k
                if (!pdf_ps_obj_has_type(&s->cur[-((si * 2) + 1)], PDF_PS_OBJ_STRING) || !pdf_ps_obj_has_type(&s->cur[-(si * 2)], PDF_PS_OBJ_STRING)) {
147
0
                    gs_free_object(mem, code_space->ranges, "cmap_endcodespacerange_func(gcsr");
148
0
                    code_space->ranges = NULL;
149
0
                    (void)pdf_ps_stack_pop(s, to_pop);
150
0
                    return_error(gs_error_typecheck);
151
0
                }
152
68.1k
                s1 = s->cur[-((si * 2) + 1)].size < MAX_CMAP_CODE_SIZE ? s->cur[-((si * 2) + 1)].size : MAX_CMAP_CODE_SIZE;
153
68.1k
                s2 = s->cur[-(si * 2)].size < MAX_CMAP_CODE_SIZE ? s->cur[-(si * 2)].size : MAX_CMAP_CODE_SIZE;
154
68.1k
                memcpy(code_space->ranges[i].first, s->cur[-((si * 2) + 1)].val.string, s1);
155
68.1k
                memcpy(code_space->ranges[i].last, s->cur[-(si * 2)].val.string, s2);
156
68.1k
                code_space->ranges[i].size = s->cur[-(si * 2)].size;
157
68.1k
            }
158
67.3k
        }
159
0
        else {
160
0
            (void)pdf_ps_stack_pop(s, to_pop);
161
0
            return_error(gs_error_VMerror);
162
0
        }
163
67.3k
    }
164
67.4k
    return pdf_ps_stack_pop(s, to_pop);
165
67.4k
}
166
167
static int cmap_insert_map(pdfi_cmap_range_t *cmap_range, pdfi_cmap_range_map_t *pdfir)
168
12.6M
{
169
12.6M
    if (cmap_range->ranges == NULL) {
170
65.5k
        cmap_range->ranges = cmap_range->ranges_tail = pdfir;
171
65.5k
    }
172
12.5M
    else {
173
12.5M
        cmap_range->ranges_tail->next = pdfir;
174
12.5M
        cmap_range->ranges_tail = pdfir;
175
12.5M
    }
176
12.6M
    cmap_range->numrangemaps++;
177
12.6M
    return 0;
178
12.6M
}
179
180
static int general_endcidrange_func(gs_memory_t *mem, pdf_ps_ctx_t *s, pdf_cmap *pdficmap, pdfi_cmap_range_t *cmap_range)
181
117k
{
182
117k
    int ncodemaps, to_pop = pdf_ps_stack_count_to_mark(s, PDF_PS_OBJ_MARK);
183
117k
    unsigned int i, j;
184
117k
    pdfi_cmap_range_map_t *pdfir;
185
117k
    pdf_ps_stack_object_t *stobj;
186
187
    /* increment to_pop to cover the mark object */
188
117k
    ncodemaps = to_pop++;
189
    /* mapping should have 3 objects on the stack:
190
     * startcode, endcode and basecid
191
     */
192
117k
    while (ncodemaps % 3) ncodemaps--;
193
194
    /* The following hard limit is an implementation limit */
195
117k
    if (ncodemaps < 0 || ncodemaps + 1 > PDF_PS_STACK_MAX) {
196
9
        pdfi_set_error(s->pdfi_ctx, 0, NULL, E_PDF_BAD_TYPE0_CMAP, "general_endcidrange_func", NULL);
197
9
        return_error(gs_error_syntaxerror);
198
9
    }
199
200
    /* The following "soft" limit is according to the spec */
201
117k
    if (ncodemaps > 300) {
202
2
        int code;
203
2
        if ((code = pdfi_set_warning_stop(s->pdfi_ctx, gs_note_error(gs_error_syntaxerror), NULL, W_PDF_LIMITCHECK_TYPE0_CMAP, "general_endcidrange_func", NULL)) < 0) {
204
0
            (void)pdf_ps_stack_pop(s, to_pop);
205
0
            return code;
206
0
        }
207
2
    }
208
209
117k
    stobj = &s->cur[-ncodemaps] + 1;
210
211
10.0M
    for (i = 0; i < ncodemaps; i += 3) {
212
9.91M
        int preflen, valuelen;
213
214
9.91M
        if (pdf_ps_obj_has_type(&(stobj[i + 2]), PDF_PS_OBJ_INTEGER)
215
9.91M
        &&  pdf_ps_obj_has_type(&(stobj[i + 1]), PDF_PS_OBJ_STRING)
216
9.91M
        &&  pdf_ps_obj_has_type(&(stobj[i]), PDF_PS_OBJ_STRING)
217
9.91M
        &&  pdf_ps_obj_size(&(stobj[i])) > 0
218
9.91M
        &&  pdf_ps_obj_size(&(stobj[i])) == pdf_ps_obj_size(&(stobj[i + 1]))){
219
220
9.91M
            uint cidbase = stobj[i + 2].val.i;
221
222
            /* First, find the length of the prefix */
223
20.3M
            for (preflen = 0; preflen < stobj[i].size; preflen++) {
224
19.8M
                if(stobj[i].val.string[preflen] != stobj[i + 1].val.string[preflen]) {
225
9.43M
                    break;
226
9.43M
                }
227
19.8M
            }
228
229
9.91M
            if (preflen == stobj[i].size) {
230
480k
                preflen = 1;
231
480k
            }
232
233
9.91M
            if (preflen > MAX_CMAP_CODE_SIZE || stobj[i].size - preflen > MAX_CMAP_CODE_SIZE || stobj[i + 1].size - preflen > MAX_CMAP_CODE_SIZE
234
9.91M
                || ((int64_t)stobj[i].size) - preflen < 0 || ((int64_t)stobj[i + 1].size) - preflen < 0) {
235
0
                (void)pdf_ps_stack_pop(s, to_pop);
236
0
                return_error(gs_error_syntaxerror);
237
0
            }
238
239
            /* Find how many bytes we need for the cidbase value */
240
            /* We always store at least two bytes for the cidbase value */
241
9.91M
            for (valuelen = 16; valuelen < 32 && (cidbase >> valuelen) > 0; valuelen += 1)
242
9.91M
                DO_NOTHING;
243
244
9.91M
            valuelen = ((valuelen + 7) & ~7) >> 3;
245
246
            /* The prefix is already directly in the gx_cmap_lookup_range_t
247
             * We need to store the lower and upper character codes, after lopping the prefix
248
             * off them. The upper and lower codes must be the same number of bytes.
249
             */
250
9.91M
            j = sizeof(pdfi_cmap_range_map_t) + 2 * (stobj[i].size - preflen) + valuelen;
251
252
9.91M
            pdfir = (pdfi_cmap_range_map_t *)gs_alloc_bytes(mem, j, "cmap_endcidrange_func(pdfi_cmap_range_map_t)");
253
9.91M
            if (pdfir != NULL) {
254
9.91M
                gx_cmap_lookup_range_t *gxr = &pdfir->range;
255
9.91M
                pdfir->next = NULL;
256
9.91M
                gxr->num_entries = 1;
257
9.91M
                gxr->keys.data = (byte *)&(pdfir[1]);
258
9.91M
                gxr->values.data = gxr->keys.data + 2 * (stobj[i].size - preflen);
259
260
9.91M
                gxr->cmap = NULL;
261
9.91M
                gxr->font_index = 0;
262
9.91M
                gxr->key_is_range = true;
263
9.91M
                gxr->value_type = cmap_range == &(pdficmap->cmap_range) ? CODE_VALUE_CID : CODE_VALUE_NOTDEF;
264
9.91M
                gxr->key_prefix_size = preflen;
265
9.91M
                gxr->key_size = stobj[i].size - gxr->key_prefix_size;
266
9.91M
                memcpy(gxr->key_prefix, stobj[i].val.string, gxr->key_prefix_size);
267
268
9.91M
                memcpy(gxr->keys.data, stobj[i].val.string + gxr->key_prefix_size, stobj[i].size - gxr->key_prefix_size);
269
9.91M
                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);
270
271
9.91M
                gxr->keys.size = (stobj[i].size - gxr->key_prefix_size) + (stobj[i + 1].size - gxr->key_prefix_size);
272
29.7M
                for (j = 0; j < valuelen; j++) {
273
19.8M
                    gxr->values.data[j] = (cidbase >> ((valuelen - 1 - j) * 8)) & 255;
274
19.8M
                }
275
9.91M
                gxr->value_size = valuelen; /* I'm not sure.... */
276
9.91M
                gxr->values.size = valuelen;
277
9.91M
                if (cmap_insert_map(cmap_range, pdfir) < 0) break;
278
9.91M
            }
279
0
            else {
280
0
                (void)pdf_ps_stack_pop(s, to_pop);
281
0
                return_error(gs_error_VMerror);
282
0
            }
283
9.91M
        }
284
9.91M
    }
285
117k
    return pdf_ps_stack_pop(s, to_pop);
286
117k
}
287
288
static int cmap_endcidrange_func(gs_memory_t *mem, pdf_ps_ctx_t *s, byte *buf, byte *bufend)
289
116k
{
290
116k
    pdf_cmap *pdficmap = (pdf_cmap *)s->client_data;
291
116k
    return general_endcidrange_func(mem, s, pdficmap, &pdficmap->cmap_range);
292
116k
}
293
294
static int cmap_endnotdefrange_func(gs_memory_t *mem, pdf_ps_ctx_t *s, byte *buf, byte *bufend)
295
317
{
296
317
    pdf_cmap *pdficmap = (pdf_cmap *)s->client_data;
297
317
    return general_endcidrange_func(mem, s, pdficmap, &pdficmap->notdef_cmap_range);
298
317
}
299
300
static int cmap_endfbrange_func(gs_memory_t *mem, pdf_ps_ctx_t *s, byte *buf, byte *bufend)
301
16.9k
{
302
16.9k
    pdf_cmap *pdficmap = (pdf_cmap *)s->client_data;
303
16.9k
    int ncodemaps, to_pop = pdf_ps_stack_count_to_mark(s, PDF_PS_OBJ_MARK);
304
16.9k
    unsigned int i, j;
305
16.9k
    pdfi_cmap_range_map_t *pdfir;
306
16.9k
    pdf_ps_stack_object_t *stobj;
307
308
    /* increment to_pop to cover the mark object */
309
16.9k
    ncodemaps = to_pop++;
310
    /* mapping should have 3 objects on the stack
311
     */
312
17.6k
    while (ncodemaps % 3) ncodemaps--;
313
314
    /* The following hard limit is an implementation limit */
315
16.9k
    if (ncodemaps < 0 || ncodemaps + 1 > PDF_PS_STACK_MAX) {
316
31
        pdfi_set_error(s->pdfi_ctx, 0, NULL, E_PDF_BAD_TYPE0_CMAP, "cmap_endfbrange_func", NULL);
317
31
        return_error(gs_error_syntaxerror);
318
31
    }
319
    /* The following "soft" limit is according to the spec */
320
321
16.9k
    if (ncodemaps > 300) {
322
164
        int code;
323
164
        if ((code = pdfi_set_warning_stop(s->pdfi_ctx, gs_note_error(gs_error_syntaxerror), NULL, W_PDF_LIMITCHECK_TYPE0_CMAP, "cmap_endfbrange_func", NULL)) < 0) {
324
0
            (void)pdf_ps_stack_pop(s, to_pop);
325
0
            return code;
326
0
        }
327
164
    }
328
329
16.9k
    stobj = &s->cur[-ncodemaps] + 1;
330
344k
    for (i = 0; i < ncodemaps; i += 3) {
331
        /* Lazy: to make the loop below simpler, put single
332
           values into a one element array
333
         */
334
327k
        if (pdf_ps_obj_has_type(&(stobj[i + 2]), PDF_PS_OBJ_STRING)) {
335
314k
            pdf_ps_stack_object_t *arr;
336
314k
            arr = (pdf_ps_stack_object_t *) gs_alloc_bytes(mem, sizeof(pdf_ps_stack_object_t), "cmap_endfbrange_func(pdf_ps_stack_object_t");
337
314k
            if (arr == NULL) {
338
0
                (void)pdf_ps_stack_pop(s, to_pop);
339
0
                return_error(gs_error_VMerror);
340
0
            }
341
314k
            else {
342
314k
                memcpy(arr, &(stobj[i + 2]), sizeof(pdf_ps_stack_object_t));
343
314k
                pdf_ps_make_array(&(stobj[i + 2]), arr, 1);
344
314k
            }
345
314k
        }
346
327k
    }
347
348
16.9k
    stobj = &s->cur[-ncodemaps] + 1;
349
350
343k
    for (i = 0; i < ncodemaps; i += 3) {
351
326k
        int preflen, valuelen;
352
353
326k
        if (pdf_ps_obj_has_type(&(stobj[i + 2]), PDF_PS_OBJ_ARRAY)
354
318k
        &&  pdf_ps_obj_has_type(&(stobj[i + 1]), PDF_PS_OBJ_STRING)
355
314k
        &&  pdf_ps_obj_has_type(&(stobj[i]), PDF_PS_OBJ_STRING)
356
312k
        &&  pdf_ps_obj_size(&(stobj[i + 1])) > 0
357
312k
        &&  pdf_ps_obj_size(&(stobj[i])) > 0){
358
359
312k
            uint cidbase;
360
312k
            int m, size;
361
362
312k
            if (stobj[i + 2].size < 1 || stobj[i].size != stobj[i + 1].size)
363
4.22k
                continue;
364
365
307k
            else if (stobj[i + 2].size == 1) {
366
306k
                if (stobj[i + 2].val.arr[0].type != PDF_PS_OBJ_STRING)
367
0
                     continue;
368
369
306k
                size = stobj[i + 2].val.arr[0].size;
370
371
306k
                cidbase = 0;
372
924k
                for (m = 0; m < size; m++) {
373
618k
                    cidbase |= stobj[i + 2].val.arr[0].val.string[size - m - 1] << (8 * m);
374
618k
                }
375
376
                /* First, find the length of the prefix */
377
667k
                for (preflen = 0; preflen < stobj[i].size; preflen++) {
378
517k
                    if(stobj[i].val.string[preflen] != stobj[i + 1].val.string[preflen]) {
379
156k
                        break;
380
156k
                    }
381
517k
                }
382
383
306k
                if (preflen == stobj[i].size) {
384
149k
                    preflen = 1;
385
149k
                }
386
387
306k
                if (preflen > MAX_CMAP_CODE_SIZE || stobj[i].size - preflen > MAX_CMAP_CODE_SIZE || stobj[i + 1].size - preflen > MAX_CMAP_CODE_SIZE
388
306k
                    || ((int64_t)stobj[i].size) - preflen < 0 || ((int64_t)stobj[i + 1].size) - preflen < 0) {
389
15
                    (void)pdf_ps_stack_pop(s, to_pop);
390
15
                    return_error(gs_error_syntaxerror);
391
15
                }
392
393
                /* Find how many bytes we need for the cidbase value */
394
                /* We always store at least two bytes for the cidbase value */
395
355k
                for (valuelen = 16; valuelen < 32 && (cidbase >> valuelen) > 0; valuelen += 1)
396
306k
                    DO_NOTHING;
397
398
306k
                valuelen = ((valuelen + 7) & ~7) >> 3;
399
400
                /* The prefix is already directly in the gx_cmap_lookup_range_t
401
                 * We need to store the lower and upper character codes, after lopping the prefix
402
                 * off them. The upper and lower codes must be the same number of bytes.
403
                 */
404
306k
                j = sizeof(pdfi_cmap_range_map_t) + 2 * (stobj[i].size - preflen) + valuelen;
405
406
306k
                pdfir = (pdfi_cmap_range_map_t *)gs_alloc_bytes(mem, j, "cmap_endcidrange_func(pdfi_cmap_range_map_t)");
407
306k
                if (pdfir != NULL) {
408
306k
                    gx_cmap_lookup_range_t *gxr = &pdfir->range;
409
306k
                    pdfir->next = NULL;
410
306k
                    gxr->num_entries = 1;
411
306k
                    gxr->keys.data = (byte *)&(pdfir[1]);
412
306k
                    gxr->values.data = gxr->keys.data + 2 * (stobj[i].size - preflen);
413
414
306k
                    gxr->cmap = NULL;
415
306k
                    gxr->font_index = 0;
416
306k
                    gxr->key_is_range = true;
417
306k
                    gxr->value_type = CODE_VALUE_CID;
418
306k
                    gxr->key_prefix_size = preflen;
419
306k
                    gxr->key_size = stobj[i].size - gxr->key_prefix_size;
420
306k
                    memcpy(gxr->key_prefix, stobj[i].val.string, gxr->key_prefix_size);
421
422
306k
                    memcpy(gxr->keys.data, stobj[i].val.string + gxr->key_prefix_size, stobj[i].size - gxr->key_prefix_size);
423
306k
                    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);
424
425
306k
                    gxr->keys.size = (stobj[i].size - gxr->key_prefix_size) + (stobj[i + 1].size - gxr->key_prefix_size);
426
924k
                    for (j = 0; j < valuelen; j++) {
427
618k
                        gxr->values.data[j] = (cidbase >> ((valuelen - 1 - j) * 8)) & 255;
428
618k
                    }
429
306k
                    gxr->value_size = valuelen; /* I'm not sure.... */
430
306k
                    gxr->values.size = valuelen;
431
306k
                    if (cmap_insert_map(&pdficmap->cmap_range, pdfir) < 0) break;
432
306k
                }
433
0
                else {
434
0
                    (void)pdf_ps_stack_pop(s, to_pop);
435
0
                    return_error(gs_error_VMerror);
436
0
                }
437
306k
            }
438
1.54k
            else {
439
1.54k
                int m, size, keysize;
440
1.54k
                uint64_t kk;
441
1.54k
                uint codelo = 0, codehi = 0;
442
443
1.54k
                if (stobj[i + 2].size < 1 || stobj[i].size != stobj[i + 1].size)
444
0
                    continue;
445
446
1.54k
                size = stobj[i].size;
447
4.31k
                for (m = 0; m < size; m++) {
448
2.77k
                    codelo |= stobj[i].val.string[size - m - 1] << (8 * m);
449
2.77k
                }
450
1.54k
                size = stobj[i + 1].size;
451
4.31k
                for (m = 0; m < size; m++) {
452
2.77k
                    codehi |= stobj[i + 1].val.string[size - m - 1] << (8 * m);
453
2.77k
                }
454
455
1.54k
                if (codehi <= codelo || stobj[i + 2].size < (codehi - codelo))
456
25
                    continue;
457
458
91.8k
                for (kk = (uint64_t)codelo; kk <= (uint64_t)codehi; kk++) {
459
90.2k
                    uint cidbase;
460
90.2k
                    uint k = (uint)kk;
461
90.2k
                    int ind = k - codelo;
462
463
90.2k
                    if (stobj[i + 2].val.arr[ind].type != PDF_PS_OBJ_STRING)
464
7
                         continue;
465
466
90.2k
                    size = stobj[i + 2].val.arr[ind].size;
467
468
90.2k
                    cidbase = 0;
469
270k
                    for (m = 0; m < size; m++) {
470
180k
                        cidbase |= stobj[i + 2].val.arr[ind].val.string[size - m - 1] << (8 * m);
471
180k
                    }
472
                    /* Find how many bytes we need for the cidbase value */
473
                    /* We always store at least two bytes for the cidbase value */
474
90.4k
                    for (valuelen = 16; valuelen < 32 && (cidbase >> valuelen) > 0; valuelen += 1)
475
90.2k
                        DO_NOTHING;
476
477
90.2k
                    valuelen = ((valuelen + 7) & ~7) >> 3;
478
479
                    /* Find how many bytes we need for the cidbase value */
480
                    /* We always store at least two bytes for the cidbase value */
481
90.4k
                    for (keysize = 16; keysize < 32 && (cidbase >> keysize) > 0; keysize += 1)
482
90.2k
                        DO_NOTHING;
483
484
90.2k
                    keysize = ((keysize + 7) & ~7) >> 3;
485
90.2k
                    if (keysize > MAX_CMAP_CODE_SIZE * 2) {
486
0
                        (void)pdf_ps_stack_pop(s, to_pop);
487
0
                        return_error(gs_error_syntaxerror);
488
0
                    }
489
90.2k
                    preflen = keysize > 4 ? 4 : keysize;
490
90.2k
                    keysize -= preflen;
491
492
                    /* The prefix is already directly in the gx_cmap_lookup_range_t
493
                     * We need to store the lower and upper character codes, after lopping the prefix
494
                     * off them. The upper and lower codes must be the same number of bytes.
495
                     */
496
90.2k
                    j = sizeof(pdfi_cmap_range_map_t) + keysize + valuelen;
497
498
90.2k
                    pdfir = (pdfi_cmap_range_map_t *)gs_alloc_bytes(mem, j, "cmap_endcidrange_func(pdfi_cmap_range_map_t)");
499
90.2k
                    if (pdfir != NULL) {
500
90.2k
                        gx_cmap_lookup_range_t *gxr = &pdfir->range;
501
90.2k
                        pdfir->next = NULL;
502
90.2k
                        gxr->num_entries = 1;
503
90.2k
                        gxr->keys.data = (byte *)&(pdfir[1]);
504
90.2k
                        gxr->values.data = gxr->keys.data + keysize;
505
506
90.2k
                        gxr->cmap = NULL;
507
90.2k
                        gxr->font_index = 0;
508
90.2k
                        gxr->key_is_range = false;
509
90.2k
                        gxr->value_type = CODE_VALUE_CID;
510
90.2k
                        gxr->key_prefix_size = preflen;
511
90.2k
                        gxr->key_size = keysize;
512
270k
                        for (j = 0; j < preflen; j++) {
513
180k
                            gxr->key_prefix[j] = (k >> ((preflen - 1 - j) * 8)) & 255;
514
180k
                        }
515
516
90.2k
                        for (j = preflen; j < preflen + keysize; j++) {
517
0
                            gxr->keys.data[j] = (k >> (((preflen + keysize) - 1 - j) * 8)) & 255;
518
0
                        }
519
520
90.2k
                        gxr->keys.size = keysize;
521
270k
                        for (j = 0; j < valuelen; j++) {
522
180k
                            gxr->values.data[j] = (cidbase >> ((valuelen - 1 - j) * 8)) & 255;
523
180k
                        }
524
90.2k
                        gxr->value_size = valuelen; /* I'm not sure.... */
525
90.2k
                        gxr->values.size = valuelen;
526
90.2k
                        if (cmap_insert_map(&pdficmap->cmap_range, pdfir) < 0) break;
527
90.2k
                    }
528
0
                    else {
529
0
                        (void)pdf_ps_stack_pop(s, to_pop);
530
0
                        return_error(gs_error_VMerror);
531
0
                    }
532
90.2k
                }
533
1.51k
            }
534
312k
        }
535
326k
    }
536
16.8k
    return pdf_ps_stack_pop(s, to_pop);
537
16.9k
}
538
539
static int general_endcidchar_func(gs_memory_t *mem, pdf_ps_ctx_t *s, pdf_cmap *pdficmap, pdfi_cmap_range_t *cmap_range)
540
41.7k
{
541
41.7k
    int ncodemaps, to_pop = pdf_ps_stack_count_to_mark(s, PDF_PS_OBJ_MARK);
542
41.7k
    int i, j;
543
41.7k
    pdfi_cmap_range_map_t *pdfir;
544
41.7k
    pdf_ps_stack_object_t *stobj;
545
546
    /* increment to_pop to cover the mark object */
547
41.7k
    ncodemaps = to_pop++;
548
    /* mapping should have 2 objects on the stack:
549
     * startcode, endcode and basecid
550
     */
551
42.1k
    while (ncodemaps % 2) ncodemaps--;
552
553
41.7k
    if (ncodemaps < 0 || ncodemaps + 1 > PDF_PS_STACK_MAX) {
554
14
        pdfi_set_error(s->pdfi_ctx, 0, NULL, E_PDF_BAD_TYPE0_CMAP, "general_endcidchar_func", NULL);
555
14
        return_error(gs_error_syntaxerror);
556
14
    }
557
558
41.7k
    if (ncodemaps > 200) {
559
293
        int code;
560
293
        if ((code = pdfi_set_warning_stop(s->pdfi_ctx, gs_note_error(gs_error_syntaxerror), NULL, W_PDF_LIMITCHECK_TYPE0_CMAP, "general_endcidchar_func", NULL)) < 0) {
561
0
            (void)pdf_ps_stack_pop(s, to_pop);
562
0
            return code;
563
0
        }
564
293
    }
565
566
41.7k
    stobj = &s->cur[-ncodemaps] + 1;
567
568
2.41M
    for (i = 0; i < ncodemaps; i += 2) {
569
2.36M
        int preflen = 1, valuelen;
570
571
2.36M
        if (pdf_ps_obj_has_type(&(stobj[i + 1]), PDF_PS_OBJ_INTEGER)
572
2.35M
        &&  pdf_ps_obj_has_type(&(stobj[i]), PDF_PS_OBJ_STRING) && stobj[i].size > 0) {
573
2.32M
            uint cidbase = stobj[i + 1].val.i;
574
575
            /* Find how many bytes we need for the cidbase value */
576
            /* We always store at least two bytes for the cidbase value */
577
3.16M
            for (valuelen = 16; valuelen < 32 && (cidbase >> valuelen) > 0; valuelen += 1)
578
2.32M
                DO_NOTHING;
579
580
2.32M
            preflen = stobj[i].size > 4 ? 4 : stobj[i].size;
581
582
2.32M
            valuelen = ((valuelen + 7) & ~7) >> 3;
583
584
            /* The prefix is already directly in the gx_cmap_lookup_range_t
585
             * We need to store the lower and upper character codes, after lopping the prefix
586
             * off them. The upper and lower codes must be the same number of bytes.
587
             */
588
2.32M
            j = sizeof(pdfi_cmap_range_map_t) + (stobj[i].size - preflen) + valuelen;
589
590
2.32M
            pdfir = (pdfi_cmap_range_map_t *)gs_alloc_bytes(mem, j, "cmap_endcidrange_func(pdfi_cmap_range_map_t)");
591
2.32M
            if (pdfir != NULL) {
592
2.32M
                gx_cmap_lookup_range_t *gxr = &pdfir->range;
593
2.32M
                pdfir->next = NULL;
594
2.32M
                gxr->num_entries = 1;
595
2.32M
                gxr->keys.data = (byte *)&(pdfir[1]);
596
2.32M
                gxr->values.data = gxr->keys.data + (stobj[i].size - preflen);
597
598
2.32M
                gxr->cmap = NULL;
599
2.32M
                gxr->font_index = 0;
600
2.32M
                gxr->key_is_range = false;
601
2.32M
                gxr->value_type = cmap_range == &(pdficmap->cmap_range) ? CODE_VALUE_CID : CODE_VALUE_NOTDEF;
602
2.32M
                gxr->key_prefix_size = preflen;
603
2.32M
                gxr->key_size = stobj[i].size - gxr->key_prefix_size;
604
2.32M
                memcpy(gxr->key_prefix, stobj[i].val.string, gxr->key_prefix_size);
605
606
2.32M
                memcpy(gxr->keys.data, stobj[i].val.string + gxr->key_prefix_size, stobj[i].size - gxr->key_prefix_size);
607
608
2.32M
                gxr->keys.size = stobj[i].size - gxr->key_prefix_size;
609
7.11M
                for (j = 0; j < valuelen; j++) {
610
4.78M
                    gxr->values.data[j] = (cidbase >> ((valuelen - 1 - j) * 8)) & 255;
611
4.78M
                }
612
2.32M
                gxr->value_size = valuelen; /* I'm not sure.... */
613
2.32M
                gxr->values.size = valuelen;
614
2.32M
                if (cmap_insert_map(cmap_range, pdfir) < 0) break;
615
2.32M
            }
616
0
            else {
617
0
                (void)pdf_ps_stack_pop(s, to_pop);
618
0
                return_error(gs_error_VMerror);
619
0
            }
620
2.32M
        }
621
2.36M
    }
622
41.7k
    return pdf_ps_stack_pop(s, to_pop);
623
41.7k
}
624
625
static int cmap_endcidchar_func(gs_memory_t *mem, pdf_ps_ctx_t *s, byte *buf, byte *bufend)
626
7.36k
{
627
7.36k
    pdf_cmap *pdficmap = (pdf_cmap *)s->client_data;
628
7.36k
    return general_endcidchar_func(mem, s, pdficmap, &pdficmap->cmap_range);
629
7.36k
}
630
631
static int cmap_endnotdefchar_func(gs_memory_t *mem, pdf_ps_ctx_t *s, byte *buf, byte *bufend)
632
0
{
633
0
    pdf_cmap *pdficmap = (pdf_cmap *)s->client_data;
634
0
    return general_endcidchar_func(mem, s, pdficmap, &pdficmap->notdef_cmap_range);
635
0
}
636
637
static int cmap_endbfchar_func(gs_memory_t *mem, pdf_ps_ctx_t *s, byte *buf, byte *bufend)
638
34.5k
{
639
34.5k
    pdf_cmap *pdficmap = (pdf_cmap *)s->client_data;
640
34.5k
    int ncodemaps = pdf_ps_stack_count_to_mark(s, PDF_PS_OBJ_MARK);
641
34.5k
    pdf_ps_stack_object_t *stobj;
642
34.5k
    int i, j;
643
644
    /* The following hard limit is an implementation limit */
645
34.5k
    if (ncodemaps < 0 || ncodemaps + 1 > PDF_PS_STACK_MAX) {
646
152
        pdfi_set_error(s->pdfi_ctx, 0, NULL, E_PDF_BAD_TYPE0_CMAP, "cmap_endbfchar_func", NULL);
647
152
        return_error(gs_error_syntaxerror);
648
152
    }
649
650
    /* The following "soft" limit is according to the spec */
651
34.4k
    if (ncodemaps > 200) {
652
293
        int code;
653
293
        if ((code = pdfi_set_warning_stop(s->pdfi_ctx, gs_note_error(gs_error_syntaxerror), NULL, W_PDF_LIMITCHECK_TYPE0_CMAP, "cmap_endbfchar_func", NULL)) < 0) {
654
0
            (void)pdf_ps_stack_pop(s, ncodemaps);
655
0
            return code;
656
0
        }
657
293
    }
658
659
34.4k
    stobj = &s->cur[-ncodemaps] + 1;
660
661
1.75M
    for (i = 0; i < ncodemaps; i += 2) {
662
1.72M
        if (pdf_ps_obj_has_type(&(stobj[i + 1]), PDF_PS_OBJ_STRING)) {
663
1.71M
            byte *c = stobj[i + 1].val.string;
664
1.71M
            int l = stobj[i + 1].size;
665
1.71M
            unsigned int v = 0;
666
667
5.46M
            for (j = 0; j < l; j++) {
668
3.74M
                v += c[l - j - 1] << (8 * j);
669
3.74M
            }
670
1.71M
            pdf_ps_make_int(&(stobj[i + 1]), v);
671
1.71M
        }
672
5.26k
        else {
673
5.26k
            continue;
674
5.26k
        }
675
1.72M
    }
676
34.4k
    return general_endcidchar_func(mem, s, pdficmap, &pdficmap->cmap_range);
677
34.4k
}
678
679
1.72M
#define CMAP_NAME_AND_LEN(s) PDF_PS_OPER_NAME_AND_LEN(s)
680
681
static int cmap_def_func(gs_memory_t *mem, pdf_ps_ctx_t *s, byte *buf, byte *bufend)
682
425k
{
683
425k
    int code = 0, code2 = 0;
684
425k
    pdf_cmap *pdficmap = (pdf_cmap *)s->client_data;
685
686
425k
    if (pdf_ps_stack_count(s) < 2) {
687
38.2k
        return pdf_ps_stack_pop(s, 1);
688
38.2k
    }
689
690
387k
    if (pdf_ps_obj_has_type(&s->cur[-1], PDF_PS_OBJ_NAME)) {
691
386k
        if (!memcmp(s->cur[-1].val.name, CMAP_NAME_AND_LEN("Registry"))) {
692
38.3k
            if (pdficmap->csi_reg.data != NULL)
693
18
               gs_free_object(mem, pdficmap->csi_reg.data, "cmap_def_func(Registry)");
694
695
38.3k
            pdficmap->csi_reg.data = gs_alloc_bytes(mem, (size_t)s->cur[0].size + 1, "cmap_def_func(Registry)");
696
38.3k
            if (pdficmap->csi_reg.data != NULL) {
697
38.3k
                pdficmap->csi_reg.size = s->cur[0].size;
698
38.3k
                if (pdf_ps_obj_has_type(&s->cur[0], PDF_PS_OBJ_STRING)) {
699
38.3k
                    memcpy(pdficmap->csi_reg.data, s->cur[0].val.string, s->cur[0].size);
700
38.3k
                    pdficmap->csi_reg.data[pdficmap->csi_reg.size] = '\0';
701
38.3k
                }
702
4
                else {
703
4
                    if (pdf_ps_obj_has_type(&s->cur[0], PDF_PS_OBJ_NAME)) {
704
4
                        memcpy(pdficmap->csi_reg.data, s->cur[0].val.name, s->cur[0].size);
705
4
                        pdficmap->csi_reg.data[pdficmap->csi_reg.size] = '\0';
706
4
                    }
707
0
                    else
708
0
                        code = gs_note_error(gs_error_typecheck);
709
4
                }
710
38.3k
            }
711
0
            else {
712
0
                code = gs_note_error(gs_error_VMerror);
713
0
            }
714
38.3k
        }
715
348k
        else if (!memcmp(s->cur[-1].val.name, CMAP_NAME_AND_LEN("Ordering"))) {
716
38.3k
            if (pdficmap->csi_ord.data != NULL)
717
18
               gs_free_object(mem, pdficmap->csi_ord.data, "cmap_def_func(Ordering)");
718
719
38.3k
            pdficmap->csi_ord.data = gs_alloc_bytes(mem, (size_t)s->cur[0].size + 1, "cmap_def_func(Ordering)");
720
38.3k
            if (pdficmap->csi_ord.data != NULL) {
721
38.3k
                pdficmap->csi_ord.size = s->cur[0].size;
722
38.3k
                if (pdf_ps_obj_has_type(&s->cur[0], PDF_PS_OBJ_STRING)) {
723
38.3k
                    memcpy(pdficmap->csi_ord.data, s->cur[0].val.string, s->cur[0].size);
724
38.3k
                    pdficmap->csi_ord.data[pdficmap->csi_ord.size] = '\0';
725
38.3k
                }
726
4
                else {
727
4
                    if (pdf_ps_obj_has_type(&s->cur[0], PDF_PS_OBJ_NAME)) {
728
4
                        memcpy(pdficmap->csi_ord.data, s->cur[0].val.name, s->cur[0].size);
729
4
                        pdficmap->csi_ord.data[pdficmap->csi_ord.size] = '\0';
730
4
                    }
731
0
                    else
732
0
                        code = gs_note_error(gs_error_typecheck);
733
4
                }
734
38.3k
            }
735
0
            else {
736
0
                code = gs_note_error(gs_error_VMerror);
737
0
            }
738
38.3k
        }
739
309k
        else if (!memcmp(s->cur[-1].val.name, CMAP_NAME_AND_LEN("Supplement"))) {
740
64.4k
            if (pdf_ps_obj_has_type(&s->cur[0], PDF_PS_OBJ_INTEGER)) {
741
64.4k
                pdficmap->csi_supplement = s->cur[0].val.i;
742
64.4k
            }
743
0
            else {
744
0
                pdficmap->csi_supplement = 0;
745
0
            }
746
64.4k
        }
747
245k
        else if (!memcmp(s->cur[-1].val.name, CMAP_NAME_AND_LEN("CMapName"))) {
748
68.0k
            if (pdficmap->name.data != NULL)
749
44
               gs_free_object(mem, pdficmap->name.data, "cmap_def_func(CMapName)");
750
751
68.0k
            pdficmap->name.data = gs_alloc_bytes(mem, (size_t)s->cur[0].size + 1, "cmap_def_func(CMapName)");
752
68.0k
            if (pdficmap->name.data != NULL) {
753
68.0k
                pdficmap->name.size = s->cur[0].size;
754
68.0k
                if (pdf_ps_obj_has_type(&s->cur[0], PDF_PS_OBJ_STRING)) {
755
0
                    memcpy(pdficmap->name.data, s->cur[0].val.string, s->cur[0].size);
756
0
                    pdficmap->name.data[pdficmap->name.size] = '\0';
757
0
                }
758
68.0k
                else {
759
68.0k
                    if (pdf_ps_obj_has_type(&s->cur[0], PDF_PS_OBJ_NAME)) {
760
68.0k
                        memcpy(pdficmap->name.data, s->cur[0].val.name, s->cur[0].size);
761
68.0k
                        pdficmap->name.data[pdficmap->name.size] = '\0';
762
68.0k
                    }
763
0
                    else
764
0
                        code = gs_note_error(gs_error_typecheck);
765
68.0k
                }
766
68.0k
            }
767
0
            else {
768
0
                code = gs_note_error(gs_error_VMerror);
769
0
            }
770
68.0k
        }
771
177k
        else if (!memcmp(s->cur[-1].val.name, CMAP_NAME_AND_LEN("CMapVersion"))) {
772
36.6k
            if (pdf_ps_obj_has_type(&s->cur[0], PDF_PS_OBJ_INTEGER)) {
773
310
                pdficmap->vers = (float)s->cur[0].val.i;
774
310
            }
775
36.3k
            else if (pdf_ps_obj_has_type(&s->cur[0], PDF_PS_OBJ_FLOAT)){
776
36.3k
                pdficmap->vers = s->cur[0].val.f;
777
36.3k
            }
778
0
            else {
779
0
                pdficmap->vers = (float)0;
780
0
            }
781
36.6k
        }
782
140k
        else if (!memcmp(s->cur[-1].val.name, CMAP_NAME_AND_LEN("CMapType"))) {
783
66.6k
            if (pdf_ps_obj_has_type(&s->cur[0], PDF_PS_OBJ_INTEGER)) {
784
66.6k
                pdficmap->cmaptype = s->cur[0].val.i;
785
66.6k
            }
786
1
            else {
787
1
                pdficmap->cmaptype = 1;
788
1
            }
789
66.6k
        }
790
74.2k
        else if (!memcmp(s->cur[-1].val.name, CMAP_NAME_AND_LEN("XUID"))) {
791
36.3k
            if (pdf_ps_obj_has_type(&s->cur[0], PDF_PS_OBJ_ARRAY)) {
792
36.3k
                int len = s->cur->size;
793
794
36.3k
                if (pdficmap->uid.xvalues != NULL)
795
0
                   gs_free_object(mem, pdficmap->uid.xvalues, "cmap_def_func(XUID)");
796
797
36.3k
                pdficmap->uid.xvalues = (long *)gs_alloc_bytes(mem, (size_t)len * sizeof(*pdficmap->uid.xvalues), "cmap_def_func(XUID)");
798
36.3k
                if (pdficmap->uid.xvalues != NULL) {
799
36.3k
                     int i;
800
36.3k
                     pdf_ps_stack_object_t *a = s->cur->val.arr;
801
36.3k
                     pdficmap->uid.id = -len;
802
181k
                     for (i = 0; i < len; i++) {
803
144k
                         if (pdf_ps_obj_has_type(&a[i], PDF_PS_OBJ_INTEGER)) {
804
144k
                             pdficmap->uid.xvalues[i] = (long)a[i].val.i;
805
144k
                         }
806
0
                         else {
807
0
                             pdficmap->uid.xvalues[i] = 0;
808
0
                         }
809
144k
                     }
810
36.3k
                }
811
0
                else {
812
0
                    code = gs_note_error(gs_error_VMerror);
813
0
                }
814
36.3k
            }
815
36.3k
        }
816
37.8k
        else if (!memcmp(s->cur[-1].val.name, CMAP_NAME_AND_LEN("WMode"))) {
817
36.9k
            if (pdf_ps_obj_has_type(&s->cur[0], PDF_PS_OBJ_INTEGER)) {
818
36.9k
                if (s->cur[0].val.i != 0) {
819
327
                    if (s->cur[0].val.i != 1) {
820
8
                        code = pdfi_set_warning_stop(s->pdfi_ctx, gs_note_error(gs_error_rangecheck), NULL, W_PDF_BAD_WMODE, "cmap_def_func", NULL);
821
8
                    }
822
327
                    pdficmap->wmode = 1;
823
327
                }
824
36.6k
                else
825
36.6k
                    pdficmap->wmode = 0;
826
36.9k
            }
827
0
            else {
828
0
                pdficmap->wmode = 0;
829
0
            }
830
36.9k
        }
831
386k
    }
832
833
387k
    code2 = pdf_ps_stack_pop(s, 2);
834
387k
    if (code < 0)
835
0
        return code;
836
387k
    else
837
387k
        return code2;
838
387k
}
839
840
static pdf_ps_oper_list_t cmap_oper_list[] =
841
{
842
  {PDF_PS_OPER_NAME_AND_LEN("usecmap"), cmap_usecmap_func},
843
  {PDF_PS_OPER_NAME_AND_LEN("usefont"), ps_pdf_null_oper_func},
844
  {PDF_PS_OPER_NAME_AND_LEN("beginusematrix"), ps_pdf_null_oper_func},
845
  {PDF_PS_OPER_NAME_AND_LEN("endusematrix"), ps_pdf_null_oper_func},
846
  {PDF_PS_OPER_NAME_AND_LEN("begincodespacerange"), pdf_ps_pop_and_pushmark_func},
847
  {PDF_PS_OPER_NAME_AND_LEN("endcodespacerange"), cmap_endcodespacerange_func},
848
  {PDF_PS_OPER_NAME_AND_LEN("begincmap"), ps_pdf_null_oper_func},
849
  {PDF_PS_OPER_NAME_AND_LEN("beginbfchar"), pdf_ps_pop_and_pushmark_func},
850
  {PDF_PS_OPER_NAME_AND_LEN("endbfchar"), cmap_endbfchar_func},
851
  {PDF_PS_OPER_NAME_AND_LEN("beginbfrange"), pdf_ps_pop_and_pushmark_func},
852
  {PDF_PS_OPER_NAME_AND_LEN("endbfrange"), cmap_endfbrange_func},
853
  {PDF_PS_OPER_NAME_AND_LEN("begincidchar"), pdf_ps_pop_and_pushmark_func},
854
  {PDF_PS_OPER_NAME_AND_LEN("endcidchar"), cmap_endcidchar_func},
855
  {PDF_PS_OPER_NAME_AND_LEN("begincidrange"), pdf_ps_pop_and_pushmark_func},
856
  {PDF_PS_OPER_NAME_AND_LEN("endcidrange"), cmap_endcidrange_func},
857
  {PDF_PS_OPER_NAME_AND_LEN("beginnotdefchar"), pdf_ps_pop_and_pushmark_func},
858
  {PDF_PS_OPER_NAME_AND_LEN("endnotdefchar"), cmap_endnotdefchar_func},
859
  {PDF_PS_OPER_NAME_AND_LEN("beginnotdefrange"), pdf_ps_pop_and_pushmark_func},
860
  {PDF_PS_OPER_NAME_AND_LEN("endnotdefrange"), cmap_endnotdefrange_func},
861
  {PDF_PS_OPER_NAME_AND_LEN("findresource"), clear_stack_oper_func},
862
  {PDF_PS_OPER_NAME_AND_LEN("dict"), pdf_ps_pop_oper_func},
863
  {PDF_PS_OPER_NAME_AND_LEN("begin"), ps_pdf_null_oper_func},
864
  {PDF_PS_OPER_NAME_AND_LEN("end"), ps_pdf_null_oper_func},
865
  {PDF_PS_OPER_NAME_AND_LEN("pop"), ps_pdf_null_oper_func},
866
  {PDF_PS_OPER_NAME_AND_LEN("def"), cmap_def_func},
867
  {PDF_PS_OPER_NAME_AND_LEN("dup"), ps_pdf_null_oper_func},
868
  {PDF_PS_OPER_NAME_AND_LEN("defineresource"), clear_stack_oper_func},
869
  {PDF_PS_OPER_NAME_AND_LEN("beginrearrangedfont"), clear_stack_oper_func}, /* we should never see this */
870
  {NULL, 0, NULL}
871
};
872
873
static int
874
pdf_cmap_open_file(pdf_context *ctx, gs_string *cmap_name, byte **buf, int64_t *buflen)
875
36.4k
{
876
36.4k
    int code = 0;
877
36.4k
    stream *s;
878
36.4k
    char fname[gp_file_name_sizeof];
879
36.4k
    const char *path_pfx = "CMap/";
880
36.4k
    fname[0] = '\0';
881
882
36.4k
    if (strlen(path_pfx) + cmap_name->size >= gp_file_name_sizeof)
883
6
        return_error(gs_error_rangecheck);
884
885
36.4k
    strncat(fname, path_pfx, strlen(path_pfx));
886
36.4k
    strncat(fname, (char *)cmap_name->data, cmap_name->size);
887
36.4k
    code = pdfi_open_resource_file(ctx, (const char *)fname, (const int)strlen(fname), &s);
888
36.4k
    if (code >= 0) {
889
36.0k
        sfseek(s, 0, SEEK_END);
890
36.0k
        *buflen = sftell(s);
891
36.0k
        sfseek(s, 0, SEEK_SET);
892
36.0k
        *buf = gs_alloc_bytes(ctx->memory, *buflen, "pdf_cmap_open_file(buf)");
893
36.0k
        if (*buf != NULL) {
894
36.0k
            sfread(*buf, 1, *buflen, s);
895
36.0k
        }
896
0
        else {
897
0
            code = gs_note_error(gs_error_VMerror);
898
0
        }
899
36.0k
        sfclose(s);
900
36.0k
    }
901
36.4k
    return code;
902
36.4k
}
903
904
static int
905
pdfi_make_gs_cmap(gs_memory_t *mem, pdf_cmap *pdficmap)
906
69.3k
{
907
69.3k
    int code = 0, i;
908
69.3k
    gs_cmap_adobe1_t *pgscmap = 0;
909
69.3k
    gx_cmap_lookup_range_t *lookups, *ndlookups = NULL;
910
69.3k
    pdfi_cmap_range_map_t *l;
911
    /* FIXME: We have to use gs_cmap_adobe1_alloc() to get the cmap procs
912
       but even if it gets passed num_ranges = 0 it still allocates
913
       a zero length array. Change gs_cmap_adobe1_alloc to work better
914
     */
915
69.3k
    if ((code = gs_cmap_adobe1_alloc(&pgscmap, pdficmap->wmode,
916
69.3k
                                     pdficmap->name.data,
917
69.3k
                                     pdficmap->name.size,
918
69.3k
                                     1,
919
69.3k
                                     0, 0, 0, 0, 0, mem)) >= 0) {
920
69.3k
        gs_free_object(mem, pgscmap->code_space.ranges, "empty ranges");
921
922
69.3k
        lookups = gs_alloc_struct_array(mem, pdficmap->cmap_range.numrangemaps,
923
69.3k
                               gx_cmap_lookup_range_t,
924
69.3k
                               &st_cmap_lookup_range_element,
925
69.3k
                               "pdfi_make_gs_cmap(lookup ranges)");
926
69.3k
        if (lookups == NULL) {
927
0
            gs_free_object(mem, pgscmap, "pdfi_make_gs_cmap(pgscmap)");
928
0
            code = gs_note_error(gs_error_VMerror);
929
0
            goto done;
930
0
        }
931
69.3k
        if (pdficmap->notdef_cmap_range.numrangemaps > 0){
932
353
            ndlookups = gs_alloc_struct_array(mem, pdficmap->notdef_cmap_range.numrangemaps,
933
353
                               gx_cmap_lookup_range_t,
934
353
                               &st_cmap_lookup_range_element,
935
353
                               "pdfi_make_gs_cmap(notdef lookup ranges)");
936
353
            if (ndlookups == NULL) {
937
0
                gs_free_object(mem, lookups, "pdfi_make_gs_cmap(lookups)");
938
0
                gs_free_object(mem, pgscmap, "pdfi_make_gs_cmap(pgscmap)");
939
0
                code = gs_note_error(gs_error_VMerror);
940
0
                goto done;
941
0
            }
942
353
        }
943
69.3k
        pgscmap->def.lookup = lookups;
944
69.3k
        pgscmap->def.num_lookup = pdficmap->cmap_range.numrangemaps;
945
69.3k
        pgscmap->notdef.lookup = ndlookups;
946
69.3k
        pgscmap->notdef.num_lookup = pdficmap->notdef_cmap_range.numrangemaps;
947
948
69.3k
        pgscmap->CIDSystemInfo[0].Registry.data = pdficmap->csi_reg.data;
949
69.3k
        pgscmap->CIDSystemInfo[0].Registry.size = pdficmap->csi_reg.size;
950
69.3k
        pgscmap->CIDSystemInfo[0].Ordering.data = pdficmap->csi_ord.data;
951
69.3k
        pgscmap->CIDSystemInfo[0].Ordering.size = pdficmap->csi_ord.size;
952
69.3k
        pgscmap->CIDSystemInfo[0].Supplement = pdficmap->csi_supplement;
953
69.3k
        memcpy(&pgscmap->code_space, &pdficmap->code_space, sizeof(pgscmap->code_space));
954
69.3k
        memcpy(&pgscmap->uid, &pdficmap->uid, sizeof(pdficmap->uid));
955
69.3k
        l = pdficmap->cmap_range.ranges;
956
12.7M
        for (i = 0; i < pdficmap->cmap_range.numrangemaps && l != NULL; i++) {
957
12.6M
            memcpy(&lookups[i], &l->range, sizeof(gx_cmap_lookup_range_t));
958
12.6M
            l = l->next;
959
12.6M
        }
960
961
69.3k
        l = pdficmap->notdef_cmap_range.ranges;
962
69.7k
        for (i = 0; i < pdficmap->notdef_cmap_range.numrangemaps && l != NULL; i++) {
963
353
            memcpy(&ndlookups[i], &l->range, sizeof(gx_cmap_lookup_range_t));
964
353
            l = l->next;
965
353
        }
966
967
69.3k
        pdficmap->gscmap = pgscmap;
968
69.3k
    }
969
970
69.3k
done:
971
69.3k
    return code;
972
69.3k
}
973
974
int
975
pdfi_read_cmap(pdf_context *ctx, pdf_obj *cmap, pdf_cmap **pcmap)
976
70.6k
{
977
70.6k
    int code = 0;
978
70.6k
    pdf_cmap pdficm[3] = {0};
979
70.6k
    pdf_cmap *pdfi_cmap = &(pdficm[1]);
980
70.6k
    byte *buf = NULL;
981
70.6k
    int64_t buflen = 0;
982
70.6k
    pdf_ps_ctx_t cmap_ctx;
983
984
70.6k
    pdfi_cmap->ctx = ctx;
985
70.6k
    switch (pdfi_type_of(cmap)) {
986
36.4k
        case PDF_NAME:
987
36.4k
        {
988
36.4k
            gs_string cmname;
989
36.4k
            pdf_name *cmapn = (pdf_name *)cmap;
990
36.4k
            cmname.data = cmapn->data;
991
36.4k
            cmname.size = cmapn->length;
992
36.4k
            code = pdf_cmap_open_file(ctx, &cmname, &buf, &buflen);
993
36.4k
            if (code < 0)
994
333
                goto error_out;
995
36.0k
            break;
996
36.4k
        }
997
36.0k
        case PDF_STREAM:
998
34.1k
        {
999
34.1k
            pdf_obj *ucmap;
1000
34.1k
            pdf_cmap *upcmap = NULL;
1001
34.1k
            pdf_dict *cmap_dict = NULL;
1002
1003
34.1k
            code = pdfi_dict_from_obj(ctx, cmap, &cmap_dict);
1004
34.1k
            if (code < 0)
1005
0
                goto error_out;
1006
1007
34.1k
            code = pdfi_dict_knownget(ctx, cmap_dict, "UseCMap", &ucmap);
1008
34.1k
            if (code > 0) {
1009
0
                code = pdfi_read_cmap(ctx, ucmap, &upcmap);
1010
0
                pdfi_countdown(ucmap);
1011
0
                if (code >= 0) {
1012
0
                    gx_code_space_range_t * ranges =
1013
0
                         (gx_code_space_range_t *)gs_alloc_byte_array(ctx->memory, upcmap->code_space.num_ranges,
1014
0
                          sizeof(gx_code_space_range_t), "cmap_usecmap_func(ranges)");
1015
0
                    if (ranges != NULL) {
1016
0
                        int i;
1017
0
                        memcpy(&pdfi_cmap->code_space, &upcmap->code_space, sizeof(pdfi_cmap->code_space));
1018
0
                        for (i = 0; i < upcmap->code_space.num_ranges; i++) {
1019
0
                            memcpy(&(ranges[i]), &(upcmap->code_space.ranges[i]), sizeof(ranges[i]));
1020
0
                        }
1021
0
                        pdfi_cmap->code_space.ranges = ranges;
1022
0
                        memcpy(&pdfi_cmap->cmap_range, &upcmap->cmap_range, sizeof(pdfi_cmap->cmap_range));
1023
0
                        memcpy(&pdfi_cmap->notdef_cmap_range, &upcmap->notdef_cmap_range, sizeof(pdfi_cmap->notdef_cmap_range));
1024
                        /* Once we've assumed control of these, NULL out entries for the sub-cmap. */
1025
0
                        upcmap->cmap_range.ranges = NULL;
1026
0
                        upcmap->notdef_cmap_range.ranges = NULL;
1027
                        /* But we keep the subcmap itself because we rely on its storage */
1028
0
                        pdfi_cmap->next = upcmap;
1029
0
                    } else {
1030
0
                        code = gs_note_error(gs_error_VMerror);
1031
0
                        goto error_out;
1032
0
                    }
1033
0
                }
1034
0
                else {
1035
0
                    pdfi_countdown(upcmap);
1036
0
                }
1037
0
            }
1038
1039
34.1k
            code = pdfi_stream_to_buffer(ctx, (pdf_stream *)cmap, &buf, &buflen);
1040
34.1k
            if (code < 0) {
1041
238
                goto error_out;
1042
238
            }
1043
33.9k
            break;
1044
34.1k
        }
1045
33.9k
        default:
1046
62
            code = gs_note_error(gs_error_typecheck);
1047
62
            goto error_out;
1048
70.6k
    }
1049
70.0k
    pdfi_cmap->ctx = ctx;
1050
70.0k
    pdfi_cmap->buf = buf;
1051
70.0k
    pdfi_cmap->buflen = buflen;
1052
1053
    /* In case of technically invalid CMap files which do not contain a CMapType, See Bug #690737.
1054
     * This makes sure we clean up the CMap contents in pdfi_free_cmap() below.
1055
     */
1056
70.0k
    pdfi_cmap->cmaptype = 1;
1057
1058
70.0k
    pdfi_pscript_stack_init(ctx, cmap_oper_list, (void *)pdfi_cmap, &cmap_ctx);
1059
1060
70.0k
    code = pdfi_pscript_interpret(&cmap_ctx, buf, buflen);
1061
70.0k
    pdfi_pscript_stack_finit(&cmap_ctx);
1062
70.0k
    if (code < 0) goto error_out;
1063
1064
69.3k
    code = pdfi_make_gs_cmap(ctx->memory, pdfi_cmap);
1065
1066
69.3k
    if (code >= 0) {
1067
69.3k
        *pcmap = (pdf_cmap *)gs_alloc_bytes(ctx->memory, sizeof(pdf_cmap), "pdfi_read_cmap(*pcmap)");
1068
69.3k
        if (*pcmap != NULL) {
1069
69.3k
            pdfi_cmap->type = PDF_CMAP;
1070
69.3k
            pdfi_cmap->ctx = ctx;
1071
69.3k
            pdfi_cmap->refcnt = 1;
1072
69.3k
            pdfi_cmap->object_num = cmap->object_num;
1073
69.3k
            pdfi_cmap->generation_num = cmap->generation_num;
1074
69.3k
            pdfi_cmap->indirect_num = cmap->indirect_num;
1075
69.3k
            pdfi_cmap->indirect_gen = cmap->indirect_gen;
1076
69.3k
            memcpy(*pcmap, pdfi_cmap, sizeof(pdf_cmap));
1077
69.3k
            pdfi_cmap = *pcmap;
1078
            /* object_num can be zero if the dictionary was defined inline */
1079
69.3k
            if (pdfi_cmap->object_num != 0) {
1080
33.2k
                code = replace_cache_entry(ctx, (pdf_obj *)pdfi_cmap);
1081
33.2k
            }
1082
69.3k
        } else {
1083
0
            code = gs_note_error(gs_error_VMerror);
1084
0
            goto error_out;
1085
0
        }
1086
69.3k
    }
1087
0
    else {
1088
0
        goto error_out;
1089
0
    }
1090
69.3k
    return 0;
1091
1092
1.29k
error_out:
1093
1.29k
    pdfi_free_cmap_contents(pdfi_cmap);
1094
1.29k
    memset(pdfi_cmap, 0x00, sizeof(pdf_cmap));
1095
1.29k
    return code;
1096
69.3k
}
1097
1098
static int pdfi_free_cmap_contents(pdf_cmap *cmap)
1099
70.6k
{
1100
70.6k
    pdfi_cmap_range_map_t *pdfir;
1101
70.6k
    gs_cmap_adobe1_t *pgscmap = cmap->gscmap;
1102
1103
70.6k
    if (pgscmap != NULL) {
1104
69.3k
        gs_free_object(OBJ_MEMORY(cmap), pgscmap->def.lookup, "pdfi_free_cmap(def.lookup)");
1105
69.3k
        gs_free_object(OBJ_MEMORY(cmap), pgscmap->notdef.lookup, "pdfi_free_cmap(notdef.lookup)");
1106
69.3k
        (void)gs_cmap_free((gs_cmap_t *)pgscmap, OBJ_MEMORY(cmap));
1107
69.3k
    }
1108
70.6k
    gs_free_object(OBJ_MEMORY(cmap), cmap->code_space.ranges, "pdfi_free_cmap(code_space.ranges");
1109
70.6k
    pdfir = cmap->cmap_range.ranges;
1110
12.7M
    while (pdfir != NULL) {
1111
12.6M
        pdfi_cmap_range_map_t *pdfir2 = pdfir->next;
1112
12.6M
        gs_free_object(OBJ_MEMORY(cmap), pdfir, "pdfi_free_cmap(cmap_range.ranges");
1113
12.6M
        pdfir = pdfir2;
1114
12.6M
    }
1115
70.6k
    pdfir = cmap->notdef_cmap_range.ranges;
1116
70.9k
    while (pdfir != NULL) {
1117
317
        pdfi_cmap_range_map_t *pdfir2 = pdfir->next;
1118
317
        gs_free_object(OBJ_MEMORY(cmap), pdfir, "pdfi_free_cmap(cmap_range.ranges");
1119
317
        pdfir = pdfir2;
1120
317
    }
1121
70.6k
    gs_free_object(OBJ_MEMORY(cmap), cmap->csi_reg.data, "pdfi_free_cmap(csi_reg.data");
1122
70.6k
    gs_free_object(OBJ_MEMORY(cmap), cmap->csi_ord.data, "pdfi_free_cmap(csi_ord.data");
1123
70.6k
    gs_free_object(OBJ_MEMORY(cmap), cmap->name.data, "pdfi_free_cmap(name.data");
1124
70.6k
    gs_free_object(OBJ_MEMORY(cmap), cmap->uid.xvalues, "pdfi_free_cmap(xuid.xvalues");
1125
70.6k
    pdfi_countdown(cmap->next);
1126
70.6k
    gs_free_object(OBJ_MEMORY(cmap), cmap->buf, "pdfi_free_cmap(cmap->buf");
1127
1128
70.6k
    return 0;
1129
70.6k
}
1130
1131
int pdfi_free_cmap(pdf_obj *cmapo)
1132
69.3k
{
1133
69.3k
    pdf_cmap *cmap = (pdf_cmap *)cmapo;
1134
    /*
1135
     * Note there is some inconsistency in the various specifications regarding CMapType; the
1136
     * Adobe tech note 5014 specifically says it only documents CMaps with a CmapType of 0, the
1137
     * PLRM says that CMapType can be 0 or 1, and the two are equivalent, the PDF Reference Manual
1138
     * doesn't say, it just refers to tech note 5014 but the example has a CMapType of 1. The PDF
1139
     * Reference does describe ToUnicode CMaps which have a CMapType of 2.
1140
     */
1141
    /* Well it seems we have PDF files which use CMapType 2 CMaps as values for a /Encoding, which is
1142
     * I believe incorrect, as these are ToUnicode CMaps....
1143
     * There's nothing for it, we'll just haev to free all CMaps for now. Note for Chris when implementing
1144
     * ToUnicode CMaps, we'll obviously have to rely on the context to know whether a CMap is an Encoding
1145
     * or a ToUnicode, we cna't use the CmMapType, just as you suspected. :-(
1146
     * See bug #696449 633_R00728_E.pdf
1147
     */
1148
    /*
1149
     * For now, we represent ToUnicode CMaps (CMapType 2) in the same data structures as regular CMaps
1150
     * (CMapType 0/1) so there is no reason (yet!) to differentiate between the two.
1151
     */
1152
1153
69.3k
    pdfi_free_cmap_contents(cmap);
1154
    gs_free_object(OBJ_MEMORY(cmap), cmap, "pdfi_free_cmap(cmap");
1155
69.3k
    return 0;
1156
69.3k
}