Coverage Report

Created: 2026-04-09 07:06

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