Coverage Report

Created: 2026-08-08 06:43

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/pigeonhole/src/testsuite/testsuite-message.c
Line
Count
Source
1
/* Copyright (c) Pigeonhole authors, see top-level COPYING file */
2
3
#include "lib.h"
4
#include "str.h"
5
#include "istream.h"
6
#include "smtp-params.h"
7
#include "message-address.h"
8
#include "mail-storage.h"
9
#include "master-service.h"
10
#include "mail-raw.h"
11
12
#include "sieve-common.h"
13
#include "sieve-address.h"
14
#include "sieve-error.h"
15
#include "sieve-message.h"
16
#include "sieve-interpreter.h"
17
18
#include "sieve-tool.h"
19
20
#include "testsuite-common.h"
21
#include "testsuite-message.h"
22
23
/*
24
 * Testsuite message environment
25
 */
26
27
struct testsuite_message {
28
  struct testsuite_message *next;
29
30
  struct mail_raw *mail_raw;
31
};
32
33
struct sieve_message_data testsuite_msgdata;
34
static struct smtp_params_rcpt testsuite_rcpt_params;
35
36
static struct testsuite_message *testsuite_msg;
37
38
static const char *_default_message_data =
39
"From: sender@example.com\n"
40
"To: recipient@example.org\n"
41
"Subject: Frop!\n"
42
"\n"
43
"Friep!\n";
44
45
static struct smtp_address *testsuite_env_mail_from = NULL;
46
static struct smtp_address *testsuite_env_rcpt_to = NULL;
47
static struct smtp_address *testsuite_env_orig_rcpt_to = NULL;
48
static char *testsuite_env_auth = NULL;
49
50
static pool_t testsuite_msg_pool;
51
static string_t *testsuite_msg_default;
52
static char *testsuite_msg_id = NULL;
53
54
static const struct smtp_address *
55
testsuite_message_get_address(struct mail *mail, const char *header)
56
0
{
57
0
  struct message_address *addr;
58
0
  struct smtp_address *smtp_addr;
59
0
  const char *str;
60
61
0
  if (mail_get_first_header(mail, header, &str) <= 0)
62
0
    return NULL;
63
0
  addr = message_address_parse(pool_datastack_create(),
64
0
             (const unsigned char *)str,
65
0
             strlen(str), 1, 0);
66
0
  if (addr == NULL || addr->mailbox == NULL || *addr->mailbox == '\0')
67
0
    return NULL;
68
0
  if (smtp_address_create_from_msg_temp(addr, &smtp_addr) < 0)
69
0
    return NULL;
70
0
  return smtp_addr;
71
0
}
72
73
static void testsuite_message_set_data(struct mail *mail)
74
0
{
75
0
  const struct smtp_address *recipient = NULL, *sender = NULL;
76
0
  const char *msg_id;
77
78
0
  static const struct smtp_address default_recipient = {
79
0
    .localpart = "recipient",
80
0
    .domain = "example.com",
81
0
  };
82
0
  static const struct smtp_address default_sender = {
83
0
    .localpart = "sender",
84
0
    .domain = "example.com",
85
0
  };
86
87
0
  i_free(testsuite_env_mail_from);
88
0
  i_free(testsuite_env_rcpt_to);
89
0
  i_free(testsuite_env_orig_rcpt_to);
90
0
  i_free(testsuite_env_auth);
91
0
  i_free(testsuite_msg_id);
92
93
  /*
94
   * Collect necessary message data
95
   */
96
97
  /* Get recipient address */
98
0
  recipient = testsuite_message_get_address(mail, "Envelope-To");
99
0
  if (recipient == NULL)
100
0
    recipient = testsuite_message_get_address(mail, "To");
101
0
  if (recipient == NULL)
102
0
    recipient = &default_recipient;
103
104
  /* Get sender address */
105
0
  sender = testsuite_message_get_address(mail, "Return-path");
106
0
  if (sender == NULL)
107
0
    sender = testsuite_message_get_address(mail, "Sender");
108
0
  if (sender == NULL)
109
0
    sender = testsuite_message_get_address(mail, "From");
110
0
  if (sender == NULL)
111
0
    sender = &default_sender;
112
113
0
  testsuite_env_mail_from = smtp_address_clone(default_pool, sender);
114
0
  testsuite_env_rcpt_to = smtp_address_clone(default_pool, recipient);
115
0
  testsuite_env_orig_rcpt_to = smtp_address_clone(default_pool, recipient);
116
117
0
  (void)mail_get_message_id(mail, &msg_id);
118
0
  testsuite_msg_id = i_strdup(msg_id);
119
120
0
  i_zero(&testsuite_msgdata);
121
0
  testsuite_msgdata.mail = mail;
122
0
  testsuite_msgdata.auth_user = sieve_tool_get_username(sieve_tool);
123
0
  testsuite_msgdata.envelope.mail_from = testsuite_env_mail_from;
124
0
  testsuite_msgdata.envelope.rcpt_to = testsuite_env_rcpt_to;
125
0
  testsuite_msgdata.id = testsuite_msg_id;
126
127
0
  i_zero(&testsuite_rcpt_params);
128
0
  testsuite_rcpt_params.orcpt.addr = testsuite_env_orig_rcpt_to;
129
130
0
  testsuite_msgdata.envelope.rcpt_params = &testsuite_rcpt_params;
131
0
}
132
133
static struct testsuite_message *testsuite_message_new(void)
134
0
{
135
0
  struct testsuite_message *msg;
136
137
0
  msg = i_new(struct testsuite_message, 1);
138
0
  msg->next = testsuite_msg;
139
0
  testsuite_msg = msg;
140
141
0
  return msg;
142
0
}
143
144
static void testsuite_message_new_string(string_t *mail_str)
145
0
{
146
0
  struct mail_user *mail_raw_user =
147
0
    sieve_tool_get_mail_raw_user(sieve_tool);
148
0
  struct testsuite_message *msg;
149
150
0
  msg = testsuite_message_new();
151
0
  msg->mail_raw = mail_raw_open_data(mail_raw_user, mail_str);
152
153
0
  testsuite_message_set_data(msg->mail_raw->mail);
154
0
}
155
156
static void testsuite_message_new_file(const char *mail_path)
157
0
{
158
0
  struct mail_user *mail_raw_user =
159
0
    sieve_tool_get_mail_raw_user(sieve_tool);
160
0
  struct testsuite_message *msg;
161
162
0
  msg = testsuite_message_new();
163
0
  msg->mail_raw = mail_raw_open_file(mail_raw_user, mail_path);
164
165
0
  testsuite_message_set_data(msg->mail_raw->mail);
166
0
}
167
168
static void testsuite_message_free(bool all)
169
0
{
170
0
  struct testsuite_message *msg;
171
172
0
  if (testsuite_msg == NULL)
173
0
    return;
174
175
0
  msg = (all ? testsuite_msg : testsuite_msg->next);
176
0
  while (msg != NULL) {
177
0
    struct testsuite_message *msg_next = msg->next;
178
179
0
    mail_raw_close(&msg->mail_raw);
180
0
    i_free(msg);
181
182
0
    msg = msg_next;
183
0
  }
184
0
  if (all)
185
0
    testsuite_msg = NULL;
186
0
  else
187
0
    testsuite_msg->next = NULL;
188
0
}
189
190
void testsuite_message_flush(void)
191
0
{
192
0
  testsuite_message_free(FALSE);
193
0
}
194
195
void testsuite_message_init(void)
196
0
{
197
0
  testsuite_msg_pool = pool_alloconly_create("testsuite_message", 6096);
198
199
0
  testsuite_msg_default = str_new(testsuite_msg_pool, 1024);
200
0
  str_append(testsuite_msg_default, _default_message_data);
201
202
0
  testsuite_message_new_string(testsuite_msg_default);
203
0
}
204
205
void testsuite_message_set_default(const struct sieve_runtime_env *renv)
206
0
{
207
0
  sieve_message_context_reset(renv->msgctx);
208
209
0
  testsuite_message_new_string(testsuite_msg_default);
210
0
}
211
212
void testsuite_message_set_string(const struct sieve_runtime_env *renv,
213
          string_t *message)
214
0
{
215
0
  sieve_message_context_reset(renv->msgctx);
216
217
0
  testsuite_message_new_string(message);
218
0
}
219
220
void testsuite_message_set_file(const struct sieve_runtime_env *renv,
221
        const char *file_path)
222
0
{
223
0
  sieve_message_context_reset(renv->msgctx);
224
225
0
  testsuite_message_new_file(file_path);
226
0
}
227
228
void testsuite_message_set_mail(const struct sieve_runtime_env *renv,
229
        struct mail *mail)
230
0
{
231
0
  sieve_message_context_reset(renv->msgctx);
232
233
0
  testsuite_message_set_data(mail);
234
0
}
235
236
void testsuite_message_deinit(void)
237
0
{
238
0
  testsuite_message_free(TRUE);
239
240
0
  i_free(testsuite_env_mail_from);
241
0
  i_free(testsuite_env_rcpt_to);
242
0
  i_free(testsuite_env_orig_rcpt_to);
243
0
  i_free(testsuite_env_auth);
244
0
  pool_unref(&testsuite_msg_pool);
245
0
  i_free(testsuite_msg_id);
246
0
}
247
248
void testsuite_envelope_set_sender_address(const struct sieve_runtime_env *renv,
249
             const struct smtp_address *address)
250
0
{
251
0
  sieve_message_context_reset(renv->msgctx);
252
253
0
  i_free(testsuite_env_mail_from);
254
255
0
  testsuite_env_mail_from = smtp_address_clone(default_pool, address);
256
0
  testsuite_msgdata.envelope.mail_from = testsuite_env_mail_from;
257
0
}
258
259
void testsuite_envelope_set_sender(const struct sieve_runtime_env *renv,
260
           const char *value)
261
0
{
262
0
  struct smtp_address *address = NULL;
263
0
  const char *error;
264
265
0
  if (smtp_address_parse_path(pool_datastack_create(), value,
266
0
            (SMTP_ADDRESS_PARSE_FLAG_ALLOW_EMPTY |
267
0
             SMTP_ADDRESS_PARSE_FLAG_BRACKETS_OPTIONAL),
268
0
            &address, &error) < 0) {
269
0
    e_error(testsuite_sieve_instance->event,
270
0
      "testsuite: envelope sender address "
271
0
      "'%s' is invalid: %s", value, error);
272
0
  }
273
0
  testsuite_envelope_set_sender_address(renv, address);
274
0
}
275
276
void testsuite_envelope_set_recipient_address(
277
  const struct sieve_runtime_env *renv,
278
  const struct smtp_address *address)
279
0
{
280
0
  sieve_message_context_reset(renv->msgctx);
281
282
0
  i_free(testsuite_env_rcpt_to);
283
0
  i_free(testsuite_env_orig_rcpt_to);
284
285
0
  testsuite_env_rcpt_to = smtp_address_clone(default_pool, address);
286
0
  testsuite_env_orig_rcpt_to = smtp_address_clone(default_pool, address);
287
0
  testsuite_msgdata.envelope.rcpt_to = testsuite_env_rcpt_to;
288
0
  testsuite_rcpt_params.orcpt.addr = testsuite_env_orig_rcpt_to;
289
0
}
290
291
void testsuite_envelope_set_recipient(const struct sieve_runtime_env *renv,
292
              const char *value)
293
0
{
294
0
  struct smtp_address *address = NULL;
295
0
  const char *error;
296
297
0
  if (smtp_address_parse_path(pool_datastack_create(), value,
298
0
            (SMTP_ADDRESS_PARSE_FLAG_ALLOW_LOCALPART |
299
0
             SMTP_ADDRESS_PARSE_FLAG_BRACKETS_OPTIONAL),
300
0
            &address, &error) < 0) {
301
0
    e_error(testsuite_sieve_instance->event,
302
0
      "testsuite: envelope recipient address "
303
0
      "'%s' is invalid: %s", value, error);
304
0
  }
305
0
  testsuite_envelope_set_recipient_address(renv, address);
306
0
}
307
308
void testsuite_envelope_set_orig_recipient_address(
309
  const struct sieve_runtime_env *renv,
310
  const struct smtp_address *address)
311
0
{
312
0
  sieve_message_context_reset(renv->msgctx);
313
314
0
  i_free(testsuite_env_orig_rcpt_to);
315
316
0
  testsuite_env_orig_rcpt_to = smtp_address_clone(default_pool, address);
317
0
  testsuite_rcpt_params.orcpt.addr = testsuite_env_orig_rcpt_to;
318
0
}
319
320
void testsuite_envelope_set_orig_recipient(const struct sieve_runtime_env *renv,
321
             const char *value)
322
0
{
323
0
  struct smtp_address *address = NULL;
324
0
  const char *error;
325
326
0
  if (smtp_address_parse_path(pool_datastack_create(), value,
327
0
            (SMTP_ADDRESS_PARSE_FLAG_ALLOW_LOCALPART |
328
0
             SMTP_ADDRESS_PARSE_FLAG_BRACKETS_OPTIONAL),
329
0
            &address, &error) < 0) {
330
0
    e_error(testsuite_sieve_instance->event,
331
0
      "testsuite: envelope recipient address "
332
0
      "'%s' is invalid: %s", value, error);
333
0
  }
334
0
  testsuite_envelope_set_orig_recipient_address(renv, address);
335
0
}
336
337
void testsuite_envelope_set_auth_user(const struct sieve_runtime_env *renv,
338
              const char *value)
339
0
{
340
0
  sieve_message_context_reset(renv->msgctx);
341
342
0
  i_free(testsuite_env_auth);
343
344
0
  testsuite_env_auth = i_strdup(value);
345
0
  testsuite_msgdata.auth_user = testsuite_env_auth;
346
0
}