Coverage Report

Created: 2026-07-16 07:09

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/pigeonhole/src/testsuite/cmd-test-binary.c
Line
Count
Source
1
/* Copyright (c) Pigeonhole authors, see top-level COPYING file */
2
3
#include "sieve-common.h"
4
#include "sieve-commands.h"
5
#include "sieve-validator.h"
6
#include "sieve-generator.h"
7
#include "sieve-interpreter.h"
8
#include "sieve-code.h"
9
#include "sieve-binary.h"
10
#include "sieve-dump.h"
11
12
#include "testsuite-common.h"
13
#include "testsuite-binary.h"
14
#include "testsuite-script.h"
15
16
/*
17
 * Commands
18
 */
19
20
static bool
21
cmd_test_binary_validate(struct sieve_validator *valdtr,
22
      struct sieve_command *cmd);
23
static bool
24
cmd_test_binary_generate(const struct sieve_codegen_env *cgenv,
25
       struct sieve_command *ctx);
26
27
/* Test_binary_load command
28
 *
29
 * Syntax:
30
 *   test_binary_load <binary-name: string>
31
 */
32
33
const struct sieve_command_def cmd_test_binary_load = {
34
  .identifier = "test_binary_load",
35
  .type = SCT_COMMAND,
36
  .positional_args = 1,
37
  .subtests = 0,
38
  .block_allowed = FALSE,
39
  .block_required = FALSE,
40
  .validate = cmd_test_binary_validate,
41
  .generate = cmd_test_binary_generate,
42
};
43
44
/* Test_binary_save command
45
 *
46
 * Syntax:
47
 *   test_binary_save <binary-name: string>
48
 */
49
50
const struct sieve_command_def cmd_test_binary_save = {
51
  .identifier = "test_binary_save",
52
  .type = SCT_COMMAND,
53
  .positional_args = 1,
54
  .subtests = 0,
55
  .block_allowed = FALSE,
56
  .block_required = FALSE,
57
  .validate = cmd_test_binary_validate,
58
  .generate = cmd_test_binary_generate,
59
};
60
61
/*
62
 * Operations
63
 */
64
65
static bool
66
cmd_test_binary_operation_dump(const struct sieve_dumptime_env *denv,
67
             sieve_size_t *address);
68
static int
69
cmd_test_binary_operation_execute(const struct sieve_runtime_env *renv,
70
          sieve_size_t *address);
71
72
/* test_binary_create operation */
73
74
const struct sieve_operation_def test_binary_load_operation = {
75
  .mnemonic = "TEST_BINARY_LOAD",
76
  .ext_def = &testsuite_extension,
77
  .code = TESTSUITE_OPERATION_TEST_BINARY_LOAD,
78
  .dump = cmd_test_binary_operation_dump,
79
  .execute = cmd_test_binary_operation_execute,
80
};
81
82
/* test_binary_delete operation */
83
84
const struct sieve_operation_def test_binary_save_operation = {
85
  .mnemonic = "TEST_BINARY_SAVE",
86
  .ext_def = &testsuite_extension,
87
  .code = TESTSUITE_OPERATION_TEST_BINARY_SAVE,
88
  .dump = cmd_test_binary_operation_dump,
89
  .execute = cmd_test_binary_operation_execute,
90
};
91
92
/*
93
 * Validation
94
 */
95
96
static bool
97
cmd_test_binary_validate(struct sieve_validator *valdtr,
98
       struct sieve_command *cmd)
99
0
{
100
0
  struct sieve_ast_argument *arg = cmd->first_positional;
101
102
0
  if (!sieve_validate_positional_argument(valdtr, cmd, arg, "binary-name",
103
0
            1, SAAT_STRING))
104
0
    return FALSE;
105
106
0
  return sieve_validator_argument_activate(valdtr, cmd, arg, FALSE);
107
0
}
108
109
/*
110
 * Code generation
111
 */
112
113
static bool
114
cmd_test_binary_generate(const struct sieve_codegen_env *cgenv,
115
       struct sieve_command *cmd)
116
0
{
117
  /* Emit operation */
118
0
  if (sieve_command_is(cmd, cmd_test_binary_load)) {
119
0
    sieve_operation_emit(cgenv->sblock, cmd->ext,
120
0
             &test_binary_load_operation);
121
0
  } else if (sieve_command_is(cmd, cmd_test_binary_save)) {
122
0
    sieve_operation_emit(cgenv->sblock, cmd->ext,
123
0
             &test_binary_save_operation);
124
0
  } else {
125
0
    i_unreached();
126
0
  }
127
128
  /* Generate arguments */
129
0
  if (!sieve_generate_arguments(cgenv, cmd, NULL))
130
0
    return FALSE;
131
132
0
  return TRUE;
133
0
}
134
135
/*
136
 * Code dump
137
 */
138
139
static bool
140
cmd_test_binary_operation_dump(const struct sieve_dumptime_env *denv,
141
             sieve_size_t *address)
142
0
{
143
0
  sieve_code_dumpf(denv, "%s:", sieve_operation_mnemonic(denv->oprtn));
144
145
0
  sieve_code_descend(denv);
146
147
0
  return sieve_opr_string_dump(denv, address, "binary-name");
148
0
}
149
150
/*
151
 * Intepretation
152
 */
153
154
static int
155
cmd_test_binary_operation_execute(const struct sieve_runtime_env *renv,
156
          sieve_size_t *address)
157
0
{
158
0
  const struct sieve_operation *oprtn = renv->oprtn;
159
0
  string_t *binary_name = NULL;
160
0
  int ret;
161
162
  /*
163
   * Read operands
164
   */
165
166
  /* Binary Name */
167
168
0
  ret = sieve_opr_string_read(renv, address, "binary-name", &binary_name);
169
0
  if (ret <= 0 )
170
0
    return ret;
171
172
  /*
173
   * Perform operation
174
   */
175
176
0
  if (sieve_operation_is(oprtn, test_binary_load_operation)) {
177
0
    struct sieve_binary *sbin =
178
0
      testsuite_binary_load(str_c(binary_name));
179
180
0
    if (sieve_runtime_trace_active(renv, SIEVE_TRLVL_COMMANDS)) {
181
0
      sieve_runtime_trace(renv, 0, "testsuite: "
182
0
              "test_binary_load command");
183
0
      sieve_runtime_trace_descend(renv);
184
0
      sieve_runtime_trace(renv, 0, "load binary '%s'",
185
0
              str_c(binary_name));
186
0
    }
187
188
0
    if ( sbin != NULL ) {
189
0
      testsuite_script_set_binary(renv, sbin);
190
191
0
      sieve_binary_unref(&sbin);
192
0
    } else {
193
0
      e_error(testsuite_sieve_instance->event,
194
0
        "failed to load binary %s", str_c(binary_name));
195
0
      return SIEVE_EXEC_FAILURE;
196
0
    }
197
0
  } else if ( sieve_operation_is(oprtn, test_binary_save_operation) ) {
198
0
    struct sieve_binary *sbin = testsuite_script_get_binary(renv);
199
200
0
    if ( sieve_runtime_trace_active(renv, SIEVE_TRLVL_COMMANDS) ) {
201
0
      sieve_runtime_trace(renv, 0, "testsuite: "
202
0
              "test_binary_save command");
203
0
      sieve_runtime_trace_descend(renv);
204
0
      sieve_runtime_trace(renv, 0, "save binary '%s'",
205
0
              str_c(binary_name));
206
0
    }
207
208
0
    if ( sbin != NULL )
209
0
      testsuite_binary_save(sbin, str_c(binary_name));
210
0
    else {
211
0
      e_error(testsuite_sieve_instance->event,
212
0
        "no compiled binary to save as %s",
213
0
        str_c(binary_name));
214
0
      return SIEVE_EXEC_FAILURE;
215
0
    }
216
0
  } else {
217
0
    i_unreached();
218
0
  }
219
220
0
  return SIEVE_EXEC_OK;
221
0
}