Coverage Report

Created: 2022-04-16 11:23

/src/ghostpdl/base/gsparamx.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
/* Extended parameter dictionary utilities */
18
#include "string_.h"
19
#include "gserrors.h"
20
#include "gstypes.h"
21
#include "gsmemory.h"
22
#include "gsparam.h"
23
#include "gsparamx.h"
24
25
/* Compare a C string and a gs_param_string. */
26
bool
27
gs_param_string_eq(const gs_param_string * pcs, const char *str)
28
1.22k
{
29
1.22k
    return (strlen(str) == pcs->size &&
30
1.22k
            !strncmp(str, (const char *)pcs->data, pcs->size));
31
1.22k
}
32
33
/* Put an enumerated value. */
34
int
35
param_put_enum(gs_param_list * plist, gs_param_name param_name,
36
               int *pvalue, const char *const pnames[], int ecode)
37
6.32k
{
38
6.32k
    gs_param_string ens;
39
6.32k
    int code = param_read_name(plist, param_name, &ens);
40
41
6.32k
    switch (code) {
42
5.09k
        case 1:
43
5.09k
            return ecode;
44
1.22k
        case 0:
45
1.22k
            {
46
1.22k
                int i;
47
48
1.22k
                for (i = 0; pnames[i] != 0; ++i)
49
1.22k
                    if (gs_param_string_eq(&ens, pnames[i])) {
50
1.22k
                        *pvalue = i;
51
1.22k
                        return 0;
52
1.22k
                    }
53
1.22k
            }
54
0
            code = gs_error_rangecheck;
55
            /* fall through */
56
0
        default:
57
0
            ecode = code;
58
0
            param_signal_error(plist, param_name, code);
59
6.32k
    }
60
0
    return ecode;
61
6.32k
}
62
63
/* Put a Boolean value. */
64
int
65
param_put_bool(gs_param_list * plist, gs_param_name param_name,
66
               bool * pval, int ecode)
67
0
{
68
0
    int code;
69
70
0
    switch (code = param_read_bool(plist, param_name, pval)) {
71
0
        default:
72
0
            ecode = code;
73
0
            param_signal_error(plist, param_name, ecode);
74
0
        case 0:
75
0
        case 1:
76
0
            break;
77
0
    }
78
0
    return ecode;
79
0
}
80
81
/* Put an integer value. */
82
int
83
param_put_int(gs_param_list * plist, gs_param_name param_name,
84
              int *pval, int ecode)
85
0
{
86
0
    int code;
87
88
0
    switch (code = param_read_int(plist, param_name, pval)) {
89
0
        default:
90
0
            ecode = code;
91
0
            param_signal_error(plist, param_name, ecode);
92
0
        case 0:
93
0
        case 1:
94
0
            break;
95
0
    }
96
0
    return ecode;
97
0
}
98
99
/* Put a long value. */
100
int
101
param_put_long(gs_param_list * plist, gs_param_name param_name,
102
               long *pval, int ecode)
103
0
{
104
0
    int code;
105
106
0
    switch (code = param_read_long(plist, param_name, pval)) {
107
0
        default:
108
0
            ecode = code;
109
0
            param_signal_error(plist, param_name, ecode);
110
0
        case 0:
111
0
        case 1:
112
0
            break;
113
0
    }
114
0
    return ecode;
115
0
}
116
117
/* Copy one parameter list to another, recursively if necessary. */
118
int
119
param_list_copy(gs_param_list *plto, gs_param_list *plfrom)
120
0
{
121
0
    gs_param_enumerator_t key_enum;
122
0
    gs_param_key_t key;
123
    /*
124
     * If plfrom and plto use different allocators, we must copy
125
     * aggregate values even if they are "persistent".
126
     */
127
0
    bool copy_persists = plto->memory == plfrom->memory;
128
0
    int code;
129
130
0
    param_init_enumerator(&key_enum);
131
0
    while ((code = param_get_next_key(plfrom, &key_enum, &key)) == 0) {
132
0
        char string_key[256]; /* big enough for any reasonable key */
133
0
        gs_param_typed_value value;
134
0
        gs_param_collection_type_t coll_type;
135
0
        gs_param_typed_value copy;
136
137
0
        if (key.size > sizeof(string_key) - 1) {
138
0
            code = gs_note_error(gs_error_rangecheck);
139
0
            break;
140
0
        }
141
0
        memcpy(string_key, key.data, key.size);
142
0
        string_key[key.size] = 0;
143
0
        if ((code = param_read_typed(plfrom, string_key, &value)) != 0) {
144
0
            code = (code > 0 ? gs_note_error(gs_error_unknownerror) : code);
145
0
            break;
146
0
        }
147
0
        gs_param_list_set_persistent_keys(plto, key.persistent);
148
0
        switch (value.type) {
149
0
        case gs_param_type_dict:
150
0
            coll_type = gs_param_collection_dict_any;
151
0
            goto cc;
152
0
        case gs_param_type_dict_int_keys:
153
0
            coll_type = gs_param_collection_dict_int_keys;
154
0
            goto cc;
155
0
        case gs_param_type_array:
156
0
            coll_type = gs_param_collection_array;
157
0
        cc:
158
0
            copy.value.d.size = value.value.d.size;
159
            /* FIXME: RJW: I suspect that this will go wrong, if size == 0.
160
             * We should probably spot size == 0 and break. */
161
0
            if ((code = param_begin_write_collection(plto, string_key,
162
0
                                                     &copy.value.d,
163
0
                                                     coll_type)) < 0 ||
164
0
                (code = param_list_copy(copy.value.d.list,
165
0
                                        value.value.d.list)) < 0 ||
166
0
                (code = param_end_write_collection(plto, string_key,
167
0
                                                   &copy.value.d)) < 0)
168
0
                break;
169
0
            code = param_end_read_collection(plfrom, string_key,
170
0
                                             &value.value.d);
171
0
            break;
172
0
        case gs_param_type_string:
173
0
            value.value.s.persistent &= copy_persists; goto ca;
174
0
        case gs_param_type_name:
175
0
            value.value.n.persistent &= copy_persists; goto ca;
176
0
        case gs_param_type_int_array:
177
0
            value.value.ia.persistent &= copy_persists; goto ca;
178
0
        case gs_param_type_float_array:
179
0
            value.value.fa.persistent &= copy_persists; goto ca;
180
0
        case gs_param_type_string_array:
181
0
            value.value.sa.persistent &= copy_persists;
182
            /* fall through */
183
0
        ca:
184
0
        default:
185
0
            code = param_write_typed(plto, string_key, &value);
186
0
        }
187
0
        if (code < 0)
188
0
            break;
189
0
    }
190
0
    return code;
191
0
}