Coverage Report

Created: 2026-04-01 06:26

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/samba/third_party/heimdal/lib/hx509/sel.c
Line
Count
Source
1
/*
2
 * Copyright (c) 2008 Kungliga Tekniska Högskolan
3
 * (Royal Institute of Technology, Stockholm, Sweden).
4
 * All rights reserved.
5
 *
6
 * Redistribution and use in source and binary forms, with or without
7
 * modification, are permitted provided that the following conditions
8
 * are met:
9
 *
10
 * 1. Redistributions of source code must retain the above copyright
11
 *    notice, this list of conditions and the following disclaimer.
12
 *
13
 * 2. Redistributions in binary form must reproduce the above copyright
14
 *    notice, this list of conditions and the following disclaimer in the
15
 *    documentation and/or other materials provided with the distribution.
16
 *
17
 * 3. Neither the name of the Institute nor the names of its contributors
18
 *    may be used to endorse or promote products derived from this software
19
 *    without specific prior written permission.
20
 *
21
 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31
 * SUCH DAMAGE.
32
 */
33
34
#include "hx_locl.h"
35
36
HX509_LIB_FUNCTION struct hx_expr * HX509_LIB_CALL
37
_hx509_make_expr(enum hx_expr_op op, void *arg1, void *arg2)
38
0
{
39
0
    struct hx_expr *expr;
40
41
0
    expr = malloc(sizeof(*expr));
42
0
    if (expr == NULL)
43
0
  return NULL;
44
0
    expr->op = op;
45
0
    expr->arg1 = arg1;
46
0
    expr->arg2 = arg2;
47
48
0
    return expr;
49
0
}
50
51
static const char *
52
eval_word(hx509_context context, hx509_env env, struct hx_expr *word)
53
0
{
54
0
    switch (word->op) {
55
0
    case expr_STRING:
56
0
  return word->arg1;
57
0
    case expr_VAR:
58
0
  if (word->arg2 == NULL)
59
0
      return hx509_env_find(context, env, word->arg1);
60
61
0
  env = hx509_env_find_binding(context, env, word->arg1);
62
0
  if (env == NULL)
63
0
      return NULL;
64
65
0
  return eval_word(context, env, word->arg2);
66
0
    default:
67
0
  return NULL;
68
0
    }
69
0
}
70
71
static hx509_env
72
find_variable(hx509_context context, hx509_env env, struct hx_expr *word)
73
0
{
74
0
    assert(word->op == expr_VAR);
75
76
0
    if (word->arg2 == NULL)
77
0
  return hx509_env_find_binding(context, env, word->arg1);
78
79
0
    env = hx509_env_find_binding(context, env, word->arg1);
80
0
    if (env == NULL)
81
0
  return NULL;
82
0
    return find_variable(context, env, word->arg2);
83
0
}
84
85
static int
86
eval_comp(hx509_context context, hx509_env env, struct hx_expr *expr)
87
0
{
88
0
    switch (expr->op) {
89
0
    case comp_NE:
90
0
    case comp_EQ:
91
0
    case comp_TAILEQ: {
92
0
  const char *s1, *s2;
93
0
  int ret;
94
95
0
  s1 = eval_word(context, env, expr->arg1);
96
0
  s2 = eval_word(context, env, expr->arg2);
97
98
0
  if (s1 == NULL || s2 == NULL)
99
0
      return FALSE;
100
101
0
  if (expr->op == comp_TAILEQ) {
102
0
      size_t len1 = strlen(s1);
103
0
      size_t len2 = strlen(s2);
104
105
0
      if (len1 < len2)
106
0
    return 0;
107
0
      ret = strcmp(s1 + (len1 - len2), s2) == 0;
108
0
  } else {
109
0
      ret = strcmp(s1, s2) == 0;
110
0
      if (expr->op == comp_NE)
111
0
    ret = !ret;
112
0
  }
113
0
  return ret;
114
0
    }
115
0
    case comp_IN: {
116
0
  struct hx_expr *subexpr;
117
0
  const char *w, *s1;
118
119
0
  w = eval_word(context, env, expr->arg1);
120
121
0
  subexpr = expr->arg2;
122
123
0
  if (subexpr->op == expr_WORDS) {
124
0
      while (subexpr) {
125
0
    s1 = eval_word(context, env, subexpr->arg1);
126
0
    if (strcmp(w, s1) == 0)
127
0
        return TRUE;
128
0
    subexpr = subexpr->arg2;
129
0
      }
130
0
  } else if (subexpr->op == expr_VAR) {
131
0
      hx509_env subenv;
132
133
0
      subenv = find_variable(context, env, subexpr);
134
0
      if (subenv == NULL)
135
0
    return FALSE;
136
137
0
      while (subenv) {
138
0
    if (subenv->type != env_string)
139
0
        continue;
140
0
    if (strcmp(w, subenv->name) == 0)
141
0
        return TRUE;
142
0
    if (strcmp(w, subenv->u.string) == 0)
143
0
        return TRUE;
144
0
    subenv = subenv->next;
145
0
      }
146
147
0
  } else
148
0
      _hx509_abort("hx509 eval IN unknown op: %d", (int)subexpr->op);
149
150
0
  return FALSE;
151
0
    }
152
0
    default:
153
0
  _hx509_abort("hx509 eval expr with unknown op: %d", (int)expr->op);
154
0
    }
155
0
    return FALSE;
156
0
}
157
158
HX509_LIB_FUNCTION int HX509_LIB_CALL
159
_hx509_expr_eval(hx509_context context, hx509_env env, struct hx_expr *expr)
160
0
{
161
0
    switch (expr->op) {
162
0
    case op_TRUE:
163
0
  return 1;
164
0
    case op_FALSE:
165
0
  return 0;
166
0
    case op_NOT:
167
0
  return ! _hx509_expr_eval(context, env, expr->arg1);
168
0
    case op_AND:
169
0
  return _hx509_expr_eval(context, env, expr->arg1) &&
170
0
      _hx509_expr_eval(context, env, expr->arg2);
171
0
    case op_OR:
172
0
  return _hx509_expr_eval(context, env, expr->arg1) ||
173
0
      _hx509_expr_eval(context, env, expr->arg2);
174
0
    case op_COMP:
175
0
  return eval_comp(context, env, expr->arg1);
176
0
    default:
177
0
  _hx509_abort("hx509 eval expr with unknown op: %d", (int)expr->op);
178
0
  UNREACHABLE(return 0);
179
0
    }
180
0
}
181
182
HX509_LIB_FUNCTION void HX509_LIB_CALL
183
_hx509_expr_free(struct hx_expr *expr)
184
0
{
185
0
    switch (expr->op) {
186
0
    case expr_STRING:
187
0
    case expr_NUMBER:
188
0
  free(expr->arg1);
189
0
  break;
190
0
    case expr_WORDS:
191
0
    case expr_FUNCTION:
192
0
    case expr_VAR:
193
0
  free(expr->arg1);
194
0
  if (expr->arg2)
195
0
      _hx509_expr_free(expr->arg2);
196
0
  break;
197
0
    default:
198
0
  if (expr->arg1)
199
0
      _hx509_expr_free(expr->arg1);
200
0
  if (expr->arg2)
201
0
      _hx509_expr_free(expr->arg2);
202
0
  break;
203
0
    }
204
0
    free(expr);
205
0
}
206
207
/* XXX Horrible, no good cause not thread-safe */
208
HX509_LIB_FUNCTION struct hx_expr * HX509_LIB_CALL
209
_hx509_expr_parse(const char *buf)
210
0
{
211
0
    _hx509_expr_input.buf = buf;
212
0
    _hx509_expr_input.length = strlen(buf);
213
0
    _hx509_expr_input.offset = 0;
214
0
    _hx509_expr_input.expr = NULL;
215
216
0
    if (_hx509_expr_input.error) {
217
0
  free(_hx509_expr_input.error);
218
0
  _hx509_expr_input.error = NULL;
219
0
    }
220
221
0
    yyparse();
222
223
0
    return _hx509_expr_input.expr;
224
0
}
225
226
const char *
227
_hx509_expr_parse_error(void)
228
0
{
229
0
    return _hx509_expr_input.error;
230
0
}
231
232
void
233
_hx509_sel_yyerror (const char *s)
234
0
{
235
0
     if (_hx509_expr_input.error)
236
0
         free(_hx509_expr_input.error);
237
238
0
     _hx509_expr_input.error = strdup(s);
239
0
}
240