Coverage Report

Created: 2026-10-28 07:22

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