Invalid character checks
[jelmer/ctrlproxy.git] / testsuite / test-parser.c
1 #include <stdio.h>
2 #include <malloc.h>
3 #include <string.h>
4 #include <check.h>
5 #include "line.h"
6 #include "torture.h"
7
8 static const char *malformed[] = {
9         "PRIVMSG :foo :bar",
10         ":bar :bar PRIVMSG foo",
11         "",
12         ": ",
13         " ",
14         NULL
15 };
16
17 START_TEST(parser_malformed)
18         struct line *l;
19         char *raw;
20         int j;
21
22         for (j = 0; malformed[j]; j++) {
23                 l = irc_parse_line(malformed[j]);
24                 if (!l) continue;
25                 raw = irc_line_string(l);
26                 free(raw);
27                 free_line(l);
28         }
29 END_TEST
30
31 #define NUM_RUNS 200
32
33 START_TEST(parser_random)
34         struct line *l;
35         char *raw;
36         char buf[4096];
37         FILE *f = fopen("/dev/urandom", "r");
38         int j;
39
40         fail_if (!f, "Couldn't open /dev/urandom");
41
42         for (j = 0; j < 200; j++) {
43                 fail_if (!fgets(buf, sizeof(buf)-2, f), "error reading random data");
44         
45                 l = irc_parse_line(buf);
46                 if (!l) continue;
47                 raw = irc_line_string(l);
48                 free(raw);
49                 free_line(l);
50         }
51
52         fclose(f);
53 END_TEST
54
55 START_TEST(parser_vargs)
56         struct line *l = irc_parse_line_args( "FOO", "x", "y", NULL);
57
58         fail_if (!l);
59         fail_if (strcmp(l->origin, "FOO") != 0);
60         fail_if (l->argc != 2);
61         fail_if (strcmp(l->args[0], "x") != 0);
62         fail_if (strcmp(l->args[1], "y") != 0);
63 END_TEST
64
65 START_TEST( parser_stringnl)
66         struct line l;
67         char *ret;
68         char *args[] = { "x", "y", "z", NULL };
69         l.origin = "foobar";
70         l.argc = 3;
71         l.args = args;
72         l.has_endcolon = WITHOUT_COLON;
73
74         ret = irc_line_string_nl(&l);
75
76         fail_if (strcmp(ret, ":foobar x y z\r\n") != 0);
77 END_TEST
78
79 START_TEST(parser_get_nick)
80         struct line l;
81         char *nick;
82
83         l.origin = "foobar";
84         nick = line_get_nick(&l);
85         fail_if (strcmp(nick, "foobar") != 0);
86         l.origin = "foobar!~username@userhost";
87         g_free(nick);
88         nick = line_get_nick(&l);
89         fail_if (strcmp(nick, "foobar") != 0);
90         g_free(nick);
91 END_TEST
92
93 START_TEST(parser_recv_line)
94         GIOChannel *ch1, *ch2;
95         struct line *l;
96         GIConv iconv;
97
98         g_io_channel_pair(&ch1, &ch2);
99         g_io_channel_set_flags(ch1, G_IO_FLAG_NONBLOCK, NULL);
100         g_io_channel_set_flags(ch2, G_IO_FLAG_NONBLOCK, NULL);
101
102         iconv = g_iconv_open("UTF-8", "UTF-8");
103
104         g_io_channel_write_chars(ch2, "PRIVMSG :bla\r\nFOO", -1, NULL, NULL);
105         g_io_channel_flush(ch2, NULL);
106
107         fail_unless(irc_recv_line(ch1, iconv, NULL, &l) == G_IO_STATUS_NORMAL);
108         fail_unless(l->argc == 2);
109         fail_unless(!strcmp(l->args[0], "PRIVMSG"));
110         fail_unless(!strcmp(l->args[1], "bla"));
111         fail_unless(irc_recv_line(ch1, iconv, NULL, &l) == G_IO_STATUS_AGAIN);
112
113         g_iconv_close(iconv);
114 END_TEST
115
116 START_TEST(parser_recv_line_invalid)
117         GIOChannel *ch1, *ch2;
118         struct line *l;
119         GIConv iconv;
120
121         g_io_channel_pair(&ch1, &ch2);
122         g_io_channel_set_flags(ch1, G_IO_FLAG_NONBLOCK, NULL);
123         g_io_channel_set_flags(ch2, G_IO_FLAG_NONBLOCK, NULL);
124         g_io_channel_set_encoding(ch1, NULL, NULL);
125         g_io_channel_set_encoding(ch2, NULL, NULL);
126
127         iconv = g_iconv_open("ISO8859-1", "UTF-8");
128
129         g_io_channel_write_chars(ch2, "PRIVMSG :bl\366a\r\n", -1, NULL, NULL);
130         g_io_channel_flush(ch2, NULL);
131
132         fail_unless(irc_recv_line(ch1, iconv, NULL, &l) == G_IO_STATUS_NORMAL);
133         fail_unless(l->argc == 2);
134         fail_unless(!strcmp(l->args[0], "PRIVMSG"));
135         fail_unless(!strcmp(l->args[1], "bla"));
136         fail_unless(irc_recv_line(ch1, iconv, NULL, &l) == G_IO_STATUS_AGAIN);
137
138         g_iconv_close(iconv);
139 END_TEST
140
141
142
143 START_TEST(parser_recv_line_iso8859)
144         GIOChannel *ch1, *ch2;
145         struct line *l;
146         GIConv iconv;
147
148         g_io_channel_pair(&ch1, &ch2);
149         g_io_channel_set_flags(ch1, G_IO_FLAG_NONBLOCK, NULL);
150         g_io_channel_set_flags(ch2, G_IO_FLAG_NONBLOCK, NULL);
151         g_io_channel_set_encoding(ch1, NULL, NULL);
152         g_io_channel_set_encoding(ch2, NULL, NULL);
153
154         iconv = g_iconv_open("UTF-8", "ISO8859-1");
155
156         fail_if(iconv == (GIConv)-1);
157
158         g_io_channel_write_chars(ch2, "PRIVMSG \366 p\r\n", -1, NULL, NULL);
159         g_io_channel_flush(ch2, NULL);
160
161         fail_unless(irc_recv_line(ch1, iconv, NULL, &l) == G_IO_STATUS_NORMAL);
162         fail_unless(l->argc == 3);
163         fail_unless(!strcmp(l->args[0], "PRIVMSG"));
164         fail_unless(!strcmp(l->args[1], "ö"));
165         fail_unless(irc_recv_line(ch1, iconv, NULL, &l) == G_IO_STATUS_AGAIN);
166
167         g_iconv_close(iconv);
168 END_TEST
169
170
171
172 START_TEST(parser_dup)
173         struct line l, *m;
174         char *args[] = { "x", "y", "z", NULL };
175         l.is_private = 1;
176         l.origin = "bla";
177         l.argc = 3;
178         l.args = args;
179         l.has_endcolon = 1;
180
181         m = linedup(&l);
182
183         fail_if (l.is_private != m->is_private);
184         fail_if (strcmp(l.origin, m->origin));
185         fail_if (l.argc != m->argc);
186         fail_if (strcmp(l.args[0], m->args[0]));
187         fail_if (strcmp(l.args[1], m->args[1]));
188         fail_if (strcmp(l.args[2], m->args[2]));
189
190         l.origin = NULL;
191         m = linedup(&l);
192         fail_if (m->origin);
193 END_TEST
194
195 START_TEST(send_args)
196         GIOChannel *ch1, *ch2;
197         char *str;
198
199         g_io_channel_pair(&ch1, &ch2);
200         g_io_channel_set_flags(ch1, G_IO_FLAG_NONBLOCK, NULL);
201         g_io_channel_set_flags(ch2, G_IO_FLAG_NONBLOCK, NULL);
202         g_io_channel_set_encoding(ch1, NULL, NULL);
203         g_io_channel_set_encoding(ch2, NULL, NULL);
204
205         irc_send_args(ch1, (GIConv)-1, NULL, "PRIVMSG", "foo", NULL);
206
207         g_io_channel_read_line(ch2, &str, NULL, NULL, NULL);
208
209         fail_unless(!strcmp(str, "PRIVMSG :foo\r\n"));
210 END_TEST
211
212 START_TEST(send_args_utf8)
213         GIOChannel *ch1, *ch2;
214         char *str;
215         GIConv iconv;
216
217         iconv = g_iconv_open("ISO8859-1", "UTF-8");
218
219         g_io_channel_pair(&ch1, &ch2);
220         g_io_channel_set_flags(ch1, G_IO_FLAG_NONBLOCK, NULL);
221         g_io_channel_set_flags(ch2, G_IO_FLAG_NONBLOCK, NULL);
222         g_io_channel_set_encoding(ch1, NULL, NULL);
223         g_io_channel_set_encoding(ch2, NULL, NULL);
224
225         irc_send_args(ch1, iconv, NULL, "PRIVMSG", "fooö", NULL);
226
227         g_iconv_close(iconv);
228
229         g_io_channel_read_line(ch2, &str, NULL, NULL, NULL);
230
231         fail_unless(!strcmp(str, "PRIVMSG :foo\366\r\n"));
232 END_TEST
233
234 Suite *parser_suite(void)
235 {
236         Suite *s = suite_create("parser");
237         TCase *tcase = tcase_create("core");
238         suite_add_tcase(s, tcase);
239         tcase_add_test(tcase, parser_vargs);
240         tcase_add_test(tcase, parser_stringnl);
241         tcase_add_test(tcase, parser_malformed);
242         tcase_add_test(tcase, parser_random);
243         tcase_add_test(tcase, parser_get_nick);
244         tcase_add_test(tcase, parser_dup);
245         tcase_add_test(tcase, parser_recv_line);
246         tcase_add_test(tcase, parser_recv_line_iso8859);
247         tcase_add_test(tcase, parser_recv_line_invalid);
248         tcase_add_test(tcase, send_args);
249         tcase_add_test(tcase, send_args_utf8);
250         return s;
251 }