Coverage Report

Created: 2026-04-12 07:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/pigeonhole/src/testsuite/testsuite-variables.c
Line
Count
Source
1
/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file
2
 */
3
4
#include "lib.h"
5
6
#include "sieve-common.h"
7
#include "sieve-ast.h"
8
#include "sieve-binary.h"
9
#include "sieve-code.h"
10
#include "sieve-commands.h"
11
#include "sieve-validator.h"
12
#include "sieve-generator.h"
13
#include "sieve-interpreter.h"
14
#include "sieve-dump.h"
15
16
#include "sieve-ext-variables.h"
17
18
#include "testsuite-common.h"
19
#include "testsuite-variables.h"
20
21
/*
22
 *
23
 */
24
25
static const struct sieve_extension *testsuite_ext_variables = NULL;
26
27
/*
28
 *
29
 */
30
31
bool testsuite_varnamespace_validate(
32
  struct sieve_validator *valdtr,
33
  const struct sieve_variables_namespace *nspc,
34
  struct sieve_ast_argument *arg, struct sieve_command *cmd,
35
  ARRAY_TYPE(sieve_variable_name) *var_name, void **var_data,
36
  bool assignment);
37
bool testsuite_varnamespace_generate(
38
  const struct sieve_codegen_env *cgenv,
39
  const struct sieve_variables_namespace *nspc,
40
  struct sieve_ast_argument *arg, struct sieve_command *cmd,
41
  void *var_data);
42
bool testsuite_varnamespace_dump_variable(
43
  const struct sieve_dumptime_env *denv,
44
  const struct sieve_variables_namespace *nspc,
45
  const struct sieve_operand *oprnd, sieve_size_t *address);
46
int testsuite_varnamespace_read_variable(
47
  const struct sieve_runtime_env *renv,
48
  const struct sieve_variables_namespace *nspc,
49
  const struct sieve_operand *oprnd, sieve_size_t *address,
50
  string_t **str_r);
51
52
static const struct sieve_variables_namespace_def testsuite_namespace = {
53
  SIEVE_OBJECT("tst", &testsuite_namespace_operand, 0),
54
  testsuite_varnamespace_validate,
55
  testsuite_varnamespace_generate,
56
  testsuite_varnamespace_dump_variable,
57
  testsuite_varnamespace_read_variable,
58
};
59
60
bool testsuite_varnamespace_validate(
61
  struct sieve_validator *valdtr,
62
  const struct sieve_variables_namespace *nspc ATTR_UNUSED,
63
  struct sieve_ast_argument *arg, struct sieve_command *cmd ATTR_UNUSED,
64
  ARRAY_TYPE(sieve_variable_name) *var_name, void **var_data,
65
  bool assignment)
66
0
{
67
0
  struct sieve_ast *ast = arg->ast;
68
0
  const struct sieve_variable_name *name_element;
69
0
  const char *variable;
70
71
  /* Check variable name */
72
73
0
  if (array_count(var_name) != 2) {
74
0
    sieve_argument_validate_error(valdtr, arg,
75
0
      "testsuite: invalid variable name within testsuite namespace: "
76
0
      "encountered sub-namespace");
77
0
    return FALSE;
78
0
  }
79
80
0
  name_element = array_idx(var_name, 1);
81
0
  if (name_element->num_variable >= 0) {
82
0
    sieve_argument_validate_error(valdtr, arg,
83
0
      "testsuite: invalid variable name within testsuite namespace 'tst.%d': "
84
0
      "encountered numeric variable name", name_element->num_variable);
85
0
    return FALSE;
86
0
  }
87
88
0
  variable = str_c(name_element->identifier);
89
0
  if (assignment) {
90
0
    sieve_argument_validate_error(valdtr, arg,
91
0
      "testsuite: cannot assign to testsuite variable 'tst.%s'",
92
0
      variable);
93
0
    return FALSE;
94
0
  }
95
96
0
  *var_data = p_strdup(sieve_ast_pool(ast), variable);
97
0
  return TRUE;
98
0
}
99
100
bool testsuite_varnamespace_generate(
101
  const struct sieve_codegen_env *cgenv,
102
  const struct sieve_variables_namespace *nspc,
103
  struct sieve_ast_argument *arg ATTR_UNUSED,
104
  struct sieve_command *cmd ATTR_UNUSED, void *var_data)
105
0
{
106
0
  const struct sieve_extension *this_ext = SIEVE_OBJECT_EXTENSION(nspc);
107
0
  const char *variable = (const char *)var_data;
108
109
0
  if (this_ext == NULL)
110
0
    return FALSE;
111
112
0
  sieve_variables_opr_namespace_variable_emit(
113
0
    cgenv->sblock, testsuite_ext_variables, this_ext,
114
0
    &testsuite_namespace);
115
0
  sieve_binary_emit_cstring(cgenv->sblock, variable);
116
117
0
  return TRUE;
118
0
}
119
120
bool testsuite_varnamespace_dump_variable(
121
  const struct sieve_dumptime_env *denv,
122
  const struct sieve_variables_namespace *nspc ATTR_UNUSED,
123
  const struct sieve_operand *oprnd, sieve_size_t *address)
124
0
{
125
0
  string_t *var_name;
126
127
0
  if (!sieve_binary_read_string(denv->sblock, address, &var_name))
128
0
    return FALSE;
129
130
0
  if (oprnd->field_name != NULL) {
131
0
    sieve_code_dumpf(denv, "%s: VAR ${tst.%s}",
132
0
         oprnd->field_name, str_c(var_name));
133
0
  } else {
134
0
    sieve_code_dumpf(denv, "VAR ${tst.%s}", str_c(var_name));
135
0
  }
136
0
  return TRUE;
137
0
}
138
139
int testsuite_varnamespace_read_variable(
140
  const struct sieve_runtime_env *renv,
141
  const struct sieve_variables_namespace *nspc ATTR_UNUSED,
142
  const struct sieve_operand *oprnd, sieve_size_t *address,
143
  string_t **str_r)
144
0
{
145
0
  string_t *var_name;
146
147
0
  if (!sieve_binary_read_string(renv->sblock, address, &var_name)) {
148
0
    sieve_runtime_trace_operand_error(renv, oprnd,
149
0
      "testsuite variable operand corrupt: invalid name");
150
0
    return SIEVE_EXEC_BIN_CORRUPT;
151
0
  }
152
153
0
  if (str_r != NULL) {
154
0
    if (strcmp(str_c(var_name), "path") == 0) {
155
0
      *str_r = t_str_new_const(testsuite_test_path,
156
0
             strlen(testsuite_test_path));
157
0
    } else {
158
0
      *str_r = t_str_new_const("", 0);
159
0
    }
160
0
  }
161
0
  return SIEVE_EXEC_OK;
162
0
}
163
164
/*
165
 * Namespace registration
166
 */
167
168
static const struct sieve_extension_objects testsuite_namespaces =
169
  SIEVE_VARIABLES_DEFINE_NAMESPACE(testsuite_namespace);
170
171
const struct sieve_operand_def testsuite_namespace_operand = {
172
  .name = "testsuite-namespace",
173
  .ext_def = &testsuite_extension,
174
  .code = TESTSUITE_OPERAND_NAMESPACE,
175
  .class =  &sieve_variables_namespace_operand_class,
176
  .interface = &testsuite_namespaces,
177
};
178
179
void testsuite_variables_init(const struct sieve_extension *this_ext,
180
            struct sieve_validator *valdtr)
181
0
{
182
0
  int ret;
183
184
0
  ret = sieve_ext_variables_get_extension(this_ext->svinst,
185
0
            &testsuite_ext_variables);
186
0
  i_assert(ret == 0);
187
188
0
  sieve_variables_namespace_register(testsuite_ext_variables, valdtr,
189
0
             this_ext, &testsuite_namespace);
190
0
}