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