This source file includes following definitions.
- _evbuffer_validate
- evbuffer_get_waste
- test_evbuffer
- no_cleanup
- test_evbuffer_remove_buffer_with_empty
- test_evbuffer_reserve2
- test_evbuffer_reserve_many
- test_evbuffer_expand
- reference_cb
- test_evbuffer_reference
- test_evbuffer_add_file
- failing_malloc
- test_evbuffer_readln
- test_evbuffer_search_eol
- test_evbuffer_iterative
- test_evbuffer_find
- test_evbuffer_ptr_set
- test_evbuffer_search
- log_change_callback
- self_draining_callback
- test_evbuffer_callbacks
- ref_done_cb
- test_evbuffer_add_reference
- test_evbuffer_prepend
- test_evbuffer_peek
- test_evbuffer_freeze
- setup_passthrough
- cleanup_passthrough
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 #ifdef WIN32
29 #include <winsock2.h>
30 #include <windows.h>
31 #endif
32
33 #include "event2/event-config.h"
34
35 #include <sys/types.h>
36 #include <sys/stat.h>
37 #ifdef _EVENT_HAVE_SYS_TIME_H
38 #include <sys/time.h>
39 #endif
40 #include <sys/queue.h>
41 #ifndef WIN32
42 #include <sys/socket.h>
43 #include <sys/wait.h>
44 #include <signal.h>
45 #include <unistd.h>
46 #include <netdb.h>
47 #endif
48 #include <stdlib.h>
49 #include <stdio.h>
50 #include <string.h>
51 #include <errno.h>
52 #include <assert.h>
53
54 #include "event2/event.h"
55 #include "event2/buffer.h"
56 #include "event2/buffer_compat.h"
57 #include "event2/util.h"
58
59 #include "evbuffer-internal.h"
60 #include "log-internal.h"
61
62 #include "regress.h"
63
64
65
66 static int
67 _evbuffer_validate(struct evbuffer *buf)
68 {
69 struct evbuffer_chain *chain;
70 size_t sum = 0;
71 int found_last_with_datap = 0;
72
73 if (buf->first == NULL) {
74 tt_assert(buf->last == NULL);
75 tt_assert(buf->total_len == 0);
76 }
77
78 chain = buf->first;
79
80 tt_assert(buf->last_with_datap);
81 if (buf->last_with_datap == &buf->first)
82 found_last_with_datap = 1;
83
84 while (chain != NULL) {
85 if (&chain->next == buf->last_with_datap)
86 found_last_with_datap = 1;
87 sum += chain->off;
88 if (chain->next == NULL) {
89 tt_assert(buf->last == chain);
90 }
91 tt_assert(chain->buffer_len >= chain->misalign + chain->off);
92 chain = chain->next;
93 }
94
95 if (buf->first)
96 tt_assert(*buf->last_with_datap);
97
98 if (*buf->last_with_datap) {
99 chain = *buf->last_with_datap;
100 if (chain->off == 0 || buf->total_len == 0) {
101 tt_assert(chain->off == 0)
102 tt_assert(chain == buf->first);
103 tt_assert(buf->total_len == 0);
104 }
105 chain = chain->next;
106 while (chain != NULL) {
107 tt_assert(chain->off == 0);
108 chain = chain->next;
109 }
110 } else {
111 tt_assert(buf->last_with_datap == &buf->first);
112 }
113 tt_assert(found_last_with_datap);
114
115 tt_assert(sum == buf->total_len);
116 return 1;
117 end:
118 return 0;
119 }
120
121 static void
122 evbuffer_get_waste(struct evbuffer *buf, size_t *allocatedp, size_t *wastedp, size_t *usedp)
123 {
124 struct evbuffer_chain *chain;
125 size_t a, w, u;
126 int n = 0;
127 u = a = w = 0;
128
129 chain = buf->first;
130
131 while (chain && chain->off==0) {
132 ++n;
133 a += chain->buffer_len;
134 chain = chain->next;
135 }
136
137 if (chain) {
138 ++n;
139 a += chain->buffer_len;
140 u += chain->off;
141 if (chain->next && chain->next->off)
142 w += (size_t)(chain->buffer_len - (chain->misalign + chain->off));
143 chain = chain->next;
144 }
145
146 while (chain && chain->off) {
147 ++n;
148 a += chain->buffer_len;
149 w += (size_t)chain->misalign;
150 u += chain->off;
151 if (chain->next && chain->next->off)
152 w += (size_t) (chain->buffer_len - (chain->misalign + chain->off));
153 chain = chain->next;
154 }
155
156 while (chain) {
157 ++n;
158 a += chain->buffer_len;
159 }
160 *allocatedp = a;
161 *wastedp = w;
162 *usedp = u;
163 }
164
165 #define evbuffer_validate(buf) \
166 TT_STMT_BEGIN if (!_evbuffer_validate(buf)) TT_DIE(("Buffer format invalid")); TT_STMT_END
167
168 static void
169 test_evbuffer(void *ptr)
170 {
171 static char buffer[512], *tmp;
172 struct evbuffer *evb = evbuffer_new();
173 struct evbuffer *evb_two = evbuffer_new();
174 size_t sz_tmp;
175 int i;
176
177 evbuffer_validate(evb);
178 evbuffer_add_printf(evb, "%s/%d", "hello", 1);
179 evbuffer_validate(evb);
180
181 tt_assert(evbuffer_get_length(evb) == 7);
182 tt_assert(!memcmp((char*)EVBUFFER_DATA(evb), "hello/1", 1));
183
184 evbuffer_add_buffer(evb, evb_two);
185 evbuffer_validate(evb);
186
187 evbuffer_drain(evb, strlen("hello/"));
188 evbuffer_validate(evb);
189 tt_assert(evbuffer_get_length(evb) == 1);
190 tt_assert(!memcmp((char*)EVBUFFER_DATA(evb), "1", 1));
191
192 evbuffer_add_printf(evb_two, "%s", "/hello");
193 evbuffer_validate(evb);
194 evbuffer_add_buffer(evb, evb_two);
195 evbuffer_validate(evb);
196
197 tt_assert(evbuffer_get_length(evb_two) == 0);
198 tt_assert(evbuffer_get_length(evb) == 7);
199 tt_assert(!memcmp((char*)EVBUFFER_DATA(evb), "1/hello", 7) != 0);
200
201 memset(buffer, 0, sizeof(buffer));
202 evbuffer_add(evb, buffer, sizeof(buffer));
203 evbuffer_validate(evb);
204 tt_assert(evbuffer_get_length(evb) == 7 + 512);
205
206 tmp = (char *)evbuffer_pullup(evb, 7 + 512);
207 tt_assert(tmp);
208 tt_assert(!strncmp(tmp, "1/hello", 7));
209 tt_assert(!memcmp(tmp + 7, buffer, sizeof(buffer)));
210 evbuffer_validate(evb);
211
212 evbuffer_prepend(evb, "something", 9);
213 evbuffer_validate(evb);
214 evbuffer_prepend(evb, "else", 4);
215 evbuffer_validate(evb);
216
217 tmp = (char *)evbuffer_pullup(evb, 4 + 9 + 7);
218 tt_assert(!strncmp(tmp, "elsesomething1/hello", 4 + 9 + 7));
219 evbuffer_validate(evb);
220
221 evbuffer_drain(evb, -1);
222 evbuffer_validate(evb);
223 evbuffer_drain(evb_two, -1);
224 evbuffer_validate(evb);
225
226 for (i = 0; i < 3; ++i) {
227 evbuffer_add(evb_two, buffer, sizeof(buffer));
228 evbuffer_validate(evb_two);
229 evbuffer_add_buffer(evb, evb_two);
230 evbuffer_validate(evb);
231 evbuffer_validate(evb_two);
232 }
233
234 tt_assert(evbuffer_get_length(evb_two) == 0);
235 tt_assert(evbuffer_get_length(evb) == i * sizeof(buffer));
236
237
238 sz_tmp = (size_t)(sizeof(buffer)*2.5);
239 evbuffer_remove_buffer(evb, evb_two, sz_tmp);
240 tt_assert(evbuffer_get_length(evb_two) == sz_tmp);
241 tt_assert(evbuffer_get_length(evb) == sizeof(buffer) / 2);
242 evbuffer_validate(evb);
243
244 if (memcmp(evbuffer_pullup(
245 evb, -1), buffer, sizeof(buffer) / 2) != 0 ||
246 memcmp(evbuffer_pullup(
247 evb_two, -1), buffer, sizeof(buffer)) != 0)
248 tt_abort_msg("Pullup did not preserve content");
249
250 evbuffer_validate(evb);
251
252
253
254 {
255 struct evbuffer_iovec v[1];
256 char *buf;
257 int i, j, r;
258
259 for (i = 0; i < 3; ++i) {
260 r = evbuffer_reserve_space(evb, 10000, v, 1);
261 tt_int_op(r, ==, 1);
262 tt_assert(v[0].iov_len >= 10000);
263 tt_assert(v[0].iov_base != NULL);
264
265 evbuffer_validate(evb);
266 buf = v[0].iov_base;
267 for (j = 0; j < 10000; ++j) {
268 buf[j] = j;
269 }
270 evbuffer_validate(evb);
271
272 tt_int_op(evbuffer_commit_space(evb, v, 1), ==, 0);
273 evbuffer_validate(evb);
274
275 tt_assert(evbuffer_get_length(evb) >= 10000);
276
277 evbuffer_drain(evb, j * 5000);
278 evbuffer_validate(evb);
279 }
280 }
281
282 end:
283 evbuffer_free(evb);
284 evbuffer_free(evb_two);
285 }
286
287 static void
288 no_cleanup(const void *data, size_t datalen, void *extra)
289 {
290 }
291
292 static void
293 test_evbuffer_remove_buffer_with_empty(void *ptr)
294 {
295 struct evbuffer *src = evbuffer_new();
296 struct evbuffer *dst = evbuffer_new();
297 char buf[2];
298
299 evbuffer_validate(src);
300 evbuffer_validate(dst);
301
302
303
304 evbuffer_add_reference(src, buf, sizeof(buf), no_cleanup, NULL);
305 evbuffer_add_reference(src, buf, sizeof(buf), no_cleanup, NULL);
306
307 evbuffer_add(dst, buf, sizeof(buf));
308 evbuffer_add_reference(dst, buf, 0, no_cleanup, NULL);
309
310 evbuffer_validate(src);
311 evbuffer_validate(dst);
312
313
314 evbuffer_remove_buffer(src, dst, 3);
315
316 evbuffer_validate(src);
317 evbuffer_validate(dst);
318
319 end:
320 evbuffer_free(src);
321 evbuffer_free(dst);
322 }
323
324 static void
325 test_evbuffer_reserve2(void *ptr)
326 {
327
328 struct evbuffer *buf = evbuffer_new();
329 int n, i;
330 struct evbuffer_iovec v[2];
331 size_t remaining;
332 char *cp, *cp2;
333
334
335 n = evbuffer_reserve_space(buf, 1024, v, 2);
336 tt_int_op(n, ==, 1);
337 tt_int_op(evbuffer_get_length(buf), ==, 0);
338 tt_assert(v[0].iov_base != NULL);
339 tt_int_op(v[0].iov_len, >=, 1024);
340 memset(v[0].iov_base, 'X', 512);
341 cp = v[0].iov_base;
342 remaining = v[0].iov_len - 512;
343 v[0].iov_len = 512;
344 evbuffer_validate(buf);
345 tt_int_op(0, ==, evbuffer_commit_space(buf, v, 1));
346 tt_int_op(evbuffer_get_length(buf), ==, 512);
347 evbuffer_validate(buf);
348
349
350
351 n = evbuffer_reserve_space(buf, 32, v, 2);
352 tt_int_op(n, ==, 1);
353 tt_assert(cp + 512 == v[0].iov_base);
354 tt_int_op(remaining, ==, v[0].iov_len);
355 memset(v[0].iov_base, 'Y', 8);
356 v[0].iov_len = 8;
357 tt_int_op(0, ==, evbuffer_commit_space(buf, v, 1));
358 tt_int_op(evbuffer_get_length(buf), ==, 520);
359 remaining -= 8;
360 evbuffer_validate(buf);
361
362
363
364 n = evbuffer_reserve_space(buf, remaining+64, v, 2);
365 tt_int_op(n, ==, 2);
366 tt_assert(cp + 520 == v[0].iov_base);
367 tt_int_op(remaining, ==, v[0].iov_len);
368 tt_assert(v[1].iov_base);
369 tt_assert(v[1].iov_len >= 64);
370 cp2 = v[1].iov_base;
371 memset(v[0].iov_base, 'Z', 1);
372 v[0].iov_len = 1;
373 tt_int_op(0, ==, evbuffer_commit_space(buf, v, 1));
374 tt_int_op(evbuffer_get_length(buf), ==, 521);
375 remaining -= 1;
376 evbuffer_validate(buf);
377
378
379
380 n = evbuffer_reserve_space(buf, remaining+64, v, 2);
381 evbuffer_validate(buf);
382 tt_int_op(n, ==, 2);
383 tt_assert(cp + 521 == v[0].iov_base);
384 tt_int_op(remaining, ==, v[0].iov_len);
385 tt_assert(v[1].iov_base == cp2);
386 tt_assert(v[1].iov_len >= 64);
387 memset(v[0].iov_base, 'W', 400);
388 v[0].iov_len = 400;
389 memset(v[1].iov_base, 'x', 60);
390 v[1].iov_len = 60;
391 tt_int_op(0, ==, evbuffer_commit_space(buf, v, 2));
392 tt_int_op(evbuffer_get_length(buf), ==, 981);
393 evbuffer_validate(buf);
394
395
396 memset(v,0,sizeof(v));
397 n = evbuffer_peek(buf, -1, NULL, v, 2);
398 tt_int_op(n, ==, 2);
399 tt_int_op(v[0].iov_len, ==, 921);
400 tt_int_op(v[1].iov_len, ==, 60);
401
402 cp = v[0].iov_base;
403 for (i=0; i<512; ++i)
404 tt_int_op(cp[i], ==, 'X');
405 for (i=512; i<520; ++i)
406 tt_int_op(cp[i], ==, 'Y');
407 for (i=520; i<521; ++i)
408 tt_int_op(cp[i], ==, 'Z');
409 for (i=521; i<921; ++i)
410 tt_int_op(cp[i], ==, 'W');
411
412 cp = v[1].iov_base;
413 for (i=0; i<60; ++i)
414 tt_int_op(cp[i], ==, 'x');
415
416 end:
417 evbuffer_free(buf);
418 }
419
420 static void
421 test_evbuffer_reserve_many(void *ptr)
422 {
423
424
425 struct evbuffer *buf = evbuffer_new();
426 struct evbuffer_iovec v[8];
427 int n;
428 size_t sz;
429 int add_data = ptr && !strcmp(ptr, "add");
430 int fill_first = ptr && !strcmp(ptr, "fill");
431 char *cp1, *cp2;
432
433
434 n = evbuffer_reserve_space(buf, 128, v, 2);
435 evbuffer_validate(buf);
436 tt_int_op(n, ==, 1);
437 tt_assert(v[0].iov_len >= 128);
438 sz = v[0].iov_len;
439 cp1 = v[0].iov_base;
440 if (add_data) {
441 *(char*)v[0].iov_base = 'X';
442 v[0].iov_len = 1;
443 n = evbuffer_commit_space(buf, v, 1);
444 tt_int_op(n, ==, 0);
445 } else if (fill_first) {
446 memset(v[0].iov_base, 'X', v[0].iov_len);
447 n = evbuffer_commit_space(buf, v, 1);
448 tt_int_op(n, ==, 0);
449 n = evbuffer_reserve_space(buf, 128, v, 2);
450 tt_int_op(n, ==, 1);
451 sz = v[0].iov_len;
452 tt_assert(v[0].iov_base != cp1);
453 cp1 = v[0].iov_base;
454 }
455
456
457 n = evbuffer_reserve_space(buf, sz+128, v, 2);
458 evbuffer_validate(buf);
459 tt_int_op(n, ==, 2);
460 sz = v[0].iov_len + v[1].iov_len;
461 tt_int_op(sz, >=, v[0].iov_len+128);
462 if (add_data) {
463 tt_assert(v[0].iov_base == cp1 + 1);
464 } else {
465 tt_assert(v[0].iov_base == cp1);
466 }
467 cp1 = v[0].iov_base;
468 cp2 = v[1].iov_base;
469
470
471 n = evbuffer_reserve_space(buf, sz+128, v, 3);
472 evbuffer_validate(buf);
473 tt_int_op(n, ==, 3);
474 tt_assert(cp1 == v[0].iov_base);
475 tt_assert(cp2 == v[1].iov_base);
476 sz = v[0].iov_len + v[1].iov_len + v[2].iov_len;
477
478
479
480 n = evbuffer_reserve_space(buf, sz+128, v, 2);
481 evbuffer_validate(buf);
482 if (add_data) {
483 tt_int_op(n, ==, 2);
484 tt_assert(cp1 == v[0].iov_base);
485 } else {
486 tt_int_op(n, ==, 1);
487 }
488
489 end:
490 evbuffer_free(buf);
491 }
492
493 static void
494 test_evbuffer_expand(void *ptr)
495 {
496 char data[4096];
497 struct evbuffer *buf;
498 size_t a,w,u;
499 void *buffer;
500
501 memset(data, 'X', sizeof(data));
502
503
504 buf = evbuffer_new();
505 tt_int_op(evbuffer_expand(buf, 20000), ==, 0);
506 evbuffer_validate(buf);
507 a=w=u=0;
508 evbuffer_get_waste(buf, &a,&w,&u);
509 tt_assert(w == 0);
510 tt_assert(u == 0);
511 tt_assert(a >= 20000);
512 tt_assert(buf->first);
513 tt_assert(buf->first == buf->last);
514 tt_assert(buf->first->off == 0);
515 tt_assert(buf->first->buffer_len >= 20000);
516
517
518
519 buffer = buf->first->buffer;
520 evbuffer_add(buf, data, 1024);
521 tt_int_op(evbuffer_expand(buf, 1024), ==, 0);
522 tt_assert(buf->first->buffer == buffer);
523 evbuffer_validate(buf);
524 evbuffer_free(buf);
525
526
527
528 buf = evbuffer_new();
529 evbuffer_add(buf, data, 400);
530 {
531 int n = (int)(buf->first->buffer_len - buf->first->off - 1);
532 tt_assert(n < (int)sizeof(data));
533 evbuffer_add(buf, data, n);
534 }
535 tt_assert(buf->first == buf->last);
536 tt_assert(buf->first->off == buf->first->buffer_len - 1);
537 evbuffer_drain(buf, buf->first->off - 1);
538 tt_assert(1 == evbuffer_get_length(buf));
539 tt_assert(buf->first->misalign > 0);
540 tt_assert(buf->first->off == 1);
541 buffer = buf->first->buffer;
542 tt_assert(evbuffer_expand(buf, 40) == 0);
543 tt_assert(buf->first == buf->last);
544 tt_assert(buf->first->off == 1);
545 tt_assert(buf->first->buffer == buffer);
546 tt_assert(buf->first->misalign == 0);
547 evbuffer_validate(buf);
548 evbuffer_free(buf);
549
550
551 buf = evbuffer_new();
552
553 evbuffer_add(buf, data, sizeof(data));
554 evbuffer_add(buf, data, sizeof(data));
555 evbuffer_add(buf, data, sizeof(data));
556
557 evbuffer_validate(buf);
558 evbuffer_expand(buf, 1024);
559 evbuffer_validate(buf);
560 evbuffer_pullup(buf, -1);
561 evbuffer_validate(buf);
562
563 end:
564 evbuffer_free(buf);
565 }
566
567
568 static int reference_cb_called;
569 static void
570 reference_cb(const void *data, size_t len, void *extra)
571 {
572 tt_str_op(data, ==, "this is what we add as read-only memory.");
573 tt_int_op(len, ==, strlen(data));
574 tt_want(extra == (void *)0xdeadaffe);
575 ++reference_cb_called;
576 end:
577 ;
578 }
579
580 static void
581 test_evbuffer_reference(void *ptr)
582 {
583 struct evbuffer *src = evbuffer_new();
584 struct evbuffer *dst = evbuffer_new();
585 struct evbuffer_iovec v[1];
586 const char *data = "this is what we add as read-only memory.";
587 reference_cb_called = 0;
588
589 tt_assert(evbuffer_add_reference(src, data, strlen(data),
590 reference_cb, (void *)0xdeadaffe) != -1);
591
592 evbuffer_reserve_space(dst, strlen(data), v, 1);
593 tt_assert(evbuffer_remove(src, v[0].iov_base, 10) != -1);
594
595 evbuffer_validate(src);
596 evbuffer_validate(dst);
597
598
599 evbuffer_prepend(src, "aaaaa", 5);
600 evbuffer_validate(src);
601 evbuffer_drain(src, 5);
602
603 tt_assert(evbuffer_remove(src, ((char*)(v[0].iov_base)) + 10,
604 strlen(data) - 10) != -1);
605
606 v[0].iov_len = strlen(data);
607
608 evbuffer_commit_space(dst, v, 1);
609 evbuffer_validate(src);
610 evbuffer_validate(dst);
611
612 tt_int_op(reference_cb_called, ==, 1);
613
614 tt_assert(!memcmp(evbuffer_pullup(dst, strlen(data)),
615 data, strlen(data)));
616 evbuffer_validate(dst);
617
618 end:
619 evbuffer_free(dst);
620 evbuffer_free(src);
621 }
622
623 int _evbuffer_testing_use_sendfile(void);
624 int _evbuffer_testing_use_mmap(void);
625 int _evbuffer_testing_use_linear_file_access(void);
626
627 static void
628 test_evbuffer_add_file(void *ptr)
629 {
630 const char *impl = ptr;
631 struct evbuffer *src = evbuffer_new();
632 const char *data = "this is what we add as file system data.";
633 size_t datalen;
634 const char *compare;
635 int fd = -1;
636 evutil_socket_t pair[2] = {-1, -1};
637 int r=0, n_written=0;
638
639
640
641 tt_assert(impl);
642 if (!strcmp(impl, "sendfile")) {
643 if (!_evbuffer_testing_use_sendfile())
644 tt_skip();
645 TT_BLATHER(("Using sendfile-based implementaion"));
646 } else if (!strcmp(impl, "mmap")) {
647 if (!_evbuffer_testing_use_mmap())
648 tt_skip();
649 TT_BLATHER(("Using mmap-based implementaion"));
650 } else if (!strcmp(impl, "linear")) {
651 if (!_evbuffer_testing_use_linear_file_access())
652 tt_skip();
653 TT_BLATHER(("Using read-based implementaion"));
654 } else {
655 TT_DIE(("Didn't recognize the implementation"));
656 }
657
658
659 evbuffer_set_flags(src, EVBUFFER_FLAG_DRAINS_TO_FD);
660
661 #if defined(_EVENT_HAVE_SENDFILE) && defined(__sun__) && defined(__svr4__)
662
663
664 if (evutil_ersatz_socketpair(AF_INET, SOCK_STREAM, 0, pair) == -1)
665 tt_abort_msg("ersatz_socketpair failed");
666 #else
667 if (evutil_socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1)
668 tt_abort_msg("socketpair failed");
669 #endif
670
671 datalen = strlen(data);
672 fd = regress_make_tmpfile(data, datalen);
673
674 tt_assert(fd != -1);
675
676 tt_assert(evbuffer_add_file(src, fd, 0, datalen) != -1);
677
678 evbuffer_validate(src);
679
680 while (evbuffer_get_length(src) &&
681 (r = evbuffer_write(src, pair[0])) > 0) {
682 evbuffer_validate(src);
683 n_written += r;
684 }
685 tt_int_op(r, !=, -1);
686 tt_int_op(n_written, ==, datalen);
687
688 evbuffer_validate(src);
689 tt_int_op(evbuffer_read(src, pair[1], (int)strlen(data)), ==, datalen);
690 evbuffer_validate(src);
691 compare = (char *)evbuffer_pullup(src, datalen);
692 tt_assert(compare != NULL);
693 if (memcmp(compare, data, datalen))
694 tt_abort_msg("Data from add_file differs.");
695
696 evbuffer_validate(src);
697 end:
698 if (pair[0] >= 0)
699 evutil_closesocket(pair[0]);
700 if (pair[1] >= 0)
701 evutil_closesocket(pair[1]);
702 evbuffer_free(src);
703 }
704
705 #ifndef _EVENT_DISABLE_MM_REPLACEMENT
706 static void *
707 failing_malloc(size_t how_much)
708 {
709 errno = ENOMEM;
710 return NULL;
711 }
712 #endif
713
714 static void
715 test_evbuffer_readln(void *ptr)
716 {
717 struct evbuffer *evb = evbuffer_new();
718 struct evbuffer *evb_tmp = evbuffer_new();
719 const char *s;
720 char *cp = NULL;
721 size_t sz;
722
723 #define tt_line_eq(content) \
724 TT_STMT_BEGIN \
725 if (!cp || sz != strlen(content) || strcmp(cp, content)) { \
726 TT_DIE(("Wanted %s; got %s [%d]", content, cp, (int)sz)); \
727 } \
728 TT_STMT_END
729
730
731 s = "complex silly newline\r\n\n\r\n\n\rmore\0\n";
732 evbuffer_add(evb, s, strlen(s)+2);
733 evbuffer_validate(evb);
734 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_ANY);
735 tt_line_eq("complex silly newline");
736 free(cp);
737 evbuffer_validate(evb);
738 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_ANY);
739 if (!cp || sz != 5 || memcmp(cp, "more\0\0", 6))
740 tt_abort_msg("Not as expected");
741 tt_uint_op(evbuffer_get_length(evb), ==, 0);
742 evbuffer_validate(evb);
743 s = "\nno newline";
744 evbuffer_add(evb, s, strlen(s));
745 free(cp);
746 evbuffer_validate(evb);
747 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_ANY);
748 tt_line_eq("");
749 free(cp);
750 evbuffer_validate(evb);
751 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_ANY);
752 tt_assert(!cp);
753 evbuffer_validate(evb);
754 evbuffer_drain(evb, evbuffer_get_length(evb));
755 tt_assert(evbuffer_get_length(evb) == 0);
756 evbuffer_validate(evb);
757
758
759 s = "Line with\rin the middle\nLine with good crlf\r\n\nfinal\n";
760 evbuffer_add(evb, s, strlen(s));
761 evbuffer_validate(evb);
762 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF);
763 tt_line_eq("Line with\rin the middle");
764 free(cp);
765 evbuffer_validate(evb);
766
767 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF);
768 tt_line_eq("Line with good crlf");
769 free(cp);
770 evbuffer_validate(evb);
771
772 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF);
773 tt_line_eq("");
774 free(cp);
775 evbuffer_validate(evb);
776
777 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF);
778 tt_line_eq("final");
779 s = "x";
780 evbuffer_validate(evb);
781 evbuffer_add(evb, s, 1);
782 evbuffer_validate(evb);
783 free(cp);
784 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF);
785 tt_assert(!cp);
786 evbuffer_validate(evb);
787
788
789 s = " and a bad crlf\nand a good one\r\n\r\nMore\r";
790 evbuffer_add(evb, s, strlen(s));
791 evbuffer_validate(evb);
792 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
793 tt_line_eq("x and a bad crlf\nand a good one");
794 free(cp);
795 evbuffer_validate(evb);
796
797 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
798 tt_line_eq("");
799 free(cp);
800 evbuffer_validate(evb);
801
802 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
803 tt_assert(!cp);
804 evbuffer_validate(evb);
805 evbuffer_add(evb, "\n", 1);
806 evbuffer_validate(evb);
807
808 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
809 tt_line_eq("More");
810 free(cp);
811 tt_assert(evbuffer_get_length(evb) == 0);
812 evbuffer_validate(evb);
813
814 s = "An internal CR\r is not an eol\r\nNor is a lack of one";
815 evbuffer_add(evb, s, strlen(s));
816 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
817 tt_line_eq("An internal CR\r is not an eol");
818 free(cp);
819 evbuffer_validate(evb);
820
821 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
822 tt_assert(!cp);
823 evbuffer_validate(evb);
824
825 evbuffer_add(evb, "\r\n", 2);
826 evbuffer_validate(evb);
827 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
828 tt_line_eq("Nor is a lack of one");
829 free(cp);
830 tt_assert(evbuffer_get_length(evb) == 0);
831 evbuffer_validate(evb);
832
833
834 s = "An\rand a nl\n\nText";
835 evbuffer_add(evb, s, strlen(s));
836 evbuffer_validate(evb);
837
838 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
839 tt_line_eq("An\rand a nl");
840 free(cp);
841 evbuffer_validate(evb);
842
843 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
844 tt_line_eq("");
845 free(cp);
846 evbuffer_validate(evb);
847
848 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
849 tt_assert(!cp);
850 free(cp);
851 evbuffer_add(evb, "\n", 1);
852 evbuffer_validate(evb);
853 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
854 tt_line_eq("Text");
855 free(cp);
856 evbuffer_validate(evb);
857
858
859 s = " and a bad crlf\nand a good one\r";
860 evbuffer_add(evb_tmp, s, strlen(s));
861 evbuffer_validate(evb);
862 evbuffer_add_buffer(evb, evb_tmp);
863 evbuffer_validate(evb);
864 s = "\n\r";
865 evbuffer_add(evb_tmp, s, strlen(s));
866 evbuffer_validate(evb);
867 evbuffer_add_buffer(evb, evb_tmp);
868 evbuffer_validate(evb);
869 s = "\nMore\r";
870 evbuffer_add(evb_tmp, s, strlen(s));
871 evbuffer_validate(evb);
872 evbuffer_add_buffer(evb, evb_tmp);
873 evbuffer_validate(evb);
874
875 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
876 tt_line_eq(" and a bad crlf\nand a good one");
877 free(cp);
878 evbuffer_validate(evb);
879
880 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
881 tt_line_eq("");
882 free(cp);
883 evbuffer_validate(evb);
884
885 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
886 tt_assert(!cp);
887 free(cp);
888 evbuffer_validate(evb);
889 evbuffer_add(evb, "\n", 1);
890 evbuffer_validate(evb);
891 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
892 tt_line_eq("More");
893 free(cp); cp = NULL;
894 evbuffer_validate(evb);
895 tt_assert(evbuffer_get_length(evb) == 0);
896
897
898 s = "one line\ntwo line\nblue line";
899 evbuffer_add(evb_tmp, s, strlen(s));
900 evbuffer_validate(evb);
901 evbuffer_add_buffer(evb, evb_tmp);
902 evbuffer_validate(evb);
903
904 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
905 tt_line_eq("one line");
906 free(cp); cp = NULL;
907 evbuffer_validate(evb);
908
909
910 #ifndef _EVENT_DISABLE_MM_REPLACEMENT
911 event_set_mem_functions(failing_malloc, realloc, free);
912 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
913 tt_assert(cp == NULL);
914 evbuffer_validate(evb);
915
916
917 event_set_mem_functions(malloc, realloc, free);
918 #endif
919 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
920 tt_line_eq("two line");
921 free(cp); cp = NULL;
922 evbuffer_validate(evb);
923
924 end:
925 evbuffer_free(evb);
926 evbuffer_free(evb_tmp);
927 if (cp) free(cp);
928 }
929
930 static void
931 test_evbuffer_search_eol(void *ptr)
932 {
933 struct evbuffer *buf = evbuffer_new();
934 struct evbuffer_ptr ptr1, ptr2;
935 const char *s;
936 size_t eol_len;
937
938 s = "string! \r\n\r\nx\n";
939 evbuffer_add(buf, s, strlen(s));
940 eol_len = -1;
941 ptr1 = evbuffer_search_eol(buf, NULL, &eol_len, EVBUFFER_EOL_CRLF);
942 tt_int_op(ptr1.pos, ==, 8);
943 tt_int_op(eol_len, ==, 2);
944
945 eol_len = -1;
946 ptr2 = evbuffer_search_eol(buf, &ptr1, &eol_len, EVBUFFER_EOL_CRLF);
947 tt_int_op(ptr2.pos, ==, 8);
948 tt_int_op(eol_len, ==, 2);
949
950 evbuffer_ptr_set(buf, &ptr1, 1, EVBUFFER_PTR_ADD);
951 eol_len = -1;
952 ptr2 = evbuffer_search_eol(buf, &ptr1, &eol_len, EVBUFFER_EOL_CRLF);
953 tt_int_op(ptr2.pos, ==, 9);
954 tt_int_op(eol_len, ==, 1);
955
956 eol_len = -1;
957 ptr2 = evbuffer_search_eol(buf, &ptr1, &eol_len, EVBUFFER_EOL_CRLF_STRICT);
958 tt_int_op(ptr2.pos, ==, 10);
959 tt_int_op(eol_len, ==, 2);
960
961 eol_len = -1;
962 ptr1 = evbuffer_search_eol(buf, NULL, &eol_len, EVBUFFER_EOL_LF);
963 tt_int_op(ptr1.pos, ==, 9);
964 tt_int_op(eol_len, ==, 1);
965
966 eol_len = -1;
967 ptr2 = evbuffer_search_eol(buf, &ptr1, &eol_len, EVBUFFER_EOL_LF);
968 tt_int_op(ptr2.pos, ==, 9);
969 tt_int_op(eol_len, ==, 1);
970
971 evbuffer_ptr_set(buf, &ptr1, 1, EVBUFFER_PTR_ADD);
972 eol_len = -1;
973 ptr2 = evbuffer_search_eol(buf, &ptr1, &eol_len, EVBUFFER_EOL_LF);
974 tt_int_op(ptr2.pos, ==, 11);
975 tt_int_op(eol_len, ==, 1);
976
977 end:
978 evbuffer_free(buf);
979 }
980
981 static void
982 test_evbuffer_iterative(void *ptr)
983 {
984 struct evbuffer *buf = evbuffer_new();
985 const char *abc = "abcdefghijklmnopqrstvuwxyzabcdefghijklmnopqrstvuwxyzabcdefghijklmnopqrstvuwxyzabcdefghijklmnopqrstvuwxyz";
986 unsigned i, j, sum, n;
987
988 sum = 0;
989 n = 0;
990 for (i = 0; i < 1000; ++i) {
991 for (j = 1; j < strlen(abc); ++j) {
992 char format[32];
993 evutil_snprintf(format, sizeof(format), "%%%u.%us", j, j);
994 evbuffer_add_printf(buf, format, abc);
995
996
997
998
999
1000 if ((n % 337) == 0)
1001 evbuffer_validate(buf);
1002
1003 sum += j;
1004 n++;
1005 }
1006 }
1007 evbuffer_validate(buf);
1008
1009 tt_uint_op(sum, ==, evbuffer_get_length(buf));
1010
1011 {
1012 size_t a,w,u;
1013 a=w=u=0;
1014 evbuffer_get_waste(buf, &a, &w, &u);
1015 if (0)
1016 printf("Allocated: %u.\nWasted: %u.\nUsed: %u.",
1017 (unsigned)a, (unsigned)w, (unsigned)u);
1018 tt_assert( ((double)w)/a < .125);
1019 }
1020 end:
1021 evbuffer_free(buf);
1022
1023 }
1024
1025 static void
1026 test_evbuffer_find(void *ptr)
1027 {
1028 u_char* p;
1029 const char* test1 = "1234567890\r\n";
1030 const char* test2 = "1234567890\r";
1031 #define EVBUFFER_INITIAL_LENGTH 256
1032 char test3[EVBUFFER_INITIAL_LENGTH];
1033 unsigned int i;
1034 struct evbuffer * buf = evbuffer_new();
1035
1036 tt_assert(buf);
1037
1038
1039 evbuffer_add(buf, (u_char*)test1, strlen(test1));
1040 evbuffer_validate(buf);
1041 evbuffer_drain(buf, strlen(test1));
1042 evbuffer_validate(buf);
1043 evbuffer_add(buf, (u_char*)test2, strlen(test2));
1044 evbuffer_validate(buf);
1045 p = evbuffer_find(buf, (u_char*)"\r\n", 2);
1046 tt_want(p == NULL);
1047
1048
1049
1050
1051
1052 evbuffer_drain(buf, strlen(test2));
1053 evbuffer_validate(buf);
1054 for (i = 0; i < EVBUFFER_INITIAL_LENGTH; ++i)
1055 test3[i] = 'a';
1056 test3[EVBUFFER_INITIAL_LENGTH - 1] = 'x';
1057 evbuffer_add(buf, (u_char *)test3, EVBUFFER_INITIAL_LENGTH);
1058 evbuffer_validate(buf);
1059 p = evbuffer_find(buf, (u_char *)"xy", 2);
1060 tt_want(p == NULL);
1061
1062
1063 p = evbuffer_find(buf, (u_char *)"ax", 2);
1064 tt_assert(p != NULL);
1065 tt_want(strncmp((char*)p, "ax", 2) == 0);
1066
1067 end:
1068 if (buf)
1069 evbuffer_free(buf);
1070 }
1071
1072 static void
1073 test_evbuffer_ptr_set(void *ptr)
1074 {
1075 struct evbuffer *buf = evbuffer_new();
1076 struct evbuffer_ptr pos;
1077 struct evbuffer_iovec v[1];
1078
1079 tt_assert(buf);
1080
1081
1082 evbuffer_reserve_space(buf, 5000, v, 1);
1083 v[0].iov_len = 5000;
1084 memset(v[0].iov_base, 1, v[0].iov_len);
1085 evbuffer_commit_space(buf, v, 1);
1086 evbuffer_validate(buf);
1087
1088 evbuffer_reserve_space(buf, 4000, v, 1);
1089 v[0].iov_len = 4000;
1090 memset(v[0].iov_base, 2, v[0].iov_len);
1091 evbuffer_commit_space(buf, v, 1);
1092
1093 evbuffer_reserve_space(buf, 3000, v, 1);
1094 v[0].iov_len = 3000;
1095 memset(v[0].iov_base, 3, v[0].iov_len);
1096 evbuffer_commit_space(buf, v, 1);
1097 evbuffer_validate(buf);
1098
1099 tt_int_op(evbuffer_get_length(buf), ==, 12000);
1100
1101 tt_assert(evbuffer_ptr_set(buf, &pos, 13000, EVBUFFER_PTR_SET) == -1);
1102 tt_assert(pos.pos == -1);
1103 tt_assert(evbuffer_ptr_set(buf, &pos, 0, EVBUFFER_PTR_SET) == 0);
1104 tt_assert(pos.pos == 0);
1105 tt_assert(evbuffer_ptr_set(buf, &pos, 13000, EVBUFFER_PTR_ADD) == -1);
1106
1107 tt_assert(evbuffer_ptr_set(buf, &pos, 0, EVBUFFER_PTR_SET) == 0);
1108 tt_assert(pos.pos == 0);
1109 tt_assert(evbuffer_ptr_set(buf, &pos, 10000, EVBUFFER_PTR_ADD) == 0);
1110 tt_assert(pos.pos == 10000);
1111 tt_assert(evbuffer_ptr_set(buf, &pos, 1000, EVBUFFER_PTR_ADD) == 0);
1112 tt_assert(pos.pos == 11000);
1113 tt_assert(evbuffer_ptr_set(buf, &pos, 1000, EVBUFFER_PTR_ADD) == -1);
1114 tt_assert(pos.pos == -1);
1115
1116 end:
1117 if (buf)
1118 evbuffer_free(buf);
1119 }
1120
1121 static void
1122 test_evbuffer_search(void *ptr)
1123 {
1124 struct evbuffer *buf = evbuffer_new();
1125 struct evbuffer *tmp = evbuffer_new();
1126 struct evbuffer_ptr pos, end;
1127
1128 tt_assert(buf);
1129 tt_assert(tmp);
1130
1131
1132 evbuffer_add_printf(tmp, "hello");
1133 evbuffer_add_buffer(buf, tmp);
1134 evbuffer_add_printf(tmp, "foo");
1135 evbuffer_add_buffer(buf, tmp);
1136 evbuffer_add_printf(tmp, "cat");
1137 evbuffer_add_buffer(buf, tmp);
1138 evbuffer_add_printf(tmp, "attack");
1139 evbuffer_add_buffer(buf, tmp);
1140
1141 pos = evbuffer_search(buf, "attack", 6, NULL);
1142 tt_int_op(pos.pos, ==, 11);
1143 pos = evbuffer_search(buf, "attacker", 8, NULL);
1144 tt_int_op(pos.pos, ==, -1);
1145
1146
1147 pos = evbuffer_search(buf, "oc", 2, NULL);
1148 tt_int_op(pos.pos, ==, 7);
1149 pos = evbuffer_search(buf, "cat", 3, &pos);
1150 tt_int_op(pos.pos, ==, 8);
1151 pos = evbuffer_search(buf, "tacking", 7, &pos);
1152 tt_int_op(pos.pos, ==, -1);
1153
1154 evbuffer_ptr_set(buf, &pos, 5, EVBUFFER_PTR_SET);
1155 pos = evbuffer_search(buf, "foo", 3, &pos);
1156 tt_int_op(pos.pos, ==, 5);
1157
1158 evbuffer_ptr_set(buf, &pos, 2, EVBUFFER_PTR_ADD);
1159 pos = evbuffer_search(buf, "tat", 3, &pos);
1160 tt_int_op(pos.pos, ==, 10);
1161
1162
1163
1164 evbuffer_ptr_set(buf, &end, 12, EVBUFFER_PTR_SET);
1165 pos = evbuffer_search_range(buf, "foo", 3, NULL, &end);
1166 tt_int_op(pos.pos, ==, 5);
1167 pos = evbuffer_search_range(buf, "foocata", 7, NULL, &end);
1168 tt_int_op(pos.pos, ==, 5);
1169 pos = evbuffer_search_range(buf, "foocatat", 8, NULL, &end);
1170 tt_int_op(pos.pos, ==, -1);
1171 pos = evbuffer_search_range(buf, "ack", 3, NULL, &end);
1172 tt_int_op(pos.pos, ==, -1);
1173
1174
1175 end:
1176 if (buf)
1177 evbuffer_free(buf);
1178 if (tmp)
1179 evbuffer_free(tmp);
1180 }
1181
1182 static void
1183 log_change_callback(struct evbuffer *buffer,
1184 const struct evbuffer_cb_info *cbinfo,
1185 void *arg)
1186 {
1187
1188 size_t old_len = cbinfo->orig_size;
1189 size_t new_len = old_len + cbinfo->n_added - cbinfo->n_deleted;
1190 struct evbuffer *out = arg;
1191 evbuffer_add_printf(out, "%lu->%lu; ", (unsigned long)old_len,
1192 (unsigned long)new_len);
1193 }
1194 static void
1195 self_draining_callback(struct evbuffer *evbuffer, size_t old_len,
1196 size_t new_len, void *arg)
1197 {
1198 if (new_len > old_len)
1199 evbuffer_drain(evbuffer, new_len);
1200 }
1201
1202 static void
1203 test_evbuffer_callbacks(void *ptr)
1204 {
1205 struct evbuffer *buf = evbuffer_new();
1206 struct evbuffer *buf_out1 = evbuffer_new();
1207 struct evbuffer *buf_out2 = evbuffer_new();
1208 struct evbuffer_cb_entry *cb1, *cb2;
1209
1210 tt_assert(buf);
1211 tt_assert(buf_out1);
1212 tt_assert(buf_out2);
1213
1214 cb1 = evbuffer_add_cb(buf, log_change_callback, buf_out1);
1215 cb2 = evbuffer_add_cb(buf, log_change_callback, buf_out2);
1216
1217
1218
1219
1220
1221 evbuffer_add_printf(buf, "The %d magic words are spotty pudding", 2);
1222 evbuffer_validate(buf);
1223 evbuffer_cb_clear_flags(buf, cb2, EVBUFFER_CB_ENABLED);
1224 evbuffer_drain(buf, 10);
1225 evbuffer_validate(buf);
1226 evbuffer_prepend(buf, "Hello", 5);
1227 evbuffer_cb_set_flags(buf, cb2, EVBUFFER_CB_ENABLED);
1228 evbuffer_add_reference(buf, "Goodbye", 7, NULL, NULL);
1229 evbuffer_remove_cb_entry(buf, cb1);
1230 evbuffer_validate(buf);
1231 evbuffer_drain(buf, evbuffer_get_length(buf)); ;
1232 tt_assert(-1 == evbuffer_remove_cb(buf, log_change_callback, NULL));
1233 evbuffer_add(buf, "X", 1);
1234 tt_assert(!evbuffer_remove_cb(buf, log_change_callback, buf_out2));
1235 evbuffer_validate(buf);
1236
1237 tt_str_op(evbuffer_pullup(buf_out1, -1), ==,
1238 "0->36; 36->26; 26->31; 31->38; ");
1239 tt_str_op(evbuffer_pullup(buf_out2, -1), ==,
1240 "0->36; 31->38; 38->0; 0->1; ");
1241 evbuffer_drain(buf_out1, evbuffer_get_length(buf_out1));
1242 evbuffer_drain(buf_out2, evbuffer_get_length(buf_out2));
1243
1244 cb1 = evbuffer_add_cb(buf, log_change_callback, buf_out1);
1245 tt_assert(cb1 != NULL);
1246 cb2 = evbuffer_add_cb(buf, log_change_callback, buf_out2);
1247 tt_assert(cb2 != NULL);
1248 evbuffer_setcb(buf, self_draining_callback, NULL);
1249 evbuffer_add_printf(buf, "This should get drained right away.");
1250 tt_uint_op(evbuffer_get_length(buf), ==, 0);
1251 tt_uint_op(evbuffer_get_length(buf_out1), ==, 0);
1252 tt_uint_op(evbuffer_get_length(buf_out2), ==, 0);
1253 evbuffer_setcb(buf, NULL, NULL);
1254 evbuffer_add_printf(buf, "This will not.");
1255 tt_str_op(evbuffer_pullup(buf, -1), ==, "This will not.");
1256 evbuffer_validate(buf);
1257 evbuffer_drain(buf, evbuffer_get_length(buf));
1258 evbuffer_validate(buf);
1259 #if 0
1260
1261 cb1 = evbuffer_add_cb(buf, log_change_callback, buf_out1);
1262 cb2 = evbuffer_add_cb(buf, log_change_callback, buf_out2);
1263 evbuffer_cb_suspend(buf,cb2);
1264 evbuffer_prepend(buf,"Hello world",11);
1265 evbuffer_validate(buf);
1266 evbuffer_cb_suspend(buf,cb1);
1267 evbuffer_add(buf,"more",4);
1268 evbuffer_cb_unsuspend(buf,cb2);
1269 evbuffer_drain(buf, 4);
1270 evbuffer_cb_unsuspend(buf,cb1);
1271 evbuffer_drain(buf, evbuffer_get_length(buf));
1272
1273 tt_str_op(evbuffer_pullup(buf_out1, -1), ==,
1274 "0->11; 11->11; 11->0; ");
1275 tt_str_op(evbuffer_pullup(buf_out2, -1), ==,
1276 "0->15; 15->11; 11->0; ");
1277 #endif
1278
1279 end:
1280 if (buf)
1281 evbuffer_free(buf);
1282 if (buf_out1)
1283 evbuffer_free(buf_out1);
1284 if (buf_out2)
1285 evbuffer_free(buf_out2);
1286 }
1287
1288 static int ref_done_cb_called_count = 0;
1289 static void *ref_done_cb_called_with = NULL;
1290 static const void *ref_done_cb_called_with_data = NULL;
1291 static size_t ref_done_cb_called_with_len = 0;
1292 static void ref_done_cb(const void *data, size_t len, void *info)
1293 {
1294 ++ref_done_cb_called_count;
1295 ref_done_cb_called_with = info;
1296 ref_done_cb_called_with_data = data;
1297 ref_done_cb_called_with_len = len;
1298 }
1299
1300 static void
1301 test_evbuffer_add_reference(void *ptr)
1302 {
1303 const char chunk1[] = "If you have found the answer to such a problem";
1304 const char chunk2[] = "you ought to write it up for publication";
1305
1306 char tmp[16];
1307 size_t len1 = strlen(chunk1), len2=strlen(chunk2);
1308
1309 struct evbuffer *buf1 = NULL, *buf2 = NULL;
1310
1311 buf1 = evbuffer_new();
1312 tt_assert(buf1);
1313
1314 evbuffer_add_reference(buf1, chunk1, len1, ref_done_cb, (void*)111);
1315 evbuffer_add(buf1, ", ", 2);
1316 evbuffer_add_reference(buf1, chunk2, len2, ref_done_cb, (void*)222);
1317 tt_int_op(evbuffer_get_length(buf1), ==, len1+len2+2);
1318
1319
1320 tt_int_op(evbuffer_remove(buf1, tmp, 6), ==, 6);
1321 tt_int_op(memcmp(tmp, "If you", 6), ==, 0);
1322 tt_int_op(evbuffer_remove(buf1, tmp, 5), ==, 5);
1323 tt_int_op(memcmp(tmp, " have", 5), ==, 0);
1324
1325
1326 tt_int_op(evbuffer_prepend(buf1, "I have ", 7), ==, 0);
1327 tt_int_op(memcmp(chunk1, "If you", 6), ==, 0);
1328 evbuffer_validate(buf1);
1329
1330
1331 evbuffer_drain(buf1, 7);
1332 evbuffer_drain(buf1, len1-11-1);
1333 tt_int_op(ref_done_cb_called_count, ==, 0);
1334 evbuffer_remove(buf1, tmp, 1);
1335 tt_int_op(tmp[0], ==, 'm');
1336 tt_assert(ref_done_cb_called_with == (void*)111);
1337 tt_assert(ref_done_cb_called_with_data == chunk1);
1338 tt_assert(ref_done_cb_called_with_len == len1);
1339 tt_int_op(ref_done_cb_called_count, ==, 1);
1340 evbuffer_validate(buf1);
1341
1342
1343 evbuffer_drain(buf1, 6);
1344 buf2 = evbuffer_new();
1345 tt_assert(buf2);
1346 tt_int_op(ref_done_cb_called_count, ==, 1);
1347 evbuffer_add(buf2, "I ", 2);
1348
1349 evbuffer_add_buffer(buf2, buf1);
1350 tt_int_op(ref_done_cb_called_count, ==, 1);
1351 evbuffer_remove(buf2, tmp, 16);
1352 tt_int_op(memcmp("I ought to write", tmp, 16), ==, 0);
1353 evbuffer_drain(buf2, evbuffer_get_length(buf2));
1354 tt_int_op(ref_done_cb_called_count, ==, 2);
1355 tt_assert(ref_done_cb_called_with == (void*)222);
1356 evbuffer_validate(buf2);
1357
1358
1359
1360 evbuffer_add(buf1, "You shake and shake the ", 24);
1361 evbuffer_add_reference(buf1, "ketchup bottle", 14, ref_done_cb,
1362 (void*)3333);
1363 evbuffer_add(buf1, ". Nothing comes and then a lot'll.", 42);
1364 evbuffer_free(buf1);
1365 buf1 = NULL;
1366 tt_int_op(ref_done_cb_called_count, ==, 3);
1367 tt_assert(ref_done_cb_called_with == (void*)3333);
1368
1369 end:
1370 if (buf1)
1371 evbuffer_free(buf1);
1372 if (buf2)
1373 evbuffer_free(buf2);
1374 }
1375
1376
1377 static void
1378 test_evbuffer_prepend(void *ptr)
1379 {
1380 struct evbuffer *buf1 = NULL, *buf2 = NULL;
1381 char tmp[128];
1382 int n;
1383
1384 buf1 = evbuffer_new();
1385 tt_assert(buf1);
1386
1387
1388 evbuffer_prepend(buf1, "This string has 29 characters", 29);
1389 evbuffer_validate(buf1);
1390
1391
1392 evbuffer_prepend(buf1, "Short.", 6);
1393 evbuffer_validate(buf1);
1394
1395
1396 evbuffer_drain(buf1, 6+11);
1397 evbuffer_prepend(buf1, "it", 2);
1398 evbuffer_validate(buf1);
1399 tt_assert(!memcmp(buf1->first->buffer+buf1->first->misalign,
1400 "it has", 6));
1401
1402
1403 evbuffer_prepend(buf1, "It is no longer true to say ", 28);
1404 evbuffer_validate(buf1);
1405 n = evbuffer_remove(buf1, tmp, sizeof(tmp)-1);
1406 tmp[n]='\0';
1407 tt_str_op(tmp,==,"It is no longer true to say it has 29 characters");
1408
1409 buf2 = evbuffer_new();
1410 tt_assert(buf2);
1411
1412
1413 n = 999;
1414 evbuffer_add_printf(buf1, "Here is string %d. ", n++);
1415 evbuffer_prepend_buffer(buf2, buf1);
1416 evbuffer_validate(buf2);
1417
1418
1419 evbuffer_add_printf(buf1, "Here is string %d. ", n++);
1420 evbuffer_prepend_buffer(buf2, buf1);
1421 evbuffer_validate(buf2);
1422 evbuffer_validate(buf1);
1423 n = evbuffer_remove(buf2, tmp, sizeof(tmp)-1);
1424 tmp[n]='\0';
1425 tt_str_op(tmp,==,"Here is string 1000. Here is string 999. ");
1426
1427 end:
1428 if (buf1)
1429 evbuffer_free(buf1);
1430 if (buf2)
1431 evbuffer_free(buf2);
1432
1433 }
1434
1435 static void
1436 test_evbuffer_peek(void *info)
1437 {
1438 struct evbuffer *buf = NULL, *tmp_buf = NULL;
1439 int i;
1440 struct evbuffer_iovec v[20];
1441 struct evbuffer_ptr ptr;
1442
1443 #define tt_iov_eq(v, s) \
1444 tt_int_op((v)->iov_len, ==, strlen(s)); \
1445 tt_assert(!memcmp((v)->iov_base, (s), strlen(s)))
1446
1447
1448 buf = evbuffer_new();
1449 tmp_buf = evbuffer_new();
1450 for (i = 0; i < 16; ++i) {
1451 evbuffer_add_printf(tmp_buf, "Contents of chunk [%d]\n", i);
1452 evbuffer_add_buffer(buf, tmp_buf);
1453 }
1454
1455
1456 i = evbuffer_peek(buf, -1, NULL, NULL, 0);
1457 tt_int_op(i, ==, 16);
1458
1459
1460 i = evbuffer_peek(buf, -1, NULL, v, 20);
1461 tt_int_op(i, ==, 16);
1462 tt_iov_eq(&v[0], "Contents of chunk [0]\n");
1463 tt_iov_eq(&v[3], "Contents of chunk [3]\n");
1464 tt_iov_eq(&v[12], "Contents of chunk [12]\n");
1465 tt_iov_eq(&v[15], "Contents of chunk [15]\n");
1466
1467
1468 memset(v, 0, sizeof(v));
1469 i = evbuffer_peek(buf, -1, NULL, v, 1);
1470 tt_int_op(i, ==, 1);
1471 tt_iov_eq(&v[0], "Contents of chunk [0]\n");
1472 tt_assert(v[1].iov_base == NULL);
1473
1474
1475 memset(v, 0, sizeof(v));
1476 i = evbuffer_peek(buf, 40, NULL, v, 16);
1477 tt_int_op(i, ==, 2);
1478 tt_iov_eq(&v[0], "Contents of chunk [0]\n");
1479 tt_iov_eq(&v[1], "Contents of chunk [1]\n");
1480 tt_assert(v[2].iov_base == NULL);
1481
1482
1483 memset(v, 0, sizeof(v));
1484 i = evbuffer_peek(buf, 100, NULL, NULL, 0);
1485 tt_int_op(i, ==, 5);
1486 tt_assert(v[0].iov_base == NULL);
1487
1488
1489 memset(v, 0, sizeof(v));
1490 i = evbuffer_peek(buf, 60, NULL, v, 1);
1491 tt_int_op(i, ==, 3);
1492 tt_iov_eq(&v[0], "Contents of chunk [0]\n");
1493 tt_assert(v[1].iov_base == NULL);
1494
1495
1496 memset(v, 0, sizeof(v));
1497 i = evbuffer_peek(buf, 65536, NULL, v, 20);
1498 tt_int_op(i, ==, 16);
1499 tt_iov_eq(&v[0], "Contents of chunk [0]\n");
1500 tt_iov_eq(&v[3], "Contents of chunk [3]\n");
1501 tt_iov_eq(&v[12], "Contents of chunk [12]\n");
1502 tt_iov_eq(&v[15], "Contents of chunk [15]\n");
1503 tt_assert(v[16].iov_base == NULL);
1504
1505
1506 memset(v, 0, sizeof(v));
1507 i = evbuffer_peek(tmp_buf, -1, NULL, v, 20);
1508 tt_int_op(i, ==, 0);
1509 tt_assert(v[0].iov_base == NULL);
1510 memset(v, 0, sizeof(v));
1511 i = evbuffer_peek(tmp_buf, 50, NULL, v, 20);
1512 tt_int_op(i, ==, 0);
1513 tt_assert(v[0].iov_base == NULL);
1514
1515
1516 memset(v, 0, sizeof(v));
1517 evbuffer_ptr_set(buf, &ptr, 30, EVBUFFER_PTR_SET);
1518 i = evbuffer_peek(buf, 50, &ptr, v, 20);
1519 tt_int_op(i, ==, 3);
1520 tt_iov_eq(&v[0], " of chunk [1]\n");
1521 tt_iov_eq(&v[1], "Contents of chunk [2]\n");
1522 tt_iov_eq(&v[2], "Contents of chunk [3]\n");
1523
1524
1525 memset(v, 0, sizeof(v));
1526 evbuffer_ptr_set(buf, &ptr, 14, EVBUFFER_PTR_ADD);
1527 i = evbuffer_peek(buf, 44, &ptr, v, 20);
1528 tt_int_op(i, ==, 2);
1529 tt_iov_eq(&v[0], "Contents of chunk [2]\n");
1530 tt_iov_eq(&v[1], "Contents of chunk [3]\n");
1531
1532 end:
1533 if (buf)
1534 evbuffer_free(buf);
1535 if (tmp_buf)
1536 evbuffer_free(tmp_buf);
1537 }
1538
1539
1540
1541
1542
1543
1544
1545
1546 static void
1547 test_evbuffer_freeze(void *ptr)
1548 {
1549 struct evbuffer *buf = NULL, *tmp_buf=NULL;
1550 const char string[] =
1551 "I've known the wind by water banks to shake\n"
1552 "The late leaves down, which frozen where they fell\n"
1553 "And held in ice as dancers in a spell\n"
1554 "Fluttered all winter long into a lake...";
1555 const int start = !strcmp(ptr, "start");
1556 char *cp;
1557 char charbuf[128];
1558 int r;
1559 size_t orig_length;
1560 struct evbuffer_iovec v[1];
1561
1562 if (!start)
1563 tt_str_op(ptr, ==, "end");
1564
1565 buf = evbuffer_new();
1566 tmp_buf = evbuffer_new();
1567 tt_assert(tmp_buf);
1568
1569 evbuffer_add(buf, string, strlen(string));
1570 evbuffer_freeze(buf, start);
1571
1572 #define FREEZE_EQ(a, startcase, endcase) \
1573 do { \
1574 if (start) { \
1575 tt_int_op((a), ==, (startcase)); \
1576 } else { \
1577 tt_int_op((a), ==, (endcase)); \
1578 } \
1579 } while (0)
1580
1581
1582 orig_length = evbuffer_get_length(buf);
1583
1584
1585 r = evbuffer_add(buf, "abc", 0);
1586 FREEZE_EQ(r, 0, -1);
1587 r = evbuffer_reserve_space(buf, 10, v, 1);
1588 FREEZE_EQ(r, 1, -1);
1589 if (r == 0) {
1590 memset(v[0].iov_base, 'X', 10);
1591 v[0].iov_len = 10;
1592 }
1593 r = evbuffer_commit_space(buf, v, 1);
1594 FREEZE_EQ(r, 0, -1);
1595 r = evbuffer_add_reference(buf, string, 5, NULL, NULL);
1596 FREEZE_EQ(r, 0, -1);
1597 r = evbuffer_add_printf(buf, "Hello %s", "world");
1598 FREEZE_EQ(r, 11, -1);
1599
1600
1601 if (!start)
1602 tt_int_op(orig_length, ==, evbuffer_get_length(buf));
1603
1604 orig_length = evbuffer_get_length(buf);
1605
1606
1607 r = evbuffer_remove(buf, charbuf, 1);
1608 FREEZE_EQ(r, -1, 1);
1609 r = evbuffer_drain(buf, 3);
1610 FREEZE_EQ(r, -1, 0);
1611 r = evbuffer_prepend(buf, "dummy", 5);
1612 FREEZE_EQ(r, -1, 0);
1613 cp = evbuffer_readln(buf, NULL, EVBUFFER_EOL_LF);
1614 FREEZE_EQ(cp==NULL, 1, 0);
1615 if (cp)
1616 free(cp);
1617
1618
1619 if (start)
1620 tt_int_op(orig_length, ==, evbuffer_get_length(buf));
1621
1622 end:
1623 if (buf)
1624 evbuffer_free(buf);
1625
1626 if (tmp_buf)
1627 evbuffer_free(tmp_buf);
1628 }
1629
1630 static void *
1631 setup_passthrough(const struct testcase_t *testcase)
1632 {
1633 return testcase->setup_data;
1634 }
1635 static int
1636 cleanup_passthrough(const struct testcase_t *testcase, void *ptr)
1637 {
1638 (void) ptr;
1639 return 1;
1640 }
1641
1642 static const struct testcase_setup_t nil_setup = {
1643 setup_passthrough,
1644 cleanup_passthrough
1645 };
1646
1647 struct testcase_t evbuffer_testcases[] = {
1648 { "evbuffer", test_evbuffer, 0, NULL, NULL },
1649 { "remove_buffer_with_empty", test_evbuffer_remove_buffer_with_empty, 0, NULL, NULL },
1650 { "reserve2", test_evbuffer_reserve2, 0, NULL, NULL },
1651 { "reserve_many", test_evbuffer_reserve_many, 0, NULL, NULL },
1652 { "reserve_many2", test_evbuffer_reserve_many, 0, &nil_setup, (void*)"add" },
1653 { "reserve_many3", test_evbuffer_reserve_many, 0, &nil_setup, (void*)"fill" },
1654 { "expand", test_evbuffer_expand, 0, NULL, NULL },
1655 { "reference", test_evbuffer_reference, 0, NULL, NULL },
1656 { "iterative", test_evbuffer_iterative, 0, NULL, NULL },
1657 { "readln", test_evbuffer_readln, TT_NO_LOGS, &basic_setup, NULL },
1658 { "search_eol", test_evbuffer_search_eol, 0, NULL, NULL },
1659 { "find", test_evbuffer_find, 0, NULL, NULL },
1660 { "ptr_set", test_evbuffer_ptr_set, 0, NULL, NULL },
1661 { "search", test_evbuffer_search, 0, NULL, NULL },
1662 { "callbacks", test_evbuffer_callbacks, 0, NULL, NULL },
1663 { "add_reference", test_evbuffer_add_reference, 0, NULL, NULL },
1664 { "prepend", test_evbuffer_prepend, TT_FORK, NULL, NULL },
1665 { "peek", test_evbuffer_peek, 0, NULL, NULL },
1666 { "freeze_start", test_evbuffer_freeze, 0, &nil_setup, (void*)"start" },
1667 { "freeze_end", test_evbuffer_freeze, 0, &nil_setup, (void*)"end" },
1668
1669 { "add_file_sendfile", test_evbuffer_add_file, TT_FORK, &nil_setup,
1670 (void*)"sendfile" },
1671 { "add_file_mmap", test_evbuffer_add_file, TT_FORK, &nil_setup,
1672 (void*)"mmap" },
1673 { "add_file_linear", test_evbuffer_add_file, TT_FORK, &nil_setup,
1674 (void*)"linear" },
1675
1676 END_OF_TESTCASES
1677 };