diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 17:36:47 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 17:36:47 +0000 |
commit | 0441d265f2bb9da249c7abf333f0f771fadb4ab5 (patch) | |
tree | 3f3789daa2f6db22da6e55e92bee0062a7d613fe /src/lib-smtp/test-smtp-params.c | |
parent | Initial commit. (diff) | |
download | dovecot-0441d265f2bb9da249c7abf333f0f771fadb4ab5.tar.xz dovecot-0441d265f2bb9da249c7abf333f0f771fadb4ab5.zip |
Adding upstream version 1:2.3.21+dfsg1.upstream/1%2.3.21+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/lib-smtp/test-smtp-params.c')
-rw-r--r-- | src/lib-smtp/test-smtp-params.c | 894 |
1 files changed, 894 insertions, 0 deletions
diff --git a/src/lib-smtp/test-smtp-params.c b/src/lib-smtp/test-smtp-params.c new file mode 100644 index 0000000..2847441 --- /dev/null +++ b/src/lib-smtp/test-smtp-params.c @@ -0,0 +1,894 @@ +/* Copyright (c) 2013-2018 Dovecot authors, see the included COPYING file */ + +#include "test-lib.h" +#include "str.h" +#include "array.h" +#include "test-common.h" +#include "smtp-common.h" +#include "smtp-address.h" +#include "smtp-params.h" + +static const char *test_extensions[] = { "FROP", "FRUP", NULL }; + +static struct smtp_address test_address1 = + { .localpart = NULL, .domain = NULL }; +static struct smtp_address test_address2 = + { .localpart = "user+detail", .domain = NULL }; +static struct smtp_address test_address3 = + { .localpart = "e=mc2", .domain = "example.com" }; + +static struct smtp_param test_params1[] = { + { .keyword = "FROP", .value = "friep" } +}; +static struct smtp_param test_params2[] = { + { .keyword = "FROP", .value = "friep" }, + { .keyword = "FRUP", .value = "frml" } +}; + +static struct buffer test_params_buffer1 = { + .data = (void*)&test_params1, + .used = sizeof(test_params1) +}; +static struct buffer test_params_buffer2 = { + .data = (void*)&test_params2, + .used = sizeof(test_params2) +}; + +/* Valid mail params tests */ + +struct valid_mail_params_parse_test { + const char *input, *output; + + enum smtp_capability caps; + const char *const *extensions; + const char *const *body_extensions; + + struct smtp_params_mail params; +}; + +static const struct valid_mail_params_parse_test +valid_mail_params_parse_tests[] = { + /* AUTH */ + { + .input = "AUTH=<>", + .caps = SMTP_CAPABILITY_AUTH, + .params = { + .auth = &test_address1 + } + }, + { + .input = "AUTH=user+2Bdetail", + .caps = SMTP_CAPABILITY_AUTH, + .params = { + .auth = &test_address2 + } + }, + { + .input = "AUTH=e+3Dmc2@example.com", + .caps = SMTP_CAPABILITY_AUTH, + .params = { + .auth = &test_address3 + } + }, + /* BODY */ + { + .input = "", + .caps = SMTP_CAPABILITY_8BITMIME, + .params = { + .body = { + .type = SMTP_PARAM_MAIL_BODY_TYPE_UNSPECIFIED, + } + } + }, + { + .input = "BODY=7BIT", + .caps = SMTP_CAPABILITY_8BITMIME, + .params = { + .body = { + .type = SMTP_PARAM_MAIL_BODY_TYPE_7BIT, + } + } + }, + { + .input = "BODY=8BITMIME", + .caps = SMTP_CAPABILITY_8BITMIME, + .params = { + .body = { + .type = SMTP_PARAM_MAIL_BODY_TYPE_8BITMIME, + } + } + }, + { + .input = "BODY=BINARYMIME", + .caps = SMTP_CAPABILITY_8BITMIME | + SMTP_CAPABILITY_BINARYMIME | + SMTP_CAPABILITY_CHUNKING, + .params = { + .body = { + .type = SMTP_PARAM_MAIL_BODY_TYPE_BINARYMIME, + } + } + }, + { + .input = "BODY=FROP", + .caps = SMTP_CAPABILITY_8BITMIME | + SMTP_CAPABILITY_BINARYMIME | + SMTP_CAPABILITY_CHUNKING, + .body_extensions = test_extensions, + .params = { + .body = { + .type = SMTP_PARAM_MAIL_BODY_TYPE_EXTENSION, + .ext = "FROP" + } + } + }, + /* ENVID */ + { + .input = "", + .caps = SMTP_CAPABILITY_DSN, + .params = { + .envid = NULL, + } + }, + { + .input = "ENVID=", + .caps = SMTP_CAPABILITY_DSN, + .params = { + .envid = "", + } + }, + { + .input = "ENVID=AABBCCDD", + .caps = SMTP_CAPABILITY_DSN, + .params = { + .envid = "AABBCCDD", + } + }, + { + .input = "ENVID=AA+2BBB+3DCC+2BDD", + .caps = SMTP_CAPABILITY_DSN, + .params = { + .envid = "AA+BB=CC+DD", + } + }, + /* RET */ + { + .input = "", + .caps = SMTP_CAPABILITY_DSN, + .params = { + .ret = SMTP_PARAM_MAIL_RET_UNSPECIFIED, + } + }, + { + .input = "RET=HDRS", + .caps = SMTP_CAPABILITY_DSN, + .params = { + .ret = SMTP_PARAM_MAIL_RET_HDRS, + } + }, + { + .input = "RET=FULL", + .caps = SMTP_CAPABILITY_DSN, + .params = { + .ret = SMTP_PARAM_MAIL_RET_FULL, + } + }, + /* SIZE */ + { + .input = "", + .caps = SMTP_CAPABILITY_SIZE, + .params = { + .size = 0 + } + }, + { + .input = "SIZE=267914296", + .caps = SMTP_CAPABILITY_SIZE, + .params = { + .size = 267914296 + } + }, + /* <extensions> */ + { + .input = "FROP=friep", + .caps = SMTP_CAPABILITY_SIZE, + .extensions = test_extensions, + .params = { + .extra_params = { + .arr = { + .buffer = &test_params_buffer1, + .element_size = sizeof(struct smtp_param) + } + } + } + }, + { + .input = "FROP=friep FRUP=frml", + .extensions = test_extensions, + .params = { + .extra_params = { + .arr = { + .buffer = &test_params_buffer2, + .element_size = sizeof(struct smtp_param) + } + } + } + } +}; + +unsigned int valid_mail_params_parse_test_count = + N_ELEMENTS(valid_mail_params_parse_tests); + +static void +test_smtp_mail_params_auth(const struct smtp_params_mail *test, + const struct smtp_params_mail *parsed) +{ + if (parsed->auth->localpart == NULL || + test->auth->localpart == NULL) { + test_out(t_strdup_printf("params.auth->localpart = %s", + parsed->auth->localpart), + (parsed->auth->localpart == test->auth->localpart)); + } else { + test_out(t_strdup_printf("params.auth->localpart = \"%s\"", + parsed->auth->localpart), + strcmp(parsed->auth->localpart, + test->auth->localpart) == 0); + } + if (parsed->auth->domain == NULL || + test->auth->domain == NULL) { + test_out(t_strdup_printf("params.auth->domain = %s", + parsed->auth->domain), + (parsed->auth->domain == test->auth->domain)); + } else { + test_out(t_strdup_printf("params.auth->domain = \"%s\"", + parsed->auth->domain), + strcmp(parsed->auth->domain, + test->auth->domain) == 0); + } +} + +static void +test_smtp_mail_params_body(const struct smtp_params_mail *test, + const struct smtp_params_mail *parsed) +{ + const char *type_name = NULL; + + switch (parsed->body.type) { + case SMTP_PARAM_MAIL_BODY_TYPE_UNSPECIFIED: + type_name = "<UNSPECIFIED>"; + break; + case SMTP_PARAM_MAIL_BODY_TYPE_7BIT: + type_name = "7BIT"; + break; + case SMTP_PARAM_MAIL_BODY_TYPE_8BITMIME: + type_name = "8BITMIME"; + break; + case SMTP_PARAM_MAIL_BODY_TYPE_BINARYMIME: + type_name = "BINARYMIME"; + break; + case SMTP_PARAM_MAIL_BODY_TYPE_EXTENSION: + type_name = parsed->body.ext; + break; + default: + i_unreached(); + } + + test_out(t_strdup_printf("params.body.type = %s", type_name), + (parsed->body.type == test->body.type && + (parsed->body.type != SMTP_PARAM_MAIL_BODY_TYPE_EXTENSION || + (parsed->body.ext != NULL && + strcmp(parsed->body.ext, test->body.ext) == 0)))); +} + +static void +test_smtp_mail_params_envid(const struct smtp_params_mail *test, + const struct smtp_params_mail *parsed) +{ + if (parsed->envid == NULL || test->envid == NULL) { + test_out(t_strdup_printf("params.auth->localpart = %s", + parsed->envid), + (parsed->envid == test->envid)); + } else { + test_out(t_strdup_printf("params.auth->localpart = \"%s\"", + parsed->envid), + strcmp(parsed->envid, test->envid) == 0); + } +} + +static void +test_smtp_mail_params_ret(const struct smtp_params_mail *test, + const struct smtp_params_mail *parsed) +{ + const char *ret_name = NULL; + + switch (parsed->ret) { + case SMTP_PARAM_MAIL_RET_UNSPECIFIED: + ret_name = "<UNSPECIFIED>"; + break; + case SMTP_PARAM_MAIL_RET_HDRS: + ret_name = "HDRS"; + break; + case SMTP_PARAM_MAIL_RET_FULL: + ret_name = "FULL"; + break; + default: + i_unreached(); + } + + test_out(t_strdup_printf("params.ret = %s", ret_name), + parsed->ret == test->ret); +} + +static void +test_smtp_mail_params_size(const struct smtp_params_mail *test, + const struct smtp_params_mail *parsed) +{ + test_out(t_strdup_printf("params.size = %"PRIuUOFF_T, parsed->size), + parsed->size == test->size); +} + +static void +test_smtp_mail_params_extensions(const struct smtp_params_mail *test, + const struct smtp_params_mail *parsed) +{ + const struct smtp_param *tparam, *pparam; + unsigned int i; + + if (!array_is_created(&test->extra_params) || + array_count(&test->extra_params) == 0) { + test_out(t_strdup_printf("params.extra_params.count = %u", + (!array_is_created(&parsed->extra_params) ? + 0 : array_count(&parsed->extra_params))), + (!array_is_created(&parsed->extra_params) || + array_count(&parsed->extra_params) == 0)); + return; + } + + if (!array_is_created(&parsed->extra_params) || + array_count(&parsed->extra_params) == 0) { + test_out("params.extra_params.count = 0", FALSE); + return; + } + + if (array_count(&test->extra_params) != + array_count(&parsed->extra_params)) { + test_out(t_strdup_printf("params.extra_params.count = %u", + (!array_is_created(&parsed->extra_params) ? + 0 : array_count(&parsed->extra_params))), FALSE); + return; + } + + for (i = 0; i < array_count(&test->extra_params); i++) { + tparam = array_idx(&test->extra_params, i); + pparam = array_idx(&parsed->extra_params, i); + + test_out(t_strdup_printf("params.extra_params[%u] = [\"%s\"=\"%s\"]", + i, pparam->keyword, pparam->value), + strcmp(pparam->keyword, tparam->keyword) == 0 && + ((pparam->value == NULL && tparam->value == NULL) || + (pparam->value != NULL && tparam->value != NULL && + strcmp(pparam->value, tparam->value) == 0))); + } +} + +static void test_smtp_mail_params_parse_valid(void) +{ + unsigned int i; + + for (i = 0; i < valid_mail_params_parse_test_count; i++) T_BEGIN { + const struct valid_mail_params_parse_test *test; + struct smtp_params_mail params; + enum smtp_param_parse_error error_code; + const char *error = NULL, *output; + int ret; + + test = &valid_mail_params_parse_tests[i]; + ret = smtp_params_mail_parse(pool_datastack_create(), + test->input, test->caps, test->extensions, + test->body_extensions, ¶ms, &error_code, &error); + + test_begin(t_strdup_printf("smtp mail params valid [%d]", i)); + test_out_reason(t_strdup_printf("parse(\"%s\")", test->input), + ret >= 0, error); + + if (ret >= 0) { + string_t *encoded; + + /* AUTH */ + if ((test->caps & SMTP_CAPABILITY_AUTH) != 0) + test_smtp_mail_params_auth(&test->params, ¶ms); + /* BODY */ + if ((test->caps & SMTP_CAPABILITY_8BITMIME) != 0 || + (test->caps & SMTP_CAPABILITY_BINARYMIME) != 0) + test_smtp_mail_params_body(&test->params, ¶ms); + /* ENVID */ + if ((test->caps & SMTP_CAPABILITY_DSN) != 0) + test_smtp_mail_params_envid(&test->params, ¶ms); + /* RET */ + if ((test->caps & SMTP_CAPABILITY_DSN) != 0) + test_smtp_mail_params_ret(&test->params, ¶ms); + /* SIZE */ + if ((test->caps & SMTP_CAPABILITY_SIZE) != 0) + test_smtp_mail_params_size(&test->params, ¶ms); + /* <extensions> */ + if (test->extensions != NULL) + test_smtp_mail_params_extensions(&test->params, ¶ms); + + encoded = t_str_new(256); + smtp_params_mail_write(encoded, test->caps, + test->extensions, ¶ms); + + output = (test->output == NULL ? test->input : test->output); + test_out(t_strdup_printf("encode() = \"%s\"", + str_c(encoded)), + strcmp(str_c(encoded), output) == 0); + } + test_end(); + } T_END; +} + +/* Invalid mail params tests */ + +struct invalid_mail_params_parse_test { + const char *input; + + enum smtp_capability caps; + const char *const *extensions; +}; + +static const struct invalid_mail_params_parse_test +invalid_mail_params_parse_tests[] = { + /* AUTH */ + { + .input = "AUTH=<>", + }, + { + .input = "AUTH=++", + .caps = SMTP_CAPABILITY_AUTH + }, + /* BODY */ + { + .input = "BODY=8BITMIME", + }, + { + .input = "BODY=BINARYMIME", + }, + { + .input = "BODY=BINARYMIME", + .caps = SMTP_CAPABILITY_BINARYMIME + }, + { + .input = "BODY=FROP", + .caps = SMTP_CAPABILITY_8BITMIME + }, + /* ENVID */ + { + .input = "ENVID=AABBCC", + }, + { + .input = "ENVID=++", + .caps = SMTP_CAPABILITY_DSN + }, + /* RET */ + { + .input = "RET=FULL", + }, + { + .input = "RET=HDR", + }, + { + .input = "RET=FROP", + .caps = SMTP_CAPABILITY_DSN + }, + /* SIZE */ + { + .input = "SIZE=13", + }, + { + .input = "SIZE=ABC", + .caps = SMTP_CAPABILITY_SIZE + } +}; + +unsigned int invalid_mail_params_parse_test_count = + N_ELEMENTS(invalid_mail_params_parse_tests); + +static void test_smtp_mail_params_parse_invalid(void) +{ + unsigned int i; + + for (i = 0; i < invalid_mail_params_parse_test_count; i++) T_BEGIN { + const struct invalid_mail_params_parse_test *test; + struct smtp_params_mail params; + enum smtp_param_parse_error error_code; + const char *error = NULL; + int ret; + + test = &invalid_mail_params_parse_tests[i]; + ret = smtp_params_mail_parse(pool_datastack_create(), + test->input, test->caps, + test->extensions, NULL, + ¶ms, &error_code, &error); + + test_begin(t_strdup_printf("smtp mail params invalid [%d]", i)); + test_out_reason(t_strdup_printf("parse(\"%s\")", test->input), + ret < 0, error); + test_end(); + } T_END; +} + +/* Valid rcpt params tests */ + +struct valid_rcpt_params_parse_test { + const char *input, *output; + + enum smtp_param_rcpt_parse_flags flags; + enum smtp_capability caps; + const char *const *extensions; + + struct smtp_params_rcpt params; +}; + +static const struct valid_rcpt_params_parse_test +valid_rcpt_params_parse_tests[] = { + /* ORCPT */ + { + .input = "ORCPT=rfc822;e+3Dmc2@example.com", + .caps = SMTP_CAPABILITY_DSN, + .params = { + .orcpt = { + .addr = &test_address3 + } + } + }, + { + .input = "ORCPT=rfc822;<e+3Dmc2@example.com>", + .output = "ORCPT=rfc822;e+3Dmc2@example.com", + .caps = SMTP_CAPABILITY_DSN, + .params = { + .orcpt = { + .addr = &test_address3 + } + } + }, + { + .input = "ORCPT=rfc822;user+2Bdetail", + .flags = SMTP_PARAM_RCPT_FLAG_ORCPT_ALLOW_LOCALPART, + .caps = SMTP_CAPABILITY_DSN, + .params = { + .orcpt = { + .addr = &test_address2 + } + } + }, + { + .input = "ORCPT=rfc822;<user+2Bdetail>", + .output = "ORCPT=rfc822;user+2Bdetail", + .flags = SMTP_PARAM_RCPT_FLAG_ORCPT_ALLOW_LOCALPART, + .caps = SMTP_CAPABILITY_DSN, + .params = { + .orcpt = { + .addr = &test_address2 + } + } + }, + /* NOTIFY */ + { + .input = "", + .caps = SMTP_CAPABILITY_DSN, + .params = { + .notify = SMTP_PARAM_RCPT_NOTIFY_UNSPECIFIED, + } + }, + { + .input = "NOTIFY=SUCCESS", + .caps = SMTP_CAPABILITY_DSN, + .params = { + .notify = SMTP_PARAM_RCPT_NOTIFY_SUCCESS, + } + }, + { + .input = "NOTIFY=FAILURE", + .caps = SMTP_CAPABILITY_DSN, + .params = { + .notify = SMTP_PARAM_RCPT_NOTIFY_FAILURE, + } + }, + { + .input = "NOTIFY=DELAY", + .caps = SMTP_CAPABILITY_DSN, + .params = { + .notify = SMTP_PARAM_RCPT_NOTIFY_DELAY, + } + }, + { + .input = "NOTIFY=NEVER", + .caps = SMTP_CAPABILITY_DSN, + .params = { + .notify = SMTP_PARAM_RCPT_NOTIFY_NEVER, + } + }, + { + .input = "NOTIFY=SUCCESS,FAILURE,DELAY", + .caps = SMTP_CAPABILITY_DSN, + .params = { + .notify = SMTP_PARAM_RCPT_NOTIFY_SUCCESS | + SMTP_PARAM_RCPT_NOTIFY_FAILURE | + SMTP_PARAM_RCPT_NOTIFY_DELAY, + } + }, + /* <extensions> */ + { + .input = "FROP=friep", + .caps = SMTP_CAPABILITY_SIZE, + .extensions = test_extensions, + .params = { + .extra_params = { + .arr = { + .buffer = &test_params_buffer1, + .element_size = sizeof(struct smtp_param) + } + } + } + }, + { + .input = "FROP=friep FRUP=frml", + .extensions = test_extensions, + .params = { + .extra_params = { + .arr = { + .buffer = &test_params_buffer2, + .element_size = sizeof(struct smtp_param) + } + } + } + } +}; + +unsigned int valid_rcpt_params_parse_test_count = + N_ELEMENTS(valid_rcpt_params_parse_tests); + +static void +test_smtp_rcpt_params_orcpt(const struct smtp_params_rcpt *test, + const struct smtp_params_rcpt *parsed) +{ + if (parsed->orcpt.addr == NULL) { + test_out("params.orcpt.addr = NULL", + test->orcpt.addr == NULL); + return; + } + + if (parsed->orcpt.addr->localpart == NULL || + test->orcpt.addr->localpart == NULL) { + test_out(t_strdup_printf("params.orcpt.addr->localpart = %s", + parsed->orcpt.addr->localpart), + (parsed->orcpt.addr->localpart == + test->orcpt.addr->localpart)); + } else { + test_out(t_strdup_printf("params.orcpt.addr->localpart = \"%s\"", + parsed->orcpt.addr->localpart), + strcmp(parsed->orcpt.addr->localpart, + test->orcpt.addr->localpart) == 0); + } + if (parsed->orcpt.addr->domain == NULL || + test->orcpt.addr->domain == NULL) { + test_out(t_strdup_printf("params.orcpt.addr->domain = %s", + parsed->orcpt.addr->domain), + (parsed->orcpt.addr->domain == + test->orcpt.addr->domain)); + } else { + test_out(t_strdup_printf("params.orcpt.addr->domain = \"%s\"", + parsed->orcpt.addr->domain), + strcmp(parsed->orcpt.addr->domain, + test->orcpt.addr->domain) == 0); + } +} + + +static void +test_smtp_rcpt_params_notify(const struct smtp_params_rcpt *test, + const struct smtp_params_rcpt *parsed) +{ + string_t *notify_name; + + notify_name = t_str_new(64); + if (parsed->notify == 0) { + str_append(notify_name, "<UNSPECIFIED>"); + } else if ((parsed->notify & SMTP_PARAM_RCPT_NOTIFY_NEVER) != 0) { + i_assert((parsed->notify & SMTP_PARAM_RCPT_NOTIFY_SUCCESS) == 0); + i_assert((parsed->notify & SMTP_PARAM_RCPT_NOTIFY_FAILURE) == 0); + i_assert((parsed->notify & SMTP_PARAM_RCPT_NOTIFY_DELAY) == 0); + str_append(notify_name, "NEVER"); + } else { + if ((parsed->notify & SMTP_PARAM_RCPT_NOTIFY_SUCCESS) != 0) + str_append(notify_name, "SUCCESS"); + if ((parsed->notify & SMTP_PARAM_RCPT_NOTIFY_FAILURE) != 0) { + if (str_len(notify_name) > 0) + str_append_c(notify_name, ','); + str_append(notify_name, "FAILURE"); + } + if ((parsed->notify & SMTP_PARAM_RCPT_NOTIFY_DELAY) != 0) { + if (str_len(notify_name) > 0) + str_append_c(notify_name, ','); + str_append(notify_name, "DELAY"); + } + } + + test_out(t_strdup_printf("params.notify = %s", str_c(notify_name)), + parsed->notify == test->notify); +} + +static void +test_smtp_rcpt_params_extensions(const struct smtp_params_rcpt *test, + const struct smtp_params_rcpt *parsed) +{ + const struct smtp_param *tparam, *pparam; + unsigned int i; + + if (!array_is_created(&test->extra_params) || + array_count(&test->extra_params) == 0) { + test_out(t_strdup_printf("params.extra_params.count = %u", + (!array_is_created(&parsed->extra_params) ? + 0 : array_count(&parsed->extra_params))), + (!array_is_created(&parsed->extra_params) || + array_count(&parsed->extra_params) == 0)); + return; + } + + if (!array_is_created(&parsed->extra_params) || + array_count(&parsed->extra_params) == 0) { + test_out("params.extra_params.count = 0", FALSE); + return; + } + + if (array_count(&test->extra_params) != + array_count(&parsed->extra_params)) { + test_out(t_strdup_printf("params.extra_params.count = %u", + (!array_is_created(&parsed->extra_params) ? 0 : + array_count(&parsed->extra_params))), FALSE); + return; + } + + for (i = 0; i < array_count(&test->extra_params); i++) { + tparam = array_idx(&test->extra_params, i); + pparam = array_idx(&parsed->extra_params, i); + + test_out(t_strdup_printf("params.extra_params[%u] = [\"%s\"=\"%s\"]", + i, pparam->keyword, pparam->value), + strcmp(pparam->keyword, tparam->keyword) == 0 && + ((pparam->value == NULL && tparam->value == NULL) || + (pparam->value != NULL && tparam->value != NULL && + strcmp(pparam->value, tparam->value) == 0))); + } +} + +static void test_smtp_rcpt_params_parse_valid(void) +{ + unsigned int i; + + for (i = 0; i < valid_rcpt_params_parse_test_count; i++) T_BEGIN { + const struct valid_rcpt_params_parse_test *test; + struct smtp_params_rcpt params; + enum smtp_param_parse_error error_code; + const char *error = NULL, *output; + int ret; + + test = &valid_rcpt_params_parse_tests[i]; + ret = smtp_params_rcpt_parse(pool_datastack_create(), + test->input, test->flags, + test->caps, test->extensions, + ¶ms, &error_code, &error); + + test_begin(t_strdup_printf("smtp rcpt params valid [%d]", i)); + test_out_reason(t_strdup_printf("parse(\"%s\")", + test->input), ret >= 0, error); + + if (ret >= 0) { + string_t *encoded; + + /* ORCPT */ + if ((test->caps & SMTP_CAPABILITY_DSN) != 0) + test_smtp_rcpt_params_orcpt(&test->params, ¶ms); + /* NOTIFY */ + if ((test->caps & SMTP_CAPABILITY_DSN) != 0) + test_smtp_rcpt_params_notify(&test->params, ¶ms); + /* <extensions> */ + if (test->extensions != NULL) + test_smtp_rcpt_params_extensions(&test->params, ¶ms); + + encoded = t_str_new(256); + smtp_params_rcpt_write(encoded, test->caps, + test->extensions, ¶ms); + + output = (test->output == NULL ? test->input : test->output); + test_out(t_strdup_printf("encode() = \"%s\"", + str_c(encoded)), + strcmp(str_c(encoded), output) == 0); + } + test_end(); + } T_END; +} + +/* Invalid rcpt params tests */ + +struct invalid_rcpt_params_parse_test { + const char *input; + + enum smtp_param_rcpt_parse_flags flags; + enum smtp_capability caps; + const char *const *extensions; +}; + +static const struct invalid_rcpt_params_parse_test +invalid_rcpt_params_parse_tests[] = { + /* DSN */ + { + .input = "ORCPT=rfc822;frop@example.com", + }, + { + .input = "ORCPT=rfc822;<>", + .caps = SMTP_CAPABILITY_DSN + }, + { + .input = "ORCPT=rfc822;", + .caps = SMTP_CAPABILITY_DSN + }, + { + .input = "ORCPT=++", + .caps = SMTP_CAPABILITY_DSN + }, + { + .input = "ORCPT=rfc822;++", + .caps = SMTP_CAPABILITY_DSN + }, + { + .input = "NOTIFY=SUCCESS", + }, + { + .input = "NOTIFY=FROP", + .caps = SMTP_CAPABILITY_DSN + }, + { + .input = "NOTIFY=NEVER,SUCCESS", + .caps = SMTP_CAPABILITY_DSN + } +}; + +unsigned int invalid_rcpt_params_parse_test_count = + N_ELEMENTS(invalid_rcpt_params_parse_tests); + +static void test_smtp_rcpt_params_parse_invalid(void) +{ + unsigned int i; + + for (i = 0; i < invalid_rcpt_params_parse_test_count; i++) T_BEGIN { + const struct invalid_rcpt_params_parse_test *test; + struct smtp_params_rcpt params; + enum smtp_param_parse_error error_code; + const char *error = NULL; + int ret; + + test = &invalid_rcpt_params_parse_tests[i]; + ret = smtp_params_rcpt_parse(pool_datastack_create(), + test->input, test->flags, + test->caps, test->extensions, + ¶ms, &error_code, &error); + + test_begin(t_strdup_printf("smtp rcpt params invalid [%d]", i)); + test_out_reason(t_strdup_printf("parse(\"%s\")", test->input), + ret < 0, error); + test_end(); + } T_END; +} + +int main(void) +{ + static void (*test_functions[])(void) = { + test_smtp_mail_params_parse_valid, + test_smtp_mail_params_parse_invalid, + test_smtp_rcpt_params_parse_valid, + test_smtp_rcpt_params_parse_invalid, + NULL + }; + return test_run(test_functions); +} |