Coverage Report

Created: 2022-10-31 07:00

/src/ghostpdl/psi/zusparam.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2001-2021 Artifex Software, Inc.
2
   All Rights Reserved.
3
4
   This software is provided AS-IS with no warranty, either express or
5
   implied.
6
7
   This software is distributed under license and may not be copied,
8
   modified or distributed except as expressly authorized under the terms
9
   of the license contained in the file LICENSE in this distribution.
10
11
   Refer to licensing information at http://www.artifex.com or contact
12
   Artifex Software, Inc.,  1305 Grant Avenue - Suite 200, Novato,
13
   CA 94945, U.S.A., +1(415)492-9861, for further information.
14
*/
15
16
17
/* User and system parameter operators */
18
#include "memory_.h"
19
#include "string_.h"
20
#include "ghost.h"
21
#include "oper.h"
22
#include "gscdefs.h"
23
#include "gsstruct.h"   /* for gxht.h */
24
#include "gsfont.h"   /* for user params */
25
#include "gxht.h"   /* for user params */
26
#include "gsutil.h"
27
#include "estack.h"
28
#include "ialloc.h"   /* for imemory for status */
29
#include "icontext.h"   /* for set_user_params prototype */
30
#include "idict.h"
31
#include "idparam.h"
32
#include "iparam.h"
33
#include "dstack.h"
34
#include "iname.h"
35
#include "itoken.h"
36
#include "iutil2.h"
37
#include "ivmem2.h"
38
#include "store.h"
39
#include "gsnamecl.h"
40
#include "igstate.h"
41
#include "gscms.h"
42
#include "gsicc_manage.h"
43
#include "gsparamx.h"
44
#include "gx.h"
45
#include "gxgstate.h"
46
#include "gslibctx.h"
47
48
49
/* The (global) font directory */
50
extern gs_font_dir *ifont_dir;  /* in zfont.c */
51
52
/* Define an individual user or system parameter. */
53
/* Eventually this will be made public. */
54
#define param_def_common\
55
    const char *pname
56
57
typedef struct param_def_s {
58
    param_def_common;
59
} param_def_t;
60
61
typedef struct size_t_param_def_s {
62
    param_def_common;
63
    size_t min_value, max_value;
64
    size_t (*current)(i_ctx_t *);
65
    int (*set)(i_ctx_t *, size_t);
66
} size_t_param_def_t;
67
68
typedef struct i64_param_def_s {
69
    param_def_common;
70
    int64_t min_value, max_value;
71
    int64_t (*current)(i_ctx_t *);
72
    int (*set)(i_ctx_t *, int64_t);
73
} i64_param_def_t;
74
75
typedef struct long_param_def_s {
76
    param_def_common;
77
    long min_value, max_value;
78
    long (*current)(i_ctx_t *);
79
    int (*set)(i_ctx_t *, long);
80
} long_param_def_t;
81
82
#if ARCH_SIZEOF_LONG > ARCH_SIZEOF_INT
83
#  define MAX_UINT_PARAM max_uint
84
#  define MIN_INT_PARAM min_int
85
#else
86
#  define MAX_UINT_PARAM max_long
87
#  define MIN_INT_PARAM min_long
88
#endif
89
90
typedef struct bool_param_def_s {
91
    param_def_common;
92
    bool (*current)(i_ctx_t *);
93
    int (*set)(i_ctx_t *, bool);
94
} bool_param_def_t;
95
96
typedef struct string_param_def_s {
97
    param_def_common;
98
    void (*current)(i_ctx_t *, gs_param_string *);
99
    int (*set)(i_ctx_t *, gs_param_string *);
100
} string_param_def_t;
101
102
/* Define a parameter set (user or system). */
103
typedef struct param_set_s {
104
    const size_t_param_def_t *size_t_defs;
105
    uint size_t_count;
106
    const i64_param_def_t *i64_defs;
107
    uint i64_count;
108
    const long_param_def_t *long_defs;
109
    uint long_count;
110
    const bool_param_def_t *bool_defs;
111
    uint bool_count;
112
    const string_param_def_t *string_defs;
113
    uint string_count;
114
} param_set;
115
116
/* Forward references */
117
static int setparams(i_ctx_t *, gs_param_list *, const param_set *);
118
static int currentparams(i_ctx_t *, const param_set *);
119
static int currentparam1(i_ctx_t *, const param_set *);
120
121
/* ------ Passwords ------ */
122
123
/* <string|int> .checkpassword <0|1|2> */
124
static int
125
zcheckpassword(i_ctx_t *i_ctx_p)
126
0
{
127
0
    os_ptr op = osp;
128
0
    ref params[2];
129
0
    array_param_list list;
130
0
    gs_param_list *const plist = (gs_param_list *)&list;
131
0
    int result = 0;
132
0
    int code = name_ref(imemory, (const byte *)"Password", 8, &params[0], 0);
133
0
    password pass;
134
135
0
    if (code < 0)
136
0
        return code;
137
0
    params[1] = *op;
138
0
    array_param_list_read(&list, params, 2, NULL, false, iimemory);
139
0
    if (dict_read_password(&pass, systemdict, "StartJobPassword") >= 0 &&
140
0
        param_check_password(plist, &pass) == 0
141
0
        )
142
0
        result = 1;
143
0
    if (dict_read_password(&pass, systemdict, "SystemParamsPassword") >= 0 &&
144
0
        param_check_password(plist, &pass) == 0
145
0
        )
146
0
        result = 2;
147
0
    iparam_list_release(&list);
148
0
    make_int(op, result);
149
0
    return 0;
150
0
}
151
152
/* ------ System parameters ------ */
153
154
/* Integer values */
155
static long
156
current_BuildTime(i_ctx_t *i_ctx_p)
157
446k
{
158
446k
    return gs_buildtime;
159
446k
}
160
161
/* we duplicate this definition here instead of including bfont.h and
162
   all its dependencies */
163
164
3.87M
#define ifont_dir (gs_lib_ctx_get_interp_instance(imemory)->font_dir)
165
166
static long
167
current_MaxFontCache(i_ctx_t *i_ctx_p)
168
446k
{
169
446k
    return gs_currentcachesize(ifont_dir);
170
446k
}
171
static int
172
set_MaxFontCache(i_ctx_t *i_ctx_p, long val)
173
0
{
174
0
    return gs_setcachesize(igs, ifont_dir,
175
0
                           (uint)(val < 0 ? 0 : val > max_uint ? max_uint :
176
0
                                   val));
177
0
}
178
static long
179
current_CurFontCache(i_ctx_t *i_ctx_p)
180
446k
{
181
446k
    uint cstat[7];
182
183
446k
    gs_cachestatus(ifont_dir, cstat);
184
446k
    return cstat[0];
185
446k
}
186
187
/* Even though size_t is unsigned, PostScript limits this to signed range */
188
static size_t
189
current_MaxGlobalVM(i_ctx_t *i_ctx_p)
190
446k
{
191
446k
    gs_memory_gc_status_t stat;
192
446k
    size_t val;
193
194
446k
    gs_memory_gc_status(iimemory_global, &stat);
195
    /* RJW: This seems very supicious to me. I get that in CPSI
196
     * mode the max_vm figure needs to be kept to 32bit mode, but
197
     * surely clipping it should be correct, rather than truncating
198
     * it? i.e. min(stat.max_vm, 0x7fffffff) */
199
446k
    if (gs_currentcpsimode(imemory))
200
0
        return stat.max_vm & 0x7fffffff;
201
    /* else clamp at the maximum positive value for the size_t size signed integer */
202
446k
    val = min(stat.max_vm, MAX_VM_THRESHOLD);
203
446k
    return val;
204
446k
}
205
206
/* Even though size_t is unsigned, PostScript limits this to signed range */
207
static int
208
set_MaxGlobalVM(i_ctx_t *i_ctx_p, size_t val)
209
0
{
210
0
    gs_memory_gc_status_t stat;
211
212
0
    gs_memory_gc_status(iimemory_global, &stat);
213
0
    stat.max_vm = val;
214
0
    gs_memory_set_gc_status(iimemory_global, &stat);
215
0
    return 0;
216
0
}
217
static long
218
current_Revision(i_ctx_t *i_ctx_p)
219
446k
{
220
446k
    return gs_revision;
221
446k
}
222
223
static long
224
current_PageCount(i_ctx_t *i_ctx_p)
225
446k
{
226
446k
    gx_device *dev = gs_currentdevice(igs);
227
228
446k
    if ((*dev_proc(dev, get_page_device))(dev) != 0)
229
178k
        if (dev->ShowpageCount > i_ctx_p->nv_page_count)
230
0
          i_ctx_p->nv_page_count = dev->ShowpageCount;
231
446k
    return 1000 + i_ctx_p->nv_page_count; /* Add 1000 to imitate NV memory */
232
446k
}
233
234
static const size_t_param_def_t system_size_t_params[] =
235
{
236
    /* Extensions */
237
    {"MaxGlobalVM", MIN_VM_THRESHOLD, MAX_VM_THRESHOLD, current_MaxGlobalVM, set_MaxGlobalVM}
238
};
239
240
static const long_param_def_t system_long_params[] =
241
{
242
    {"BuildTime", min_long, max_long, current_BuildTime, NULL},
243
    {"MaxFontCache", 0, MAX_UINT_PARAM, current_MaxFontCache, set_MaxFontCache},
244
    {"CurFontCache", 0, MAX_UINT_PARAM, current_CurFontCache, NULL},
245
    {"Revision", min_long, max_long, current_Revision, NULL},
246
    {"PageCount", min_long, max_long, current_PageCount, NULL}
247
};
248
249
/* Boolean values */
250
static bool
251
current_ByteOrder(i_ctx_t *i_ctx_p)
252
535k
{
253
535k
    return !ARCH_IS_BIG_ENDIAN;
254
535k
}
255
static const bool_param_def_t system_bool_params[] =
256
{
257
    {"ByteOrder", current_ByteOrder, NULL}
258
};
259
260
/* String values */
261
static void
262
current_RealFormat(i_ctx_t *i_ctx_p, gs_param_string * pval)
263
535k
{
264
535k
#if ARCH_FLOATS_ARE_IEEE
265
535k
    static const char *const rfs = "IEEE";
266
#else
267
    static const char *const rfs = "not IEEE";
268
#endif
269
270
535k
    pval->data = (const byte *)rfs;
271
535k
    pval->size = strlen(rfs);
272
535k
    pval->persistent = true;
273
535k
}
274
275
static const string_param_def_t system_string_params[] =
276
{
277
    {"RealFormat", current_RealFormat, NULL},
278
};
279
280
/* The system parameter set */
281
static const param_set system_param_set =
282
{
283
    system_size_t_params, countof(system_size_t_params),
284
    NULL, 0,  /* No i64 params for systemparams (yet) */
285
    system_long_params, countof(system_long_params),
286
    system_bool_params, countof(system_bool_params),
287
    system_string_params, countof(system_string_params)
288
};
289
290
/* <dict> .setsystemparams - */
291
static int
292
zsetsystemparams(i_ctx_t *i_ctx_p)
293
0
{
294
0
    os_ptr op = osp;
295
0
    int code;
296
0
    dict_param_list list;
297
0
    gs_param_list *const plist = (gs_param_list *)&list;
298
0
    password pass;
299
300
0
    check_type(*op, t_dictionary);
301
0
    code = dict_param_list_read(&list, op, NULL, false, iimemory);
302
0
    if (code < 0)
303
0
        return code;
304
0
    code = dict_read_password(&pass, systemdict, "SystemParamsPassword");
305
0
    if (code < 0)
306
0
        return code;
307
0
    code = param_check_password(plist, &pass);
308
0
    if (code != 0) {
309
0
        if (code > 0)
310
0
            code = gs_note_error(gs_error_invalidaccess);
311
0
        goto out;
312
0
    }
313
0
    code = param_read_password(plist, "StartJobPassword", &pass);
314
0
    switch (code) {
315
0
        default:    /* invalid */
316
0
            goto out;
317
0
        case 1:   /* missing */
318
0
            break;
319
0
        case 0:
320
0
            code = dict_write_password(&pass, systemdict,
321
0
                                       "StartJobPassword",
322
0
                                       ! i_ctx_p->LockFilePermissions);
323
0
            if (code < 0)
324
0
                goto out;
325
0
    }
326
0
    code = param_read_password(plist, "SystemParamsPassword", &pass);
327
0
    switch (code) {
328
0
        default:    /* invalid */
329
0
            goto out;
330
0
        case 1:   /* missing */
331
0
            break;
332
0
        case 0:
333
0
            code = dict_write_password(&pass, systemdict,
334
0
                                       "SystemParamsPassword",
335
0
                                       ! i_ctx_p->LockFilePermissions);
336
0
            if (code < 0)
337
0
                goto out;
338
0
    }
339
340
0
    code = setparams(i_ctx_p, plist, &system_param_set);
341
0
  out:
342
0
    iparam_list_release(&list);
343
0
    if (code < 0)
344
0
        return code;
345
0
    pop(1);
346
0
    return 0;
347
0
}
348
349
/* - .currentsystemparams <name1> <value1> ... */
350
static int
351
zcurrentsystemparams(i_ctx_t *i_ctx_p)
352
446k
{
353
446k
    return currentparams(i_ctx_p, &system_param_set);
354
446k
}
355
356
/* <name> .getsystemparam <value> */
357
static int
358
zgetsystemparam(i_ctx_t *i_ctx_p)
359
178k
{
360
178k
    return currentparam1(i_ctx_p, &system_param_set);
361
178k
}
362
363
/* ------ User parameters ------ */
364
365
/* Integer values */
366
static long
367
current_JobTimeout(i_ctx_t *i_ctx_p)
368
356k
{
369
356k
    return 0;
370
356k
}
371
static int
372
set_JobTimeout(i_ctx_t *i_ctx_p, long val)
373
254k
{
374
254k
    return 0;
375
254k
}
376
static long
377
current_MaxFontItem(i_ctx_t *i_ctx_p)
378
446k
{
379
446k
    return gs_currentcacheupper(ifont_dir);
380
446k
}
381
static int
382
set_MaxFontItem(i_ctx_t *i_ctx_p, long val)
383
433k
{
384
433k
    return gs_setcacheupper(ifont_dir, val);
385
433k
}
386
static long
387
current_MinFontCompress(i_ctx_t *i_ctx_p)
388
446k
{
389
446k
    return gs_currentcachelower(ifont_dir);
390
446k
}
391
static int
392
set_MinFontCompress(i_ctx_t *i_ctx_p, long val)
393
432k
{
394
432k
    return gs_setcachelower(ifont_dir, val);
395
432k
}
396
static long
397
current_MaxOpStack(i_ctx_t *i_ctx_p)
398
356k
{
399
356k
    return ref_stack_max_count(&o_stack);
400
356k
}
401
static int
402
set_MaxOpStack(i_ctx_t *i_ctx_p, long val)
403
343k
{
404
343k
    return ref_stack_set_max_count(&o_stack, val);
405
343k
}
406
static long
407
current_MaxDictStack(i_ctx_t *i_ctx_p)
408
356k
{
409
356k
    return ref_stack_max_count(&d_stack);
410
356k
}
411
static int
412
set_MaxDictStack(i_ctx_t *i_ctx_p, long val)
413
343k
{
414
343k
    return ref_stack_set_max_count(&d_stack, val);
415
343k
}
416
static long
417
current_MaxExecStack(i_ctx_t *i_ctx_p)
418
356k
{
419
356k
    return ref_stack_max_count(&e_stack);
420
356k
}
421
static int
422
set_MaxExecStack(i_ctx_t *i_ctx_p, long val)
423
343k
{
424
343k
    return ref_stack_set_max_count(&e_stack, val);
425
343k
}
426
static size_t
427
current_MaxLocalVM(i_ctx_t *i_ctx_p)
428
356k
{
429
356k
    gs_memory_gc_status_t stat;
430
356k
    size_t val;
431
432
356k
    gs_memory_gc_status(iimemory_local, &stat);
433
    /* RJW: This seems very supicious to me. I get that in CPSI
434
     * mode the max_vm figure needs to be kept to 32bit mode, but
435
     * surely clipping it should be correct, rather than truncating
436
     * it? i.e. min(stat.max_vm, 0x7fffffff) */
437
356k
    if (gs_currentcpsimode(imemory))
438
0
        return stat.max_vm & 0x7fffffff;
439
    /* else clamp at the maximun positive value for the size_t size signed integer */
440
356k
    val = min(stat.max_vm, MAX_VM_THRESHOLD);
441
356k
    return val;
442
356k
}
443
/* Even though size_t is unsigned, PostScript limits this to signed range */
444
static int
445
set_MaxLocalVM(i_ctx_t *i_ctx_p, size_t val)
446
254k
{
447
254k
    gs_memory_gc_status_t stat;
448
449
254k
    gs_memory_gc_status(iimemory_local, &stat);
450
254k
    stat.max_vm = val;
451
254k
    gs_memory_set_gc_status(iimemory_local, &stat);
452
254k
    return 0;
453
254k
}
454
static long
455
current_VMReclaim(i_ctx_t *i_ctx_p)
456
446k
{
457
446k
    gs_memory_gc_status_t gstat, lstat;
458
459
446k
    gs_memory_gc_status(iimemory_global, &gstat);
460
446k
    gs_memory_gc_status(iimemory_local, &lstat);
461
446k
    return (!gstat.enabled ? -2 : !lstat.enabled ? -1 : 0);
462
446k
}
463
static int64_t
464
current_VMThreshold(i_ctx_t *i_ctx_p)
465
446k
{
466
446k
    gs_memory_gc_status_t stat;
467
468
446k
    gs_memory_gc_status(iimemory_local, &stat);
469
446k
    return stat.vm_threshold;
470
446k
}
471
static long
472
current_WaitTimeout(i_ctx_t *i_ctx_p)
473
356k
{
474
356k
    return 0;
475
356k
}
476
static int
477
set_WaitTimeout(i_ctx_t *i_ctx_p, long val)
478
254k
{
479
254k
    return 0;
480
254k
}
481
static long
482
current_MinScreenLevels(i_ctx_t *i_ctx_p)
483
356k
{
484
356k
    return gs_currentminscreenlevels(imemory);
485
356k
}
486
static int
487
set_MinScreenLevels(i_ctx_t *i_ctx_p, long val)
488
254k
{
489
254k
    gs_setminscreenlevels(imemory, (uint) val);
490
254k
    return 0;
491
254k
}
492
static long
493
current_AlignToPixels(i_ctx_t *i_ctx_p)
494
356k
{
495
356k
    return gs_currentaligntopixels(ifont_dir);
496
356k
}
497
static int
498
set_AlignToPixels(i_ctx_t *i_ctx_p, long val)
499
254k
{
500
254k
    gs_setaligntopixels(ifont_dir, (uint)val);
501
254k
    return 0;
502
254k
}
503
static long
504
current_GridFitTT(i_ctx_t *i_ctx_p)
505
356k
{
506
356k
    return gs_currentgridfittt(ifont_dir);
507
356k
}
508
static int
509
set_GridFitTT(i_ctx_t *i_ctx_p, long val)
510
254k
{
511
254k
    gs_setgridfittt(ifont_dir, (uint)val);
512
254k
    return 0;
513
254k
}
514
515
#undef ifont_dir
516
517
static void
518
current_devicen_icc(i_ctx_t *i_ctx_p, gs_param_string * pval)
519
356k
{
520
356k
    gs_currentdevicenicc(igs, pval);
521
356k
}
522
523
static int
524
set_devicen_profile_icc(i_ctx_t *i_ctx_p, gs_param_string * pval)
525
254k
{
526
254k
    return gs_setdevicenprofileicc(igs, pval);
527
254k
}
528
529
static void
530
current_default_gray_icc(i_ctx_t *i_ctx_p, gs_param_string * pval)
531
356k
{
532
356k
    gs_currentdefaultgrayicc(igs, pval);
533
356k
}
534
535
static int
536
set_default_gray_icc(i_ctx_t *i_ctx_p, gs_param_string * pval)
537
254k
{
538
254k
    return gs_setdefaultgrayicc(igs, pval);
539
254k
}
540
541
static void
542
current_icc_directory(i_ctx_t *i_ctx_p, gs_param_string * pval)
543
446k
{
544
446k
    gs_currenticcdirectory(igs, pval);
545
446k
}
546
547
static int
548
set_icc_directory(i_ctx_t *i_ctx_p, gs_param_string * pval)
549
433k
{
550
433k
    return gs_seticcdirectory(igs, pval);
551
433k
}
552
553
static void
554
current_srcgtag_icc(i_ctx_t *i_ctx_p, gs_param_string * pval)
555
356k
{
556
356k
    gs_currentsrcgtagicc(igs, pval);
557
356k
}
558
559
static int
560
set_srcgtag_icc(i_ctx_t *i_ctx_p, gs_param_string * pval)
561
254k
{
562
254k
    return gs_setsrcgtagicc(igs, pval);
563
254k
}
564
565
static void
566
current_default_rgb_icc(i_ctx_t *i_ctx_p, gs_param_string * pval)
567
356k
{
568
356k
    gs_currentdefaultrgbicc(igs, pval);
569
356k
}
570
571
static int
572
set_default_rgb_icc(i_ctx_t *i_ctx_p, gs_param_string * pval)
573
254k
{
574
254k
    return gs_setdefaultrgbicc(igs, pval);
575
254k
}
576
577
static void
578
current_named_icc(i_ctx_t *i_ctx_p, gs_param_string * pval)
579
356k
{
580
356k
    gs_currentnamedicc(igs, pval);
581
356k
}
582
583
static int
584
set_named_profile_icc(i_ctx_t *i_ctx_p, gs_param_string * pval)
585
254k
{
586
254k
    return gs_setnamedprofileicc(igs, pval);
587
254k
}
588
589
static void
590
current_default_cmyk_icc(i_ctx_t *i_ctx_p, gs_param_string * pval)
591
356k
{
592
356k
    gs_currentdefaultcmykicc(igs, pval);
593
356k
}
594
595
static int
596
set_default_cmyk_icc(i_ctx_t *i_ctx_p, gs_param_string * pval)
597
254k
{
598
254k
    return gs_setdefaultcmykicc(igs, pval);
599
254k
}
600
601
static void
602
current_lab_icc(i_ctx_t *i_ctx_p, gs_param_string * pval)
603
356k
{
604
356k
    gs_currentlabicc(igs, pval);
605
356k
}
606
607
static int
608
set_lab_icc(i_ctx_t *i_ctx_p, gs_param_string * pval)
609
254k
{
610
254k
    return gs_setlabicc(igs, pval);
611
254k
}
612
613
static const size_t_param_def_t user_size_t_params[] =
614
{
615
    {"MaxLocalVM", MIN_VM_THRESHOLD, MAX_VM_THRESHOLD, current_MaxLocalVM, set_MaxLocalVM}
616
};
617
618
static const i64_param_def_t user_i64_params[] =
619
{
620
    {"VMThreshold", -1, MAX_VM_THRESHOLD, current_VMThreshold, set_vm_threshold},
621
};
622
623
static const long_param_def_t user_long_params[] =
624
{
625
    {"JobTimeout", 0, MAX_UINT_PARAM,
626
     current_JobTimeout, set_JobTimeout},
627
    {"MaxFontItem", MIN_INT_PARAM, MAX_UINT_PARAM,
628
     current_MaxFontItem, set_MaxFontItem},
629
    {"MinFontCompress", MIN_INT_PARAM, MAX_UINT_PARAM,
630
     current_MinFontCompress, set_MinFontCompress},
631
    {"MaxOpStack", -1, max_long,
632
     current_MaxOpStack, set_MaxOpStack},
633
    {"MaxDictStack", -1, max_long,
634
     current_MaxDictStack, set_MaxDictStack},
635
    {"MaxExecStack", -1, max_long,
636
     current_MaxExecStack, set_MaxExecStack},
637
    {"VMReclaim", -2, 0,
638
     current_VMReclaim, set_vm_reclaim},
639
    {"WaitTimeout", 0, MAX_UINT_PARAM,
640
     current_WaitTimeout, set_WaitTimeout},
641
    /* Extensions */
642
    {"MinScreenLevels", 0, MAX_UINT_PARAM,
643
     current_MinScreenLevels, set_MinScreenLevels},
644
    {"AlignToPixels", 0, 1,
645
     current_AlignToPixels, set_AlignToPixels},
646
    {"GridFitTT", 0, 3,
647
     current_GridFitTT, set_GridFitTT}
648
};
649
650
/* Note that string objects that are maintained as user params must be
651
   either allocated in non-gc memory or be a constant in the executable.
652
   The problem stems from the way userparams are retained during garbage
653
   collection in a param_list (collected by currentuserparams).  For
654
   some reason this param_list does not get the pointers to strings relocated
655
   during the GC. Note that the param_dict itself is correctly updated by reloc,
656
   it is just the pointers to the strings in the param_list that are not traced
657
   and updated. An example of this includes the ICCProfilesDir, which sets a
658
   string in the icc_manager. When a reclaim occurs, the string is relocated
659
   (when in non-gc memory and when it is noted to the gc with the proper object
660
   descriptor).  Then if a set_icc_directory occurs, the user params pointer has
661
   NOT been updated and validation problems will occur. */
662
static const string_param_def_t user_string_params[] =
663
{
664
    {"DefaultGrayProfile", current_default_gray_icc, set_default_gray_icc},
665
    {"DefaultRGBProfile", current_default_rgb_icc, set_default_rgb_icc},
666
    {"DefaultCMYKProfile", current_default_cmyk_icc, set_default_cmyk_icc},
667
    {"NamedProfile", current_named_icc, set_named_profile_icc},
668
    {"ICCProfilesDir", current_icc_directory, set_icc_directory},
669
    {"LabProfile", current_lab_icc, set_lab_icc},
670
    {"DeviceNProfile", current_devicen_icc, set_devicen_profile_icc},
671
    {"SourceObjectICC", current_srcgtag_icc, set_srcgtag_icc}
672
};
673
674
/* Boolean values */
675
static bool
676
current_AccurateScreens(i_ctx_t *i_ctx_p)
677
356k
{
678
356k
    return gs_currentaccuratescreens(imemory);
679
356k
}
680
static int
681
set_AccurateScreens(i_ctx_t *i_ctx_p, bool val)
682
254k
{
683
254k
    gs_setaccuratescreens(imemory, val);
684
254k
    return 0;
685
254k
}
686
/* Boolean values */
687
static bool
688
current_OverrideICC(i_ctx_t *i_ctx_p)
689
356k
{
690
356k
    return gs_currentoverrideicc(igs);
691
356k
}
692
static int
693
set_OverrideICC(i_ctx_t *i_ctx_p, bool val)
694
254k
{
695
254k
    gs_setoverrideicc(igs, val);
696
254k
    return 0;
697
254k
}
698
static bool
699
current_LockFilePermissions(i_ctx_t *i_ctx_p)
700
356k
{
701
356k
    return i_ctx_p->LockFilePermissions;
702
356k
}
703
static int
704
set_LockFilePermissions(i_ctx_t *i_ctx_p, bool val)
705
254k
{
706
    /* allow locking even if already locked */
707
254k
    if (i_ctx_p->LockFilePermissions && !val)
708
0
        return_error(gs_error_invalidaccess);
709
254k
    i_ctx_p->LockFilePermissions = val;
710
254k
    return 0;
711
254k
}
712
static bool
713
current_RenderTTNotdef(i_ctx_t *i_ctx_p)
714
356k
{
715
356k
    return i_ctx_p->RenderTTNotdef;
716
356k
}
717
static int
718
set_RenderTTNotdef(i_ctx_t *i_ctx_p, bool val)
719
254k
{
720
254k
    i_ctx_p->RenderTTNotdef = val;
721
254k
    return 0;
722
254k
}
723
static const bool_param_def_t user_bool_params[] =
724
{
725
    {"AccurateScreens", current_AccurateScreens, set_AccurateScreens},
726
    {"LockFilePermissions", current_LockFilePermissions, set_LockFilePermissions},
727
    {"RenderTTNotdef", current_RenderTTNotdef, set_RenderTTNotdef},
728
    {"OverrideICC", current_OverrideICC, set_OverrideICC}
729
};
730
731
/* The user parameter set */
732
static const param_set user_param_set =
733
{
734
    user_size_t_params, countof(user_size_t_params),
735
    user_i64_params, countof(user_i64_params),
736
    user_long_params, countof(user_long_params),
737
    user_bool_params, countof(user_bool_params),
738
    user_string_params, countof(user_string_params)
739
};
740
741
/* <dict> .setuserparams - */
742
/* We break this out for use when switching contexts. */
743
int
744
set_user_params(i_ctx_t *i_ctx_p, const ref *paramdict)
745
2.57M
{
746
2.57M
    dict_param_list list;
747
2.57M
    int code;
748
749
2.57M
    check_type(*paramdict, t_dictionary);
750
2.57M
    code = dict_param_list_read(&list, paramdict, NULL, false, iimemory);
751
2.57M
    if (code < 0)
752
0
        return code;
753
2.57M
    code = setparams(i_ctx_p, (gs_param_list *)&list, &user_param_set);
754
2.57M
    iparam_list_release(&list);
755
2.57M
    return code;
756
2.57M
}
757
static int
758
zsetuserparams(i_ctx_t *i_ctx_p)
759
2.30M
{
760
2.30M
    os_ptr op = osp;
761
2.30M
    int code = set_user_params(i_ctx_p, op);
762
763
2.30M
    if (code >= 0) {
764
        /* Update cached scanner options. */
765
2.30M
        i_ctx_p->scanner_options =
766
2.30M
            ztoken_scanner_options(op, i_ctx_p->scanner_options);
767
2.30M
        pop(1);
768
2.30M
    }
769
2.30M
    return code;
770
2.30M
}
771
772
/* - .currentuserparams <name1> <value1> ... */
773
static int
774
zcurrentuserparams(i_ctx_t *i_ctx_p)
775
356k
{
776
356k
    return currentparams(i_ctx_p, &user_param_set);
777
356k
}
778
779
/* <name> .getuserparam <value> */
780
static int
781
zgetuserparam(i_ctx_t *i_ctx_p)
782
446k
{
783
446k
    return currentparam1(i_ctx_p, &user_param_set);
784
446k
}
785
786
/* ------ Initialization procedure ------ */
787
788
const op_def zusparam_op_defs[] =
789
{
790
        /* User and system parameters are accessible even in Level 1 */
791
        /* (if this is a Level 2 system). */
792
    {"0.currentsystemparams", zcurrentsystemparams},
793
    {"0.currentuserparams", zcurrentuserparams},
794
    {"1.getsystemparam", zgetsystemparam},
795
    {"1.getuserparam", zgetuserparam},
796
    {"1.setsystemparams", zsetsystemparams},
797
    {"1.setuserparams", zsetuserparams},
798
        /* The rest of the operators are defined only in Level 2. */
799
    op_def_begin_level2(),
800
    {"1.checkpassword", zcheckpassword},
801
    op_def_end(0)
802
};
803
804
/* ------ Internal procedures ------ */
805
806
/* Set the values of a parameter set from a parameter list. */
807
/* We don't attempt to back out if anything fails. */
808
static int
809
setparams(i_ctx_t *i_ctx_p, gs_param_list * plist, const param_set * pset)
810
2.57M
{
811
2.57M
    int code;
812
2.57M
    unsigned int i;
813
814
5.14M
    for (i = 0; i < pset->size_t_count; i++) {
815
2.57M
        const size_t_param_def_t *pdef = &pset->size_t_defs[i];
816
2.57M
        size_t val;
817
818
2.57M
        if (pdef->set == NULL)
819
0
            continue;
820
2.57M
        code = param_read_size_t(plist, pdef->pname, &val);
821
2.57M
        switch (code) {
822
0
            default:    /* invalid */
823
0
                return code;
824
2.32M
            case 1:   /* missing */
825
2.32M
                break;
826
254k
            case 0:
827
254k
                if (val < pdef->min_value || val > pdef->max_value)
828
0
                    return_error(gs_error_rangecheck);
829
254k
                code = (*pdef->set)(i_ctx_p, val);
830
254k
                if (code < 0)
831
0
                    return code;
832
2.57M
        }
833
2.57M
    }
834
835
5.14M
    for (i = 0; i < pset->i64_count; i++) {
836
2.57M
        const i64_param_def_t *pdef = &pset->i64_defs[i];
837
2.57M
        int64_t val;
838
839
2.57M
        if (pdef->set == NULL)
840
0
            continue;
841
2.57M
        code = param_read_i64(plist, pdef->pname, &val);
842
2.57M
        switch (code) {
843
0
            default:    /* invalid */
844
0
                return code;
845
2.14M
            case 1:   /* missing */
846
2.14M
                break;
847
433k
            case 0:
848
433k
                if (val < pdef->min_value || val > pdef->max_value)
849
0
                    return_error(gs_error_rangecheck);
850
433k
                code = (*pdef->set)(i_ctx_p, val);
851
433k
                if (code < 0)
852
0
                    return code;
853
2.57M
        }
854
2.57M
    }
855
856
30.8M
    for (i = 0; i < pset->long_count; i++) {
857
28.3M
        const long_param_def_t *pdef = &pset->long_defs[i];
858
28.3M
        long val;
859
860
28.3M
        if (pdef->set == NULL)
861
0
            continue;
862
28.3M
        code = param_read_long(plist, pdef->pname, &val);
863
28.3M
        switch (code) {
864
3
            default:    /* invalid */
865
3
                return code;
866
24.7M
            case 1:   /* missing */
867
24.7M
                break;
868
3.60M
            case 0:
869
3.60M
                if (val < pdef->min_value || val > pdef->max_value)
870
3
                    return_error(gs_error_rangecheck);
871
3.60M
                code = (*pdef->set)(i_ctx_p, val);
872
3.60M
                if (code < 0)
873
0
                    return code;
874
28.3M
        }
875
28.3M
    }
876
12.8M
    for (i = 0; i < pset->bool_count; i++) {
877
10.2M
        const bool_param_def_t *pdef = &pset->bool_defs[i];
878
10.2M
        bool val;
879
880
10.2M
        if (pdef->set == NULL)
881
0
            continue;
882
10.2M
        code = param_read_bool(plist, pdef->pname, &val);
883
10.2M
        if (code == 0)
884
1.01M
            code = (*pdef->set)(i_ctx_p, val);
885
10.2M
        if (code < 0)
886
0
            return code;
887
10.2M
    }
888
889
23.1M
    for (i = 0; i < pset->string_count; i++) {
890
20.5M
        const string_param_def_t *pdef = &pset->string_defs[i];
891
20.5M
        gs_param_string val;
892
893
20.5M
        if (pdef->set == NULL)
894
0
            continue;
895
20.5M
        code = param_read_string(plist, pdef->pname, &val);
896
20.5M
        switch (code) {
897
0
            default:    /* invalid */
898
0
                return code;
899
18.3M
            case 1:   /* missing */
900
18.3M
                break;
901
2.21M
            case 0:
902
2.21M
                code = (*pdef->set)(i_ctx_p, &val);
903
2.21M
                if (code < 0)
904
0
                    return code;
905
20.5M
        }
906
20.5M
    }
907
908
2.57M
    return 0;
909
2.57M
}
910
911
/* Get the current values of a parameter set to the stack. */
912
static bool
913
pname_matches(const char *pname, const ref * psref)
914
25.0M
{
915
25.0M
    return
916
25.0M
        (psref == 0 ||
917
25.0M
         !bytes_compare((const byte *)pname, strlen(pname),
918
12.5M
                        psref->value.const_bytes, r_size(psref)));
919
25.0M
}
920
static int
921
current_param_list(i_ctx_t *i_ctx_p, const param_set * pset,
922
                   const ref * psref /*t_string */ )
923
1.42M
{
924
1.42M
    stack_param_list list;
925
1.42M
    gs_param_list *const plist = (gs_param_list *)&list;
926
1.42M
    int code = 0;
927
1.42M
    unsigned int i;
928
929
1.42M
    stack_param_list_write(&list, &o_stack, NULL, iimemory);
930
931
2.85M
    for (i = 0; i < pset->size_t_count; i++) {
932
1.42M
        const char *pname = pset->size_t_defs[i].pname;
933
934
1.42M
        if (pname_matches(pname, psref)) {
935
803k
            size_t val = (*pset->size_t_defs[i].current)(i_ctx_p);
936
937
803k
            code = param_write_size_t(plist, pname, &val);
938
803k
            if (code < 0)
939
0
                return code;
940
803k
        }
941
1.42M
    }
942
2.23M
    for (i = 0; i < pset->i64_count; i++) {
943
803k
        const char *pname = pset->i64_defs[i].pname;
944
945
803k
        if (pname_matches(pname, psref)) {
946
446k
            int64_t val = (*pset->i64_defs[i].current)(i_ctx_p);
947
948
446k
            code = param_write_i64(plist, pname, &val);
949
446k
            if (code < 0)
950
0
                return code;
951
446k
        }
952
803k
    }
953
13.3M
    for (i = 0; i < pset->long_count; i++) {
954
11.9M
        const char *pname = pset->long_defs[i].pname;
955
956
11.9M
        if (pname_matches(pname, psref)) {
957
6.42M
            long val = (*pset->long_defs[i].current)(i_ctx_p);
958
959
6.42M
            code = param_write_long(plist, pname, &val);
960
6.42M
            if (code < 0)
961
0
                return code;
962
6.42M
        }
963
11.9M
    }
964
5.26M
    for (i = 0; i < pset->bool_count; i++) {
965
3.83M
        const char *pname = pset->bool_defs[i].pname;
966
967
3.83M
        if (pname_matches(pname, psref)) {
968
1.96M
            bool val = (*pset->bool_defs[i].current)(i_ctx_p);
969
970
1.96M
            code = param_write_bool(plist, pname, &val);
971
1.96M
            if (code < 0)
972
0
                return code;
973
1.96M
        }
974
3.83M
    }
975
8.47M
    for (i = 0; i < pset->string_count; i++) {
976
7.04M
        const char *pname = pset->string_defs[i].pname;
977
978
7.04M
        if (pname_matches(pname, psref)) {
979
3.48M
            gs_param_string val;
980
981
3.48M
            (*pset->string_defs[i].current)(i_ctx_p, &val);
982
3.48M
            code = param_write_string(plist, pname, &val);
983
3.48M
            if (code < 0)
984
0
                return code;
985
3.48M
        }
986
7.04M
    }
987
1.42M
    if (psref) {
988
        /*
989
         * Scanner options can be read, but only individually by .getuserparam.
990
         * This avoids putting them into userparams, and being affected by save/restore.
991
         */
992
624k
        const char *pname;
993
624k
        bool val;
994
624k
        int code;
995
996
624k
        switch (ztoken_get_scanner_option(psref, i_ctx_p->scanner_options, &pname)) {
997
0
            case 0:
998
0
                code = param_write_null(plist, pname);
999
0
                break;
1000
0
            case 1:
1001
0
                val = true;
1002
0
                code = param_write_bool(plist, pname, &val);
1003
0
                break;
1004
624k
            default:
1005
624k
                code = 0;
1006
624k
                break;
1007
624k
        }
1008
624k
        if (code < 0)
1009
0
            return code;
1010
624k
    }
1011
1.42M
    return code;
1012
1.42M
}
1013
1014
/* Get the current values of a parameter set to the stack. */
1015
static int
1016
currentparams(i_ctx_t *i_ctx_p, const param_set * pset)
1017
803k
{
1018
803k
    return current_param_list(i_ctx_p, pset, NULL);
1019
803k
}
1020
1021
/* Get the value of a single parameter to the stack, or signal an error. */
1022
static int
1023
currentparam1(i_ctx_t *i_ctx_p, const param_set * pset)
1024
624k
{
1025
624k
    os_ptr op = osp;
1026
624k
    ref sref;
1027
624k
    int code;
1028
1029
624k
    check_type(*op, t_name);
1030
624k
    check_ostack(2);
1031
624k
    name_string_ref(imemory, (const ref *)op, &sref);
1032
624k
    code = current_param_list(i_ctx_p, pset, &sref);
1033
624k
    if (code < 0)
1034
0
        return code;
1035
624k
    if (osp == op)
1036
0
        return_error(gs_error_undefined);
1037
    /* We know osp == op + 2. */
1038
624k
    ref_assign(op, op + 2);
1039
624k
    pop(2);
1040
624k
    return code;
1041
624k
}