Coverage Report

Created: 2026-09-03 07:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/pigeonhole/src/lib-sieve/plugins/ihave/cmd-error.c
Line
Count
Source
1
/* Copyright (c) Pigeonhole authors, see top-level COPYING file */
2
3
#include "lib.h"
4
#include "str-sanitize.h"
5
6
#include "sieve-extensions.h"
7
#include "sieve-commands.h"
8
#include "sieve-code.h"
9
10
#include "sieve-validator.h"
11
#include "sieve-generator.h"
12
#include "sieve-binary.h"
13
#include "sieve-interpreter.h"
14
#include "sieve-dump.h"
15
16
#include "ext-ihave-common.h"
17
18
/*
19
 * Error command
20
 *
21
 * Syntax
22
 *   error <message: string>
23
 */
24
25
static bool
26
cmd_error_validate(struct sieve_validator *valdtr, struct sieve_command *tst);
27
static bool
28
cmd_error_generate(const struct sieve_codegen_env *cgenv,
29
       struct sieve_command *ctx);
30
31
const struct sieve_command_def error_command = {
32
  .identifier = "error",
33
  .type = SCT_COMMAND,
34
  .positional_args = 1,
35
  .subtests = 0,
36
  .block_allowed = FALSE,
37
  .block_required = FALSE,
38
  .validate = cmd_error_validate,
39
  .generate = cmd_error_generate,
40
};
41
42
/*
43
 * Body operation
44
 */
45
46
static bool
47
cmd_error_operation_dump(const struct sieve_dumptime_env *denv,
48
       sieve_size_t *address);
49
static int
50
cmd_error_operation_execute(const struct sieve_runtime_env *renv,
51
          sieve_size_t *address);
52
53
const struct sieve_operation_def cmd_error_operation = {
54
  .mnemonic = "ERROR",
55
  .ext_def = &ihave_extension,
56
  .code = EXT_IHAVE_OPERATION_ERROR,
57
  .dump = cmd_error_operation_dump,
58
  .execute = cmd_error_operation_execute,
59
};
60
61
/*
62
 * Validation
63
 */
64
65
static bool
66
cmd_error_validate(struct sieve_validator *valdtr, struct sieve_command *tst)
67
0
{
68
0
  struct sieve_ast_argument *arg = tst->first_positional;
69
70
0
  if (!sieve_validate_positional_argument(valdtr, tst, arg, "message", 1,
71
0
            SAAT_STRING))
72
0
    return FALSE;
73
0
  return sieve_validator_argument_activate(valdtr, tst, arg, FALSE);
74
0
}
75
76
/*
77
 * Code generation
78
 */
79
80
static bool
81
cmd_error_generate(const struct sieve_codegen_env *cgenv,
82
       struct sieve_command *cmd)
83
0
{
84
0
  (void)sieve_operation_emit(cgenv->sblock, cmd->ext,
85
0
           &cmd_error_operation);
86
87
  /* Generate arguments */
88
0
  return sieve_generate_arguments(cgenv, cmd, NULL);
89
0
}
90
91
/*
92
 * Code dump
93
 */
94
95
static bool
96
cmd_error_operation_dump(const struct sieve_dumptime_env *denv,
97
       sieve_size_t *address)
98
0
{
99
0
  sieve_code_dumpf(denv, "ERROR");
100
0
  sieve_code_descend(denv);
101
102
0
  return sieve_opr_string_dump(denv, address, "message");
103
0
}
104
105
/*
106
 * Interpretation
107
 */
108
109
static int
110
cmd_error_operation_execute(const struct sieve_runtime_env *renv,
111
          sieve_size_t *address)
112
0
{
113
0
  string_t *message;
114
0
  int ret;
115
116
  /*
117
   * Read operands
118
   */
119
120
  /* Read message */
121
122
0
  ret = sieve_opr_string_read(renv, address, "message", &message);
123
0
  if (ret <= 0)
124
0
    return ret;
125
126
  /*
127
   * Perform operation
128
   */
129
130
0
  sieve_runtime_trace(renv, SIEVE_TRLVL_COMMANDS, "error \"%s\"",
131
0
          str_sanitize(str_c(message), 80));
132
133
0
  sieve_runtime_error(renv, NULL, "%s", str_c(message));
134
135
0
  return SIEVE_EXEC_FAILURE;
136
0
}