rfc822: Fix bug parsing headers when body begins with linear whitespace
[ccan] / ccan / rfc822 / test / testdata.h
1 #ifndef RFC822_TESTDATA_H
2 #define RFC822_TESTDATA_H
3
4 #include <ccan/talloc/talloc.h>
5 #include <ccan/array_size/array_size.h>
6 #include <ccan/foreach/foreach.h>
7
8 struct testhdr {
9         const char *name, *val;
10 };
11
12 struct aexample {
13         const char *name;
14         struct testhdr *hdrs;
15         size_t nhdrs;
16         const char *body;
17 };
18
19 #define AEXAMPLE(s)                             \
20         struct aexample s = {           \
21                 .name = #s,                     \
22                 .hdrs = s##_hdrs,               \
23                 .nhdrs = ARRAY_SIZE(s##_hdrs),  \
24                 .body = s##_body,               \
25         };
26
27 struct testhdr test_msg_1_hdrs[] = {
28         {"Date", "Tue, 22 Feb 2011 00:15:59 +1100"},
29         {"From", "Mister From <from@example.com>"},
30         {"To", "Mizz To <to@example.org>"},
31         {"Subject", "Some subject"},
32         {"Message-ID", "<20110221131559.GA28327@example>"},
33         {"MIME-Version", "1.0"},
34         {"Content-Type", "text/plain; charset=us-ascii"},
35         {"Content-Disposition", "inline"},
36 };
37 const char test_msg_1_body[] = "Test message\n";
38 AEXAMPLE(test_msg_1);
39
40 #define test_msg_empty_body_hdrs test_msg_1_hdrs
41 const char test_msg_empty_body_body[] = "";
42 AEXAMPLE(test_msg_empty_body);
43
44 #define test_msg_nlnl_lf_hdrs test_msg_1_hdrs
45 const char test_msg_nlnl_lf_body[] = "Message containing \n\n inside body\n";
46 AEXAMPLE(test_msg_nlnl_lf);
47
48 #define test_msg_nlnl_crlf_hdrs test_msg_1_hdrs
49 const char test_msg_nlnl_crlf_body[] = "Message containing \r\n\r\n inside body\r\n";
50 AEXAMPLE(test_msg_nlnl_crlf);
51
52 #define test_msg_nlnl_mixed_hdrs test_msg_1_hdrs
53 const char test_msg_nlnl_mixed_body[] = "Message containing both \n\n and \r\n\r\n inside body\n\r\n";
54 AEXAMPLE(test_msg_nlnl_mixed);
55
56 #define test_msg_space_body_hdrs test_msg_1_hdrs
57 const char test_msg_space_body_body[] = " Message with LWS at start of body\n";
58 AEXAMPLE(test_msg_space_body);
59
60 #define for_each_aexample(_e)                                \
61         foreach_ptr((_e), &test_msg_1, &test_msg_empty_body, \
62                     &test_msg_nlnl_lf, &test_msg_nlnl_crlf, \
63                     &test_msg_nlnl_mixed, \
64                     &test_msg_space_body)
65
66 #define for_each_aexample_buf(_e, _buf, _len)   \
67         for_each_aexample((_e))                 \
68         if (((_buf) = assemble_msg((_e), &(_len))) != NULL)
69
70 static inline int num_aexamples(void)
71 {
72         const struct aexample *e;
73         int n = 0;
74
75         for_each_aexample(e)
76                 n++;
77
78         return n;
79 }
80
81 static inline int num_aexample_hdrs(void)
82 {
83         const struct aexample *e;
84         int n = 0;
85
86         for_each_aexample(e)
87                 n += e->nhdrs;
88
89         return n;
90 }
91
92 static inline const char *assemble_msg(const struct aexample *e,
93                                        size_t *len, int crlf)
94 {
95         const char *nl = crlf ? "\r\n" : "\n";
96         int nln = crlf ? 2 : 1;
97         char *msg, *amsg;
98         size_t n = 0;
99         int i;
100
101         msg = talloc_strdup(NULL, "");
102         if (!msg)
103                 return NULL;
104
105         for (i = 0; i < e->nhdrs; i++) {
106                 amsg = talloc_asprintf_append(msg, "%s:%s%s", e->hdrs[i].name,
107                                               e->hdrs[i].val, nl);
108                 if (!amsg) {
109                         talloc_free(msg);
110                         return NULL;
111                 }
112                 msg = amsg;
113                 n += strlen(e->hdrs[i].name) + strlen(e->hdrs[i].val) + 1 + nln;
114         }
115         amsg = talloc_asprintf_append(msg, "%s%s", nl, e->body);
116         if (!amsg) {
117                 talloc_free(msg);
118                 return NULL;
119         }
120         msg = amsg;
121         n += strlen(e->body) + nln;
122         *len = n;
123         return msg;
124 }
125
126 #define NLT(crlf)       ((crlf) ? "CRLF" : "LF")
127
128 #endif /* RFC822_TESTDATA_H */