static void test_rfc822_parse_comment_nuls(void) { const unsigned char input[] = "(\000a\000\000b\\\000c(\000d)\000)"; const char output[] = "!a!!b\\!c(!d)!"; struct rfc822_parser_context parser; string_t *str = t_str_new(64); test_begin("rfc822 parse comment with NULs"); rfc822_parser_init(&parser, input, sizeof(input)-1, str); test_assert(rfc822_skip_comment(&parser) == 0); /* should be same as input, except the outer () removed */ test_assert(str_len(str) == sizeof(input)-1-2 && memcmp(input+1, str_data(str), str_len(str)) == 0); rfc822_parser_deinit(&parser); str_truncate(str, 0); rfc822_parser_init(&parser, input, sizeof(input)-1, str); parser.nul_replacement_str = "!"; test_assert(rfc822_skip_comment(&parser) == 0); test_assert(strcmp(str_c(str), output) == 0); rfc822_parser_deinit(&parser); test_end(); }
static void test_rfc822_parse_comment(void) { static const struct { const char *input, *output; int ret; } tests[] = { { "(", "", -1 }, { "(()", "", -1 }, { "()", "", 0 }, { "(())", "()", 0 }, { "(foo ( bar ) baz)", "foo ( bar ) baz", 0 }, { "(foo\t\tbar)", "foo\t\tbar", 0 }, { "(foo\\(bar)", "foo(bar", 0 }, { "(foo\\\\bar)", "foo\\bar", 0 }, { "(foo\\\\\\\\)", "foo\\\\", 0 }, { "(foo\\)bar)", "foo)bar", 0 }, { "(foo\"flop\"\"bar)", "foo\"flop\"\"bar", 0 }, { "(foo\n bar)", "foo bar", 0 }, { "(foo\n\t\t bar)", "foo\t\t bar", 0 }, { "(foo\\\n bar)", "foo\\ bar", 0 }, { "(foo\\\r\n bar)", "foo\\ bar", 0 }, }; struct rfc822_parser_context parser, parser2; string_t *str = t_str_new(64); unsigned int i = 0; test_begin("rfc822 parse comment"); for (i = 0; i < N_ELEMENTS(tests); i++) { rfc822_parser_init(&parser, (const void *)tests[i].input, strlen(tests[i].input), str); rfc822_parser_init(&parser2, (const void *)tests[i].input, strlen(tests[i].input), NULL); test_assert_idx(rfc822_skip_comment(&parser) == tests[i].ret, i); test_assert_idx(rfc822_skip_comment(&parser2) == tests[i].ret, i); test_assert_idx(tests[i].ret < 0 || strcmp(tests[i].output, str_c(str)) == 0, i); rfc822_parser_deinit(&parser); rfc822_parser_deinit(&parser2); str_truncate(str, 0); } test_end(); }
int rfc822_skip_lwsp(struct rfc822_parser_context *ctx) { for (; ctx->data != ctx->end;) { if (*ctx->data == ' ' || *ctx->data == '\t' || *ctx->data == '\r' || *ctx->data == '\n') { ctx->data++; continue; } if (*ctx->data != '(') break; if (rfc822_skip_comment(ctx) < 0) return -1; } return ctx->data != ctx->end; }