]> git.ozlabs.org Git - ccan/blob - ccan/rfc822/test/run-hdr-and-body.c
rfc822: Fix bug parsing headers when body begins with linear whitespace
[ccan] / ccan / rfc822 / test / run-hdr-and-body.c
1 #include <ccan/foreach/foreach.h>
2 #include <ccan/failtest/failtest_override.h>
3 #include <ccan/failtest/failtest.h>
4 #include <ccan/tap/tap.h>
5 #include <stdlib.h>
6 #include <string.h>
7
8 #define CCAN_RFC822_DEBUG
9
10 #include <ccan/rfc822/rfc822.h>
11
12 #include <ccan/rfc822/rfc822.c>
13
14 #include "testdata.h"
15 #include "helper.h"
16
17 #define CHECK_HEADERS(_e, _msg, _h, _n, _crlf)  \
18         do { \
19                 int _i; \
20                 for (_i = 0; _i < (_e)->nhdrs; _i++) {  \
21                         (_h) = rfc822_next_header((_msg), (_h)); \
22                         ok((_h), "header %d exists %s", _i, (_n)); \
23                         if (!(_h)) \
24                                 break; \
25                         check_header((_msg), (_h), (_e)->hdrs[_i].name, \
26                                      (_e)->hdrs[_i].val, crlf); \
27                 } \
28         } while (0)
29
30 static void check_header(struct rfc822_msg *msg,
31                          struct rfc822_header *h,
32                          const char *name, const char *val,
33                          int crlf)
34 {
35         struct bytestring hname, hvalue, hfull;
36         size_t namelen = strlen(name);
37         size_t valuelen = strlen(val);
38         size_t nln = crlf ? 2 : 1;
39         size_t fulllen = namelen + valuelen + 1 + nln;
40
41         ok(rfc822_header_errors(msg, h) == 0, "Header valid");
42         allocation_failure_check();
43
44         hname = rfc822_header_raw_name(msg, h);
45         allocation_failure_check();
46
47         ok(hname.ptr && bytestring_eq(hname, bytestring_from_string(name)),
48            "Header name \"%.*s\"", hname.len, hname.ptr);
49
50         hvalue = rfc822_header_raw_value(msg, h);
51         allocation_failure_check();
52
53         ok(hvalue.ptr && ((valuelen + nln) == hvalue.len)
54            && (memcmp(val, hvalue.ptr, valuelen) == 0)
55            && (!crlf || (hvalue.ptr[hvalue.len - 2] == '\r'))
56            && (hvalue.ptr[hvalue.len - 1] == '\n'),
57            "Header value");
58
59         hfull = rfc822_header_raw_content(msg, h);
60         allocation_failure_check();
61
62         ok(hfull.ptr && (fulllen == hfull.len)
63            && (memcmp(name, hfull.ptr, namelen) == 0)
64            && (hfull.ptr[namelen] == ':')
65            && (memcmp(val, hfull.ptr + namelen + 1, valuelen) == 0)
66            && (!crlf || (hfull.ptr[fulllen-2] == '\r'))
67            && (hfull.ptr[fulllen-1] == '\n'),
68            "Full header");
69 }
70
71 static void test_bodyhdr(const struct aexample *e, const char *buf, size_t len,
72                          const char *exname, int crlf)
73 {
74         struct rfc822_msg *msg;
75         struct rfc822_header *h = NULL;
76         struct bytestring body;
77
78         msg = rfc822_start(NULL, buf, len);
79         allocation_failure_check();
80
81         ok(msg, "opened %s", exname);
82
83         body = rfc822_body(msg);
84         allocation_failure_check();
85         ok(bytestring_eq(body, bytestring_from_string(e->body)),
86            "body content %s", exname);
87
88         CHECK_HEADERS(e, msg, h, exname, crlf);
89         h = rfc822_next_header(msg, h);
90         allocation_failure_check();
91         ok(!h, "Too many headers for %s", exname);
92
93         rfc822_free(msg);
94         allocation_failure_check();
95 }
96
97 static void test_hdrbody(const struct aexample *e, const char *buf, size_t len,
98                          const char *exname, int crlf)
99 {
100         struct rfc822_msg *msg;
101         struct rfc822_header *h = NULL;
102         struct bytestring body;
103
104         msg = rfc822_start(NULL, buf, len);
105         allocation_failure_check();
106         ok(msg, "opened %s", exname);
107
108         CHECK_HEADERS(e, msg, h, exname, crlf);
109         h = rfc822_next_header(msg, h);
110         allocation_failure_check();
111         ok(!h, "Too many headers for %s", exname);
112
113         body = rfc822_body(msg);
114         allocation_failure_check();
115         ok(bytestring_eq(body, bytestring_from_string(e->body)),
116            "body content %s", exname);
117
118         rfc822_free(msg);
119         allocation_failure_check();
120 }
121
122 static void test_hdrhdr(const struct aexample *e, const char *buf, size_t len,
123                         const char *exname, int crlf)
124 {
125         struct rfc822_msg *msg;
126         struct rfc822_header *h;
127
128         msg = rfc822_start(NULL, buf, len);
129         allocation_failure_check();
130         ok(msg, "opened %s", exname);
131
132         h = NULL;
133         CHECK_HEADERS(e, msg, h, exname, crlf);
134
135         h = rfc822_next_header(msg, h);
136         allocation_failure_check();
137         ok(!h, "Too many headers for %s", exname);
138
139         /* And again, this time it should be cached */
140         h = NULL;
141         CHECK_HEADERS(e, msg, h, exname, crlf);
142
143         h = rfc822_next_header(msg, h);
144         allocation_failure_check();
145         ok(!h, "Too many headers for %s", exname);
146
147         rfc822_free(msg);
148         allocation_failure_check();
149 }
150
151 int main(int argc, char *argv[])
152 {
153         struct aexample *e;
154
155         /* This is how many tests you plan to run */
156         plan_tests(20*num_aexamples() + 40*num_aexample_hdrs());
157
158         failtest_setup(argc, argv);
159
160         for_each_aexample(e) {
161                 int crlf;
162
163                 foreach_int(crlf, 0, 1) {
164                         const char *buf;
165                         size_t len;
166                         char exname[256];
167
168                         sprintf(exname, "%s[%s]", e->name, NLT(crlf));
169
170                         buf = assemble_msg(e, &len, crlf);
171                         ok((buf), "assembled %s", exname);
172                         if (!buf)
173                                 continue;
174
175                         test_bodyhdr(e, buf, len, exname, crlf);
176                         test_hdrbody(e, buf, len, exname, crlf);
177                         test_hdrhdr(e, buf, len, exname, crlf);
178
179                         talloc_free(buf);
180                 }
181         }
182
183         /* This exits depending on whether all tests passed */
184         failtest_exit(exit_status());
185 }