Coverage Report

Created: 2025-06-24 07:01

/src/ghostpdl/psi/iutil2.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2001-2023 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
17
/* Level 2 utilities for Ghostscript interpreter */
18
#include "memory_.h"
19
#include "string_.h"
20
#include "ghost.h"
21
#include "ierrors.h"
22
#include "opcheck.h"
23
#include "gsparam.h"
24
#include "gsutil.h"   /* bytes_compare prototype */
25
#include "idict.h"
26
#include "imemory.h"    /* for iutil.h */
27
#include "iutil.h"
28
#include "iutil2.h"
29
30
/* ------ Password utilities ------ */
31
32
/* Read a password from a parameter list. */
33
/* Return 0 if present, 1 if absent, or an error code. */
34
int
35
param_read_password(gs_param_list * plist, const char *kstr, password * ppass)
36
0
{
37
0
    gs_param_string ps;
38
0
    long ipass;
39
0
    int code = param_read_string(plist, kstr, &ps);
40
41
0
    switch (code) {
42
0
        case 0:   /* OK */
43
0
            if (ps.size > MAX_PASSWORD)
44
0
                return_error(gs_error_limitcheck);
45
            /* Copy the data back. */
46
0
            memcpy(ppass->data, ps.data, ps.size);
47
0
            ppass->size = ps.size;
48
0
            return 0;
49
0
        case 1:   /* key is missing */
50
0
            return 1;
51
0
    }
52
    /* We might have gotten a typecheck because */
53
    /* the supplied password was an integer. */
54
0
    if (code != gs_error_typecheck)
55
0
        return code;
56
0
    code = param_read_long(plist, kstr, &ipass);
57
0
    if (code != 0)   /* error or missing */
58
0
        return code;
59
0
    gs_snprintf((char *)ppass->data, MAX_PASSWORD, "%ld", ipass);
60
0
    ppass->size = strlen((char *)ppass->data);
61
0
    return 0;
62
0
}
63
/* Write a password to a parameter list. */
64
int
65
param_write_password(gs_param_list * plist, const char *kstr,
66
                     const password * ppass)
67
0
{
68
0
    gs_param_string ps;
69
70
0
    ps.data = (const byte *)ppass->data, ps.size = ppass->size,
71
0
        ps.persistent = false;
72
0
    if (ps.size > MAX_PASSWORD)
73
0
        return_error(gs_error_limitcheck);
74
0
    return param_write_string(plist, kstr, &ps);
75
0
}
76
77
/* Check a password from a parameter list. */
78
/* Return 0 if OK, 1 if not OK, or an error code. */
79
int
80
param_check_password(gs_param_list * plist, const password * ppass)
81
0
{
82
0
    if (ppass->size != 0) {
83
0
        password pass;
84
0
        int code = param_read_password(plist, "Password", &pass);
85
86
0
        if (code)
87
0
            return code;
88
0
        if (pass.size != ppass->size ||
89
0
            bytes_compare(&pass.data[0], pass.size,
90
0
                          &ppass->data[0],
91
0
                          ppass->size) != 0
92
0
            )
93
0
            return 1;
94
0
    }
95
0
    return 0;
96
0
}
97
98
/* Read a password from, or write a password into, a dictionary */
99
/* (presumably systemdict). */
100
static int
101
dict_find_password(ref ** ppvalue, const ref * pdref, const char *kstr)
102
0
{
103
0
    ref *pvalue;
104
105
0
    if (dict_find_string(pdref, kstr, &pvalue) <= 0)
106
0
        return_error(gs_error_undefined);
107
0
    if (!r_has_type(pvalue, t_string) ||
108
0
        r_has_attrs(pvalue, a_read) ||
109
0
        pvalue->value.const_bytes[0] >= r_size(pvalue)
110
0
        )
111
0
        return_error(gs_error_rangecheck);
112
0
    *ppvalue = pvalue;
113
0
    return 0;
114
0
}
115
int
116
dict_read_password(password * ppass, const ref * pdref, const char *pkey)
117
0
{
118
0
    ref *pvalue;
119
0
    int code = dict_find_password(&pvalue, pdref, pkey);
120
121
0
    if (code < 0)
122
0
        return code;
123
0
    if (pvalue->value.const_bytes[0] > MAX_PASSWORD)
124
0
        return_error(gs_error_rangecheck);  /* limitcheck? */
125
0
    memcpy(ppass->data, pvalue->value.const_bytes + 1,
126
0
           (ppass->size = pvalue->value.const_bytes[0]));
127
0
    return 0;
128
0
}
129
int
130
dict_write_password(const password * ppass, ref * pdref, const char *pkey,
131
                        bool change_allowed)
132
0
{
133
0
    ref *pvalue;
134
0
    int code = dict_find_password(&pvalue, pdref, pkey);
135
136
0
    if (code < 0)
137
0
        return code;
138
0
    if (ppass->size >= r_size(pvalue))
139
0
        return_error(gs_error_rangecheck);
140
0
    if (!change_allowed &&
141
0
        bytes_compare(pvalue->value.bytes + 1, pvalue->value.bytes[0],
142
0
            ppass->data, ppass->size) != 0)
143
0
        return_error(gs_error_invalidaccess);
144
0
    memcpy(pvalue->value.bytes + 1, ppass->data,
145
0
           (pvalue->value.bytes[0] = ppass->size));
146
0
    return 0;
147
0
}