2 * Copyright (c) 2003-2007 Niels Provos <provos@citi.umich.edu>
3 * Copyright (c) 2007-2010 Niels Provos and Nick Mathewson
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 #include "event2/event-config.h"
35 #include <sys/types.h>
37 #ifdef _EVENT_HAVE_SYS_TIME_H
40 #include <sys/queue.h>
42 #include <sys/socket.h>
54 #include "event2/event.h"
55 #include "event2/buffer.h"
56 #include "event2/buffer_compat.h"
57 #include "event2/util.h"
59 #include "evbuffer-internal.h"
60 #include "log-internal.h"
64 /* Validates that an evbuffer is good. Returns false if it isn't, true if it
67 _evbuffer_validate(struct evbuffer *buf)
69 struct evbuffer_chain *chain;
71 int found_last_with_datap = 0;
73 if (buf->first == NULL) {
74 tt_assert(buf->last == NULL);
75 tt_assert(buf->total_len == 0);
80 tt_assert(buf->last_with_datap);
81 if (buf->last_with_datap == &buf->first)
82 found_last_with_datap = 1;
84 while (chain != NULL) {
85 if (&chain->next == buf->last_with_datap)
86 found_last_with_datap = 1;
88 if (chain->next == NULL) {
89 tt_assert(buf->last == chain);
91 tt_assert(chain->buffer_len >= chain->misalign + chain->off);
96 tt_assert(*buf->last_with_datap);
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);
106 while (chain != NULL) {
107 tt_assert(chain->off == 0);
111 tt_assert(buf->last_with_datap == &buf->first);
113 tt_assert(found_last_with_datap);
115 tt_assert(sum == buf->total_len);
122 evbuffer_get_waste(struct evbuffer *buf, size_t *allocatedp, size_t *wastedp, size_t *usedp)
124 struct evbuffer_chain *chain;
130 /* skip empty at start */
131 while (chain && chain->off==0) {
133 a += chain->buffer_len;
136 /* first nonempty chain: stuff at the end only is wasted. */
139 a += chain->buffer_len;
141 if (chain->next && chain->next->off)
142 w += (size_t)(chain->buffer_len - (chain->misalign + chain->off));
145 /* subsequent nonempty chains */
146 while (chain && chain->off) {
148 a += chain->buffer_len;
149 w += (size_t)chain->misalign;
151 if (chain->next && chain->next->off)
152 w += (size_t) (chain->buffer_len - (chain->misalign + chain->off));
155 /* subsequent empty chains */
158 a += chain->buffer_len;
165 #define evbuffer_validate(buf) \
166 TT_STMT_BEGIN if (!_evbuffer_validate(buf)) TT_DIE(("Buffer format invalid")); TT_STMT_END
169 test_evbuffer(void *ptr)
171 static char buffer[512], *tmp;
172 struct evbuffer *evb = evbuffer_new();
173 struct evbuffer *evb_two = evbuffer_new();
177 evbuffer_validate(evb);
178 evbuffer_add_printf(evb, "%s/%d", "hello", 1);
179 evbuffer_validate(evb);
181 tt_assert(evbuffer_get_length(evb) == 7);
182 tt_assert(!memcmp((char*)EVBUFFER_DATA(evb), "hello/1", 1));
184 evbuffer_add_buffer(evb, evb_two);
185 evbuffer_validate(evb);
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));
192 evbuffer_add_printf(evb_two, "%s", "/hello");
193 evbuffer_validate(evb);
194 evbuffer_add_buffer(evb, evb_two);
195 evbuffer_validate(evb);
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);
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);
206 tmp = (char *)evbuffer_pullup(evb, 7 + 512);
208 tt_assert(!strncmp(tmp, "1/hello", 7));
209 tt_assert(!memcmp(tmp + 7, buffer, sizeof(buffer)));
210 evbuffer_validate(evb);
212 evbuffer_prepend(evb, "something", 9);
213 evbuffer_validate(evb);
214 evbuffer_prepend(evb, "else", 4);
215 evbuffer_validate(evb);
217 tmp = (char *)evbuffer_pullup(evb, 4 + 9 + 7);
218 tt_assert(!strncmp(tmp, "elsesomething1/hello", 4 + 9 + 7));
219 evbuffer_validate(evb);
221 evbuffer_drain(evb, -1);
222 evbuffer_validate(evb);
223 evbuffer_drain(evb_two, -1);
224 evbuffer_validate(evb);
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);
234 tt_assert(evbuffer_get_length(evb_two) == 0);
235 tt_assert(evbuffer_get_length(evb) == i * sizeof(buffer));
237 /* test remove buffer */
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);
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");
250 evbuffer_validate(evb);
253 /* testing one-vector reserve and commit */
255 struct evbuffer_iovec v[1];
259 for (i = 0; i < 3; ++i) {
260 r = evbuffer_reserve_space(evb, 10000, v, 1);
262 tt_assert(v[0].iov_len >= 10000);
263 tt_assert(v[0].iov_base != NULL);
265 evbuffer_validate(evb);
267 for (j = 0; j < 10000; ++j) {
270 evbuffer_validate(evb);
272 tt_int_op(evbuffer_commit_space(evb, v, 1), ==, 0);
273 evbuffer_validate(evb);
275 tt_assert(evbuffer_get_length(evb) >= 10000);
277 evbuffer_drain(evb, j * 5000);
278 evbuffer_validate(evb);
284 evbuffer_free(evb_two);
288 test_evbuffer_reserve2(void *ptr)
290 /* Test the two-vector cases of reserve/commit. */
291 struct evbuffer *buf = evbuffer_new();
293 struct evbuffer_iovec v[2];
297 /* First chunk will necessarily be one chunk. Use 512 bytes of it.*/
298 n = evbuffer_reserve_space(buf, 1024, v, 2);
300 tt_int_op(evbuffer_get_length(buf), ==, 0);
301 tt_assert(v[0].iov_base != NULL);
302 tt_int_op(v[0].iov_len, >=, 1024);
303 memset(v[0].iov_base, 'X', 512);
305 remaining = v[0].iov_len - 512;
307 evbuffer_validate(buf);
308 tt_int_op(0, ==, evbuffer_commit_space(buf, v, 1));
309 tt_int_op(evbuffer_get_length(buf), ==, 512);
310 evbuffer_validate(buf);
312 /* Ask for another same-chunk request, in an existing chunk. Use 8
314 n = evbuffer_reserve_space(buf, 32, v, 2);
316 tt_assert(cp + 512 == v[0].iov_base);
317 tt_int_op(remaining, ==, v[0].iov_len);
318 memset(v[0].iov_base, 'Y', 8);
320 tt_int_op(0, ==, evbuffer_commit_space(buf, v, 1));
321 tt_int_op(evbuffer_get_length(buf), ==, 520);
323 evbuffer_validate(buf);
325 /* Now ask for a request that will be split. Use only one byte of it,
327 n = evbuffer_reserve_space(buf, remaining+64, v, 2);
329 tt_assert(cp + 520 == v[0].iov_base);
330 tt_int_op(remaining, ==, v[0].iov_len);
331 tt_assert(v[1].iov_base);
332 tt_assert(v[1].iov_len >= 64);
334 memset(v[0].iov_base, 'Z', 1);
336 tt_int_op(0, ==, evbuffer_commit_space(buf, v, 1));
337 tt_int_op(evbuffer_get_length(buf), ==, 521);
339 evbuffer_validate(buf);
341 /* Now ask for a request that will be split. Use some of the first
342 * part and some of the second. */
343 n = evbuffer_reserve_space(buf, remaining+64, v, 2);
344 evbuffer_validate(buf);
346 tt_assert(cp + 521 == v[0].iov_base);
347 tt_int_op(remaining, ==, v[0].iov_len);
348 tt_assert(v[1].iov_base == cp2);
349 tt_assert(v[1].iov_len >= 64);
350 memset(v[0].iov_base, 'W', 400);
352 memset(v[1].iov_base, 'x', 60);
354 tt_int_op(0, ==, evbuffer_commit_space(buf, v, 2));
355 tt_int_op(evbuffer_get_length(buf), ==, 981);
356 evbuffer_validate(buf);
358 /* Now peek to make sure stuff got made how we like. */
359 memset(v,0,sizeof(v));
360 n = evbuffer_peek(buf, -1, NULL, v, 2);
362 tt_int_op(v[0].iov_len, ==, 921);
363 tt_int_op(v[1].iov_len, ==, 60);
366 for (i=0; i<512; ++i)
367 tt_int_op(cp[i], ==, 'X');
368 for (i=512; i<520; ++i)
369 tt_int_op(cp[i], ==, 'Y');
370 for (i=520; i<521; ++i)
371 tt_int_op(cp[i], ==, 'Z');
372 for (i=521; i<921; ++i)
373 tt_int_op(cp[i], ==, 'W');
377 tt_int_op(cp[i], ==, 'x');
384 test_evbuffer_reserve_many(void *ptr)
386 /* This is a glass-box test to handle expanding a buffer with more
387 * chunks and reallocating chunks as needed */
388 struct evbuffer *buf = evbuffer_new();
389 struct evbuffer_iovec v[8];
392 int add_data = ptr && !strcmp(ptr, "add");
393 int fill_first = ptr && !strcmp(ptr, "fill");
396 /* When reserving the the first chunk, we just allocate it */
397 n = evbuffer_reserve_space(buf, 128, v, 2);
398 evbuffer_validate(buf);
400 tt_assert(v[0].iov_len >= 128);
404 *(char*)v[0].iov_base = 'X';
406 n = evbuffer_commit_space(buf, v, 1);
408 } else if (fill_first) {
409 memset(v[0].iov_base, 'X', v[0].iov_len);
410 n = evbuffer_commit_space(buf, v, 1);
412 n = evbuffer_reserve_space(buf, 128, v, 2);
415 tt_assert(v[0].iov_base != cp1);
419 /* Make another chunk get added. */
420 n = evbuffer_reserve_space(buf, sz+128, v, 2);
421 evbuffer_validate(buf);
423 sz = v[0].iov_len + v[1].iov_len;
424 tt_int_op(sz, >=, v[0].iov_len+128);
426 tt_assert(v[0].iov_base == cp1 + 1);
428 tt_assert(v[0].iov_base == cp1);
433 /* And a third chunk. */
434 n = evbuffer_reserve_space(buf, sz+128, v, 3);
435 evbuffer_validate(buf);
437 tt_assert(cp1 == v[0].iov_base);
438 tt_assert(cp2 == v[1].iov_base);
439 sz = v[0].iov_len + v[1].iov_len + v[2].iov_len;
441 /* Now force a reallocation by asking for more space in only 2
443 n = evbuffer_reserve_space(buf, sz+128, v, 2);
444 evbuffer_validate(buf);
447 tt_assert(cp1 == v[0].iov_base);
457 test_evbuffer_expand(void *ptr)
460 struct evbuffer *buf;
464 memset(data, 'X', sizeof(data));
466 /* Make sure that expand() works on an empty buffer */
467 buf = evbuffer_new();
468 tt_int_op(evbuffer_expand(buf, 20000), ==, 0);
469 evbuffer_validate(buf);
471 evbuffer_get_waste(buf, &a,&w,&u);
474 tt_assert(a >= 20000);
475 tt_assert(buf->first);
476 tt_assert(buf->first == buf->last);
477 tt_assert(buf->first->off == 0);
478 tt_assert(buf->first->buffer_len >= 20000);
480 /* Make sure that expand() works as a no-op when there's enough
481 * contiguous space already. */
482 buffer = buf->first->buffer;
483 evbuffer_add(buf, data, 1024);
484 tt_int_op(evbuffer_expand(buf, 1024), ==, 0);
485 tt_assert(buf->first->buffer == buffer);
486 evbuffer_validate(buf);
489 /* Make sure that expand() can work by moving misaligned data
490 * when it makes sense to do so. */
491 buf = evbuffer_new();
492 evbuffer_add(buf, data, 400);
494 int n = (int)(buf->first->buffer_len - buf->first->off - 1);
495 tt_assert(n < (int)sizeof(data));
496 evbuffer_add(buf, data, n);
498 tt_assert(buf->first == buf->last);
499 tt_assert(buf->first->off == buf->first->buffer_len - 1);
500 evbuffer_drain(buf, buf->first->off - 1);
501 tt_assert(1 == evbuffer_get_length(buf));
502 tt_assert(buf->first->misalign > 0);
503 tt_assert(buf->first->off == 1);
504 buffer = buf->first->buffer;
505 tt_assert(evbuffer_expand(buf, 40) == 0);
506 tt_assert(buf->first == buf->last);
507 tt_assert(buf->first->off == 1);
508 tt_assert(buf->first->buffer == buffer);
509 tt_assert(buf->first->misalign == 0);
510 evbuffer_validate(buf);
513 /* add, expand, pull-up: This used to crash libevent. */
514 buf = evbuffer_new();
516 evbuffer_add(buf, data, sizeof(data));
517 evbuffer_add(buf, data, sizeof(data));
518 evbuffer_add(buf, data, sizeof(data));
520 evbuffer_validate(buf);
521 evbuffer_expand(buf, 1024);
522 evbuffer_validate(buf);
523 evbuffer_pullup(buf, -1);
524 evbuffer_validate(buf);
531 static int reference_cb_called;
533 reference_cb(const void *data, size_t len, void *extra)
535 tt_str_op(data, ==, "this is what we add as read-only memory.");
536 tt_int_op(len, ==, strlen(data));
537 tt_want(extra == (void *)0xdeadaffe);
538 ++reference_cb_called;
544 test_evbuffer_reference(void *ptr)
546 struct evbuffer *src = evbuffer_new();
547 struct evbuffer *dst = evbuffer_new();
548 struct evbuffer_iovec v[1];
549 const char *data = "this is what we add as read-only memory.";
550 reference_cb_called = 0;
552 tt_assert(evbuffer_add_reference(src, data, strlen(data),
553 reference_cb, (void *)0xdeadaffe) != -1);
555 evbuffer_reserve_space(dst, strlen(data), v, 1);
556 tt_assert(evbuffer_remove(src, v[0].iov_base, 10) != -1);
558 evbuffer_validate(src);
559 evbuffer_validate(dst);
561 /* make sure that we don't write data at the beginning */
562 evbuffer_prepend(src, "aaaaa", 5);
563 evbuffer_validate(src);
564 evbuffer_drain(src, 5);
566 tt_assert(evbuffer_remove(src, ((char*)(v[0].iov_base)) + 10,
567 strlen(data) - 10) != -1);
569 v[0].iov_len = strlen(data);
571 evbuffer_commit_space(dst, v, 1);
572 evbuffer_validate(src);
573 evbuffer_validate(dst);
575 tt_int_op(reference_cb_called, ==, 1);
577 tt_assert(!memcmp(evbuffer_pullup(dst, strlen(data)),
578 data, strlen(data)));
579 evbuffer_validate(dst);
586 int _evbuffer_testing_use_sendfile(void);
587 int _evbuffer_testing_use_mmap(void);
588 int _evbuffer_testing_use_linear_file_access(void);
591 test_evbuffer_add_file(void *ptr)
593 const char *impl = ptr;
594 struct evbuffer *src = evbuffer_new();
595 const char *data = "this is what we add as file system data.";
599 evutil_socket_t pair[2] = {-1, -1};
600 int r=0, n_written=0;
602 /* Add a test for a big file. XXXX */
605 if (!strcmp(impl, "sendfile")) {
606 if (!_evbuffer_testing_use_sendfile())
608 TT_BLATHER(("Using sendfile-based implementaion"));
609 } else if (!strcmp(impl, "mmap")) {
610 if (!_evbuffer_testing_use_mmap())
612 TT_BLATHER(("Using mmap-based implementaion"));
613 } else if (!strcmp(impl, "linear")) {
614 if (!_evbuffer_testing_use_linear_file_access())
616 TT_BLATHER(("Using read-based implementaion"));
618 TT_DIE(("Didn't recognize the implementation"));
621 #if defined(_EVENT_HAVE_SENDFILE) && defined(__sun__) && defined(__svr4__)
622 /* We need to use a pair of AF_INET sockets, since Solaris
623 doesn't support sendfile() over AF_UNIX. */
624 if (evutil_ersatz_socketpair(AF_INET, SOCK_STREAM, 0, pair) == -1)
625 tt_abort_msg("ersatz_socketpair failed");
627 if (evutil_socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1)
628 tt_abort_msg("socketpair failed");
631 datalen = strlen(data);
632 fd = regress_make_tmpfile(data, datalen);
636 tt_assert(evbuffer_add_file(src, fd, 0, datalen) != -1);
638 evbuffer_validate(src);
640 while (evbuffer_get_length(src) &&
641 (r = evbuffer_write(src, pair[0])) > 0) {
642 evbuffer_validate(src);
645 tt_int_op(r, !=, -1);
646 tt_int_op(n_written, ==, datalen);
648 evbuffer_validate(src);
649 tt_int_op(evbuffer_read(src, pair[1], (int)strlen(data)), ==, datalen);
650 evbuffer_validate(src);
651 compare = (char *)evbuffer_pullup(src, datalen);
652 tt_assert(compare != NULL);
653 if (memcmp(compare, data, datalen))
654 tt_abort_msg("Data from add_file differs.");
656 evbuffer_validate(src);
659 evutil_closesocket(pair[0]);
661 evutil_closesocket(pair[1]);
665 #ifndef _EVENT_DISABLE_MM_REPLACEMENT
667 failing_malloc(size_t how_much)
675 test_evbuffer_readln(void *ptr)
677 struct evbuffer *evb = evbuffer_new();
678 struct evbuffer *evb_tmp = evbuffer_new();
683 #define tt_line_eq(content) \
685 if (!cp || sz != strlen(content) || strcmp(cp, content)) { \
686 TT_DIE(("Wanted %s; got %s [%d]", content, cp, (int)sz)); \
691 s = "complex silly newline\r\n\n\r\n\n\rmore\0\n";
692 evbuffer_add(evb, s, strlen(s)+2);
693 evbuffer_validate(evb);
694 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_ANY);
695 tt_line_eq("complex silly newline");
697 evbuffer_validate(evb);
698 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_ANY);
699 if (!cp || sz != 5 || memcmp(cp, "more\0\0", 6))
700 tt_abort_msg("Not as expected");
701 tt_uint_op(evbuffer_get_length(evb), ==, 0);
702 evbuffer_validate(evb);
704 evbuffer_add(evb, s, strlen(s));
706 evbuffer_validate(evb);
707 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_ANY);
710 evbuffer_validate(evb);
711 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_ANY);
713 evbuffer_validate(evb);
714 evbuffer_drain(evb, evbuffer_get_length(evb));
715 tt_assert(evbuffer_get_length(evb) == 0);
716 evbuffer_validate(evb);
719 s = "Line with\rin the middle\nLine with good crlf\r\n\nfinal\n";
720 evbuffer_add(evb, s, strlen(s));
721 evbuffer_validate(evb);
722 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF);
723 tt_line_eq("Line with\rin the middle");
725 evbuffer_validate(evb);
727 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF);
728 tt_line_eq("Line with good crlf");
730 evbuffer_validate(evb);
732 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF);
735 evbuffer_validate(evb);
737 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF);
740 evbuffer_validate(evb);
741 evbuffer_add(evb, s, 1);
742 evbuffer_validate(evb);
744 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF);
746 evbuffer_validate(evb);
748 /* Test CRLF_STRICT */
749 s = " and a bad crlf\nand a good one\r\n\r\nMore\r";
750 evbuffer_add(evb, s, strlen(s));
751 evbuffer_validate(evb);
752 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
753 tt_line_eq("x and a bad crlf\nand a good one");
755 evbuffer_validate(evb);
757 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
760 evbuffer_validate(evb);
762 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
764 evbuffer_validate(evb);
765 evbuffer_add(evb, "\n", 1);
766 evbuffer_validate(evb);
768 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
771 tt_assert(evbuffer_get_length(evb) == 0);
772 evbuffer_validate(evb);
774 s = "An internal CR\r is not an eol\r\nNor is a lack of one";
775 evbuffer_add(evb, s, strlen(s));
776 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
777 tt_line_eq("An internal CR\r is not an eol");
779 evbuffer_validate(evb);
781 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
783 evbuffer_validate(evb);
785 evbuffer_add(evb, "\r\n", 2);
786 evbuffer_validate(evb);
787 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
788 tt_line_eq("Nor is a lack of one");
790 tt_assert(evbuffer_get_length(evb) == 0);
791 evbuffer_validate(evb);
794 s = "An\rand a nl\n\nText";
795 evbuffer_add(evb, s, strlen(s));
796 evbuffer_validate(evb);
798 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
799 tt_line_eq("An\rand a nl");
801 evbuffer_validate(evb);
803 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
806 evbuffer_validate(evb);
808 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
811 evbuffer_add(evb, "\n", 1);
812 evbuffer_validate(evb);
813 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
816 evbuffer_validate(evb);
818 /* Test CRLF_STRICT - across boundaries*/
819 s = " and a bad crlf\nand a good one\r";
820 evbuffer_add(evb_tmp, s, strlen(s));
821 evbuffer_validate(evb);
822 evbuffer_add_buffer(evb, evb_tmp);
823 evbuffer_validate(evb);
825 evbuffer_add(evb_tmp, s, strlen(s));
826 evbuffer_validate(evb);
827 evbuffer_add_buffer(evb, evb_tmp);
828 evbuffer_validate(evb);
830 evbuffer_add(evb_tmp, s, strlen(s));
831 evbuffer_validate(evb);
832 evbuffer_add_buffer(evb, evb_tmp);
833 evbuffer_validate(evb);
835 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
836 tt_line_eq(" and a bad crlf\nand a good one");
838 evbuffer_validate(evb);
840 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
843 evbuffer_validate(evb);
845 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
848 evbuffer_validate(evb);
849 evbuffer_add(evb, "\n", 1);
850 evbuffer_validate(evb);
851 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
854 evbuffer_validate(evb);
855 tt_assert(evbuffer_get_length(evb) == 0);
857 /* Test memory problem*/
858 s = "one line\ntwo line\nblue line";
859 evbuffer_add(evb_tmp, s, strlen(s));
860 evbuffer_validate(evb);
861 evbuffer_add_buffer(evb, evb_tmp);
862 evbuffer_validate(evb);
864 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
865 tt_line_eq("one line");
867 evbuffer_validate(evb);
869 /* the next call to readline should fail */
870 #ifndef _EVENT_DISABLE_MM_REPLACEMENT
871 event_set_mem_functions(failing_malloc, realloc, free);
872 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
873 tt_assert(cp == NULL);
874 evbuffer_validate(evb);
876 /* now we should get the next line back */
877 event_set_mem_functions(malloc, realloc, free);
879 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
880 tt_line_eq("two line");
882 evbuffer_validate(evb);
887 evbuffer_free(evb_tmp);
892 test_evbuffer_iterative(void *ptr)
894 struct evbuffer *buf = evbuffer_new();
895 const char *abc = "abcdefghijklmnopqrstvuwxyzabcdefghijklmnopqrstvuwxyzabcdefghijklmnopqrstvuwxyzabcdefghijklmnopqrstvuwxyz";
896 unsigned i, j, sum, n;
900 for (i = 0; i < 1000; ++i) {
901 for (j = 1; j < strlen(abc); ++j) {
903 evutil_snprintf(format, sizeof(format), "%%%u.%us", j, j);
904 evbuffer_add_printf(buf, format, abc);
906 /* Only check for rep violations every so often.
907 Walking over the whole list of chains can get
908 pretty expensive as it gets long.
911 evbuffer_validate(buf);
917 evbuffer_validate(buf);
919 tt_uint_op(sum, ==, evbuffer_get_length(buf));
924 evbuffer_get_waste(buf, &a, &w, &u);
926 printf("Allocated: %u.\nWasted: %u.\nUsed: %u.",
927 (unsigned)a, (unsigned)w, (unsigned)u);
928 tt_assert( ((double)w)/a < .125);
936 test_evbuffer_find(void *ptr)
939 const char* test1 = "1234567890\r\n";
940 const char* test2 = "1234567890\r";
941 #define EVBUFFER_INITIAL_LENGTH 256
942 char test3[EVBUFFER_INITIAL_LENGTH];
944 struct evbuffer * buf = evbuffer_new();
946 /* make sure evbuffer_find doesn't match past the end of the buffer */
947 evbuffer_add(buf, (u_char*)test1, strlen(test1));
948 evbuffer_validate(buf);
949 evbuffer_drain(buf, strlen(test1));
950 evbuffer_validate(buf);
951 evbuffer_add(buf, (u_char*)test2, strlen(test2));
952 evbuffer_validate(buf);
953 p = evbuffer_find(buf, (u_char*)"\r\n", 2);
957 * drain the buffer and do another find; in r309 this would
958 * read past the allocated buffer causing a valgrind error.
960 evbuffer_drain(buf, strlen(test2));
961 evbuffer_validate(buf);
962 for (i = 0; i < EVBUFFER_INITIAL_LENGTH; ++i)
964 test3[EVBUFFER_INITIAL_LENGTH - 1] = 'x';
965 evbuffer_add(buf, (u_char *)test3, EVBUFFER_INITIAL_LENGTH);
966 evbuffer_validate(buf);
967 p = evbuffer_find(buf, (u_char *)"xy", 2);
970 /* simple test for match at end of allocated buffer */
971 p = evbuffer_find(buf, (u_char *)"ax", 2);
972 tt_assert(p != NULL);
973 tt_want(strncmp((char*)p, "ax", 2) == 0);
981 test_evbuffer_ptr_set(void *ptr)
983 struct evbuffer *buf = evbuffer_new();
984 struct evbuffer_ptr pos;
985 struct evbuffer_iovec v[1];
987 /* create some chains */
988 evbuffer_reserve_space(buf, 5000, v, 1);
990 memset(v[0].iov_base, 1, v[0].iov_len);
991 evbuffer_commit_space(buf, v, 1);
992 evbuffer_validate(buf);
994 evbuffer_reserve_space(buf, 4000, v, 1);
996 memset(v[0].iov_base, 2, v[0].iov_len);
997 evbuffer_commit_space(buf, v, 1);
999 evbuffer_reserve_space(buf, 3000, v, 1);
1000 v[0].iov_len = 3000;
1001 memset(v[0].iov_base, 3, v[0].iov_len);
1002 evbuffer_commit_space(buf, v, 1);
1003 evbuffer_validate(buf);
1005 tt_int_op(evbuffer_get_length(buf), ==, 12000);
1007 tt_assert(evbuffer_ptr_set(buf, &pos, 13000, EVBUFFER_PTR_SET) == -1);
1008 tt_assert(pos.pos == -1);
1009 tt_assert(evbuffer_ptr_set(buf, &pos, 0, EVBUFFER_PTR_SET) == 0);
1010 tt_assert(pos.pos == 0);
1011 tt_assert(evbuffer_ptr_set(buf, &pos, 13000, EVBUFFER_PTR_ADD) == -1);
1013 tt_assert(evbuffer_ptr_set(buf, &pos, 0, EVBUFFER_PTR_SET) == 0);
1014 tt_assert(pos.pos == 0);
1015 tt_assert(evbuffer_ptr_set(buf, &pos, 10000, EVBUFFER_PTR_ADD) == 0);
1016 tt_assert(pos.pos == 10000);
1017 tt_assert(evbuffer_ptr_set(buf, &pos, 1000, EVBUFFER_PTR_ADD) == 0);
1018 tt_assert(pos.pos == 11000);
1019 tt_assert(evbuffer_ptr_set(buf, &pos, 1000, EVBUFFER_PTR_ADD) == -1);
1020 tt_assert(pos.pos == -1);
1028 test_evbuffer_search(void *ptr)
1030 struct evbuffer *buf = evbuffer_new();
1031 struct evbuffer *tmp = evbuffer_new();
1032 struct evbuffer_ptr pos, end;
1034 /* set up our chains */
1035 evbuffer_add_printf(tmp, "hello"); /* 5 chars */
1036 evbuffer_add_buffer(buf, tmp);
1037 evbuffer_add_printf(tmp, "foo"); /* 3 chars */
1038 evbuffer_add_buffer(buf, tmp);
1039 evbuffer_add_printf(tmp, "cat"); /* 3 chars */
1040 evbuffer_add_buffer(buf, tmp);
1041 evbuffer_add_printf(tmp, "attack");
1042 evbuffer_add_buffer(buf, tmp);
1044 pos = evbuffer_search(buf, "attack", 6, NULL);
1045 tt_int_op(pos.pos, ==, 11);
1046 pos = evbuffer_search(buf, "attacker", 8, NULL);
1047 tt_int_op(pos.pos, ==, -1);
1049 /* test continuing search */
1050 pos = evbuffer_search(buf, "oc", 2, NULL);
1051 tt_int_op(pos.pos, ==, 7);
1052 pos = evbuffer_search(buf, "cat", 3, &pos);
1053 tt_int_op(pos.pos, ==, 8);
1054 pos = evbuffer_search(buf, "tacking", 7, &pos);
1055 tt_int_op(pos.pos, ==, -1);
1057 evbuffer_ptr_set(buf, &pos, 5, EVBUFFER_PTR_SET);
1058 pos = evbuffer_search(buf, "foo", 3, &pos);
1059 tt_int_op(pos.pos, ==, 5);
1061 evbuffer_ptr_set(buf, &pos, 2, EVBUFFER_PTR_ADD);
1062 pos = evbuffer_search(buf, "tat", 3, &pos);
1063 tt_int_op(pos.pos, ==, 10);
1065 /* test bounded search. */
1066 /* Set "end" to the first t in "attack". */
1067 evbuffer_ptr_set(buf, &end, 12, EVBUFFER_PTR_SET);
1068 pos = evbuffer_search_range(buf, "foo", 3, NULL, &end);
1069 tt_int_op(pos.pos, ==, 5);
1070 pos = evbuffer_search_range(buf, "foocata", 7, NULL, &end);
1071 tt_int_op(pos.pos, ==, 5);
1072 pos = evbuffer_search_range(buf, "foocatat", 8, NULL, &end);
1073 tt_int_op(pos.pos, ==, -1);
1074 pos = evbuffer_search_range(buf, "ack", 3, NULL, &end);
1075 tt_int_op(pos.pos, ==, -1);
1085 log_change_callback(struct evbuffer *buffer,
1086 const struct evbuffer_cb_info *cbinfo,
1090 size_t old_len = cbinfo->orig_size;
1091 size_t new_len = old_len + cbinfo->n_added - cbinfo->n_deleted;
1092 struct evbuffer *out = arg;
1093 evbuffer_add_printf(out, "%lu->%lu; ", (unsigned long)old_len,
1094 (unsigned long)new_len);
1097 self_draining_callback(struct evbuffer *evbuffer, size_t old_len,
1098 size_t new_len, void *arg)
1100 if (new_len > old_len)
1101 evbuffer_drain(evbuffer, new_len);
1105 test_evbuffer_callbacks(void *ptr)
1107 struct evbuffer *buf = evbuffer_new();
1108 struct evbuffer *buf_out1 = evbuffer_new();
1109 struct evbuffer *buf_out2 = evbuffer_new();
1110 struct evbuffer_cb_entry *cb1, *cb2;
1112 cb1 = evbuffer_add_cb(buf, log_change_callback, buf_out1);
1113 cb2 = evbuffer_add_cb(buf, log_change_callback, buf_out2);
1115 /* Let's run through adding and deleting some stuff from the buffer
1116 * and turning the callbacks on and off and removing them. The callback
1117 * adds a summary of length changes to buf_out1/buf_out2 when called. */
1119 evbuffer_add_printf(buf, "The %d magic words are spotty pudding", 2);
1120 evbuffer_validate(buf);
1121 evbuffer_cb_clear_flags(buf, cb2, EVBUFFER_CB_ENABLED);
1122 evbuffer_drain(buf, 10); /*36->26*/
1123 evbuffer_validate(buf);
1124 evbuffer_prepend(buf, "Hello", 5);/*26->31*/
1125 evbuffer_cb_set_flags(buf, cb2, EVBUFFER_CB_ENABLED);
1126 evbuffer_add_reference(buf, "Goodbye", 7, NULL, NULL); /*31->38*/
1127 evbuffer_remove_cb_entry(buf, cb1);
1128 evbuffer_validate(buf);
1129 evbuffer_drain(buf, evbuffer_get_length(buf)); /*38->0*/;
1130 tt_assert(-1 == evbuffer_remove_cb(buf, log_change_callback, NULL));
1131 evbuffer_add(buf, "X", 1); /* 0->1 */
1132 tt_assert(!evbuffer_remove_cb(buf, log_change_callback, buf_out2));
1133 evbuffer_validate(buf);
1135 tt_str_op(evbuffer_pullup(buf_out1, -1), ==,
1136 "0->36; 36->26; 26->31; 31->38; ");
1137 tt_str_op(evbuffer_pullup(buf_out2, -1), ==,
1138 "0->36; 31->38; 38->0; 0->1; ");
1139 evbuffer_drain(buf_out1, evbuffer_get_length(buf_out1));
1140 evbuffer_drain(buf_out2, evbuffer_get_length(buf_out2));
1141 /* Let's test the obsolete buffer_setcb function too. */
1142 cb1 = evbuffer_add_cb(buf, log_change_callback, buf_out1);
1143 tt_assert(cb1 != NULL);
1144 cb2 = evbuffer_add_cb(buf, log_change_callback, buf_out2);
1145 tt_assert(cb2 != NULL);
1146 evbuffer_setcb(buf, self_draining_callback, NULL);
1147 evbuffer_add_printf(buf, "This should get drained right away.");
1148 tt_uint_op(evbuffer_get_length(buf), ==, 0);
1149 tt_uint_op(evbuffer_get_length(buf_out1), ==, 0);
1150 tt_uint_op(evbuffer_get_length(buf_out2), ==, 0);
1151 evbuffer_setcb(buf, NULL, NULL);
1152 evbuffer_add_printf(buf, "This will not.");
1153 tt_str_op(evbuffer_pullup(buf, -1), ==, "This will not.");
1154 evbuffer_validate(buf);
1155 evbuffer_drain(buf, evbuffer_get_length(buf));
1156 evbuffer_validate(buf);
1158 /* Now let's try a suspended callback. */
1159 cb1 = evbuffer_add_cb(buf, log_change_callback, buf_out1);
1160 cb2 = evbuffer_add_cb(buf, log_change_callback, buf_out2);
1161 evbuffer_cb_suspend(buf,cb2);
1162 evbuffer_prepend(buf,"Hello world",11); /*0->11*/
1163 evbuffer_validate(buf);
1164 evbuffer_cb_suspend(buf,cb1);
1165 evbuffer_add(buf,"more",4); /* 11->15 */
1166 evbuffer_cb_unsuspend(buf,cb2);
1167 evbuffer_drain(buf, 4); /* 15->11 */
1168 evbuffer_cb_unsuspend(buf,cb1);
1169 evbuffer_drain(buf, evbuffer_get_length(buf)); /* 11->0 */
1171 tt_str_op(evbuffer_pullup(buf_out1, -1), ==,
1172 "0->11; 11->11; 11->0; ");
1173 tt_str_op(evbuffer_pullup(buf_out2, -1), ==,
1174 "0->15; 15->11; 11->0; ");
1181 evbuffer_free(buf_out1);
1183 evbuffer_free(buf_out2);
1186 static int ref_done_cb_called_count = 0;
1187 static void *ref_done_cb_called_with = NULL;
1188 static const void *ref_done_cb_called_with_data = NULL;
1189 static size_t ref_done_cb_called_with_len = 0;
1190 static void ref_done_cb(const void *data, size_t len, void *info)
1192 ++ref_done_cb_called_count;
1193 ref_done_cb_called_with = info;
1194 ref_done_cb_called_with_data = data;
1195 ref_done_cb_called_with_len = len;
1199 test_evbuffer_add_reference(void *ptr)
1201 const char chunk1[] = "If you have found the answer to such a problem";
1202 const char chunk2[] = "you ought to write it up for publication";
1203 /* -- Knuth's "Notes on the Exercises" from TAOCP */
1205 size_t len1 = strlen(chunk1), len2=strlen(chunk2);
1207 struct evbuffer *buf1 = NULL, *buf2 = NULL;
1209 buf1 = evbuffer_new();
1212 evbuffer_add_reference(buf1, chunk1, len1, ref_done_cb, (void*)111);
1213 evbuffer_add(buf1, ", ", 2);
1214 evbuffer_add_reference(buf1, chunk2, len2, ref_done_cb, (void*)222);
1215 tt_int_op(evbuffer_get_length(buf1), ==, len1+len2+2);
1217 /* Make sure we can drain a little from a reference. */
1218 tt_int_op(evbuffer_remove(buf1, tmp, 6), ==, 6);
1219 tt_int_op(memcmp(tmp, "If you", 6), ==, 0);
1220 tt_int_op(evbuffer_remove(buf1, tmp, 5), ==, 5);
1221 tt_int_op(memcmp(tmp, " have", 5), ==, 0);
1223 /* Make sure that prepending does not meddle with immutable data */
1224 tt_int_op(evbuffer_prepend(buf1, "I have ", 7), ==, 0);
1225 tt_int_op(memcmp(chunk1, "If you", 6), ==, 0);
1226 evbuffer_validate(buf1);
1228 /* Make sure that when the chunk is over, the callback is invoked. */
1229 evbuffer_drain(buf1, 7); /* Remove prepended stuff. */
1230 evbuffer_drain(buf1, len1-11-1); /* remove all but one byte of chunk1 */
1231 tt_int_op(ref_done_cb_called_count, ==, 0);
1232 evbuffer_remove(buf1, tmp, 1);
1233 tt_int_op(tmp[0], ==, 'm');
1234 tt_assert(ref_done_cb_called_with == (void*)111);
1235 tt_assert(ref_done_cb_called_with_data == chunk1);
1236 tt_assert(ref_done_cb_called_with_len == len1);
1237 tt_int_op(ref_done_cb_called_count, ==, 1);
1238 evbuffer_validate(buf1);
1240 /* Drain some of the remaining chunk, then add it to another buffer */
1241 evbuffer_drain(buf1, 6); /* Remove the ", you ". */
1242 buf2 = evbuffer_new();
1244 tt_int_op(ref_done_cb_called_count, ==, 1);
1245 evbuffer_add(buf2, "I ", 2);
1247 evbuffer_add_buffer(buf2, buf1);
1248 tt_int_op(ref_done_cb_called_count, ==, 1);
1249 evbuffer_remove(buf2, tmp, 16);
1250 tt_int_op(memcmp("I ought to write", tmp, 16), ==, 0);
1251 evbuffer_drain(buf2, evbuffer_get_length(buf2));
1252 tt_int_op(ref_done_cb_called_count, ==, 2);
1253 tt_assert(ref_done_cb_called_with == (void*)222);
1254 evbuffer_validate(buf2);
1256 /* Now add more stuff to buf1 and make sure that it gets removed on
1258 evbuffer_add(buf1, "You shake and shake the ", 24);
1259 evbuffer_add_reference(buf1, "ketchup bottle", 14, ref_done_cb,
1261 evbuffer_add(buf1, ". Nothing comes and then a lot'll.", 42);
1262 evbuffer_free(buf1);
1264 tt_int_op(ref_done_cb_called_count, ==, 3);
1265 tt_assert(ref_done_cb_called_with == (void*)3333);
1269 evbuffer_free(buf1);
1271 evbuffer_free(buf2);
1274 /* Some cases that we didn't get in test_evbuffer() above, for more coverage. */
1276 test_evbuffer_prepend(void *ptr)
1278 struct evbuffer *buf1 = NULL, *buf2 = NULL;
1282 buf1 = evbuffer_new();
1285 /* Case 0: The evbuffer is entirely empty. */
1286 evbuffer_prepend(buf1, "This string has 29 characters", 29);
1287 evbuffer_validate(buf1);
1289 /* Case 1: Prepend goes entirely in new chunk. */
1290 evbuffer_prepend(buf1, "Short.", 6);
1291 evbuffer_validate(buf1);
1293 /* Case 2: prepend goes entirely in first chunk. */
1294 evbuffer_drain(buf1, 6+11);
1295 evbuffer_prepend(buf1, "it", 2);
1296 evbuffer_validate(buf1);
1297 tt_assert(!memcmp(buf1->first->buffer+buf1->first->misalign,
1300 /* Case 3: prepend is split over multiple chunks. */
1301 evbuffer_prepend(buf1, "It is no longer true to say ", 28);
1302 evbuffer_validate(buf1);
1303 n = evbuffer_remove(buf1, tmp, sizeof(tmp)-1);
1305 tt_str_op(tmp,==,"It is no longer true to say it has 29 characters");
1307 buf2 = evbuffer_new();
1310 /* Case 4: prepend a buffer to an empty buffer. */
1312 evbuffer_add_printf(buf1, "Here is string %d. ", n++);
1313 evbuffer_prepend_buffer(buf2, buf1);
1314 evbuffer_validate(buf2);
1316 /* Case 5: prepend a buffer to a nonempty buffer. */
1317 evbuffer_add_printf(buf1, "Here is string %d. ", n++);
1318 evbuffer_prepend_buffer(buf2, buf1);
1319 evbuffer_validate(buf2);
1320 evbuffer_validate(buf1);
1321 n = evbuffer_remove(buf2, tmp, sizeof(tmp)-1);
1323 tt_str_op(tmp,==,"Here is string 1000. Here is string 999. ");
1327 evbuffer_free(buf1);
1329 evbuffer_free(buf2);
1334 test_evbuffer_peek(void *info)
1336 struct evbuffer *buf = NULL, *tmp_buf = NULL;
1338 struct evbuffer_iovec v[20];
1339 struct evbuffer_ptr ptr;
1341 #define tt_iov_eq(v, s) \
1342 tt_int_op((v)->iov_len, ==, strlen(s)); \
1343 tt_assert(!memcmp((v)->iov_base, (s), strlen(s)))
1345 /* Let's make a very fragmented buffer. */
1346 buf = evbuffer_new();
1347 tmp_buf = evbuffer_new();
1348 for (i = 0; i < 16; ++i) {
1349 evbuffer_add_printf(tmp_buf, "Contents of chunk [%d]\n", i);
1350 evbuffer_add_buffer(buf, tmp_buf);
1353 /* Simple peek: get everything. */
1354 i = evbuffer_peek(buf, -1, NULL, v, 20);
1355 tt_int_op(i, ==, 16); /* we used only 16 chunks. */
1356 tt_iov_eq(&v[0], "Contents of chunk [0]\n");
1357 tt_iov_eq(&v[3], "Contents of chunk [3]\n");
1358 tt_iov_eq(&v[12], "Contents of chunk [12]\n");
1359 tt_iov_eq(&v[15], "Contents of chunk [15]\n");
1361 /* Just get one chunk worth. */
1362 memset(v, 0, sizeof(v));
1363 i = evbuffer_peek(buf, -1, NULL, v, 1);
1364 tt_int_op(i, ==, 1);
1365 tt_iov_eq(&v[0], "Contents of chunk [0]\n");
1366 tt_assert(v[1].iov_base == NULL);
1368 /* Suppose we want at least the first 40 bytes. */
1369 memset(v, 0, sizeof(v));
1370 i = evbuffer_peek(buf, 40, NULL, v, 16);
1371 tt_int_op(i, ==, 2);
1372 tt_iov_eq(&v[0], "Contents of chunk [0]\n");
1373 tt_iov_eq(&v[1], "Contents of chunk [1]\n");
1374 tt_assert(v[2].iov_base == NULL);
1376 /* How many chunks do we need for 100 bytes? */
1377 memset(v, 0, sizeof(v));
1378 i = evbuffer_peek(buf, 100, NULL, NULL, 0);
1379 tt_int_op(i, ==, 5);
1380 tt_assert(v[0].iov_base == NULL);
1382 /* Now we ask for more bytes than we provide chunks for */
1383 memset(v, 0, sizeof(v));
1384 i = evbuffer_peek(buf, 60, NULL, v, 1);
1385 tt_int_op(i, ==, 3);
1386 tt_iov_eq(&v[0], "Contents of chunk [0]\n");
1387 tt_assert(v[1].iov_base == NULL);
1389 /* Now we ask for more bytes than the buffer has. */
1390 memset(v, 0, sizeof(v));
1391 i = evbuffer_peek(buf, 65536, NULL, v, 20);
1392 tt_int_op(i, ==, 16); /* we used only 16 chunks. */
1393 tt_iov_eq(&v[0], "Contents of chunk [0]\n");
1394 tt_iov_eq(&v[3], "Contents of chunk [3]\n");
1395 tt_iov_eq(&v[12], "Contents of chunk [12]\n");
1396 tt_iov_eq(&v[15], "Contents of chunk [15]\n");
1397 tt_assert(v[16].iov_base == NULL);
1399 /* What happens if we try an empty buffer? */
1400 memset(v, 0, sizeof(v));
1401 i = evbuffer_peek(tmp_buf, -1, NULL, v, 20);
1402 tt_int_op(i, ==, 0);
1403 tt_assert(v[0].iov_base == NULL);
1404 memset(v, 0, sizeof(v));
1405 i = evbuffer_peek(tmp_buf, 50, NULL, v, 20);
1406 tt_int_op(i, ==, 0);
1407 tt_assert(v[0].iov_base == NULL);
1409 /* Okay, now time to have fun with pointers. */
1410 memset(v, 0, sizeof(v));
1411 evbuffer_ptr_set(buf, &ptr, 30, EVBUFFER_PTR_SET);
1412 i = evbuffer_peek(buf, 50, &ptr, v, 20);
1413 tt_int_op(i, ==, 3);
1414 tt_iov_eq(&v[0], " of chunk [1]\n");
1415 tt_iov_eq(&v[1], "Contents of chunk [2]\n");
1416 tt_iov_eq(&v[2], "Contents of chunk [3]\n"); /*more than we asked for*/
1418 /* advance to the start of another chain. */
1419 memset(v, 0, sizeof(v));
1420 evbuffer_ptr_set(buf, &ptr, 14, EVBUFFER_PTR_ADD);
1421 i = evbuffer_peek(buf, 44, &ptr, v, 20);
1422 tt_int_op(i, ==, 2);
1423 tt_iov_eq(&v[0], "Contents of chunk [2]\n");
1424 tt_iov_eq(&v[1], "Contents of chunk [3]\n"); /*more than we asked for*/
1430 evbuffer_free(tmp_buf);
1433 /* Check whether evbuffer freezing works right. This is called twice,
1434 once with the argument "start" and once with the argument "end".
1435 When we test "start", we freeze the start of an evbuffer and make sure
1436 that modifying the start of the buffer doesn't work. When we test
1437 "end", we freeze the end of an evbuffer and make sure that modifying
1438 the end of the buffer doesn't work.
1441 test_evbuffer_freeze(void *ptr)
1443 struct evbuffer *buf = NULL, *tmp_buf=NULL;
1444 const char string[] = /* Year's End, Richard Wilbur */
1445 "I've known the wind by water banks to shake\n"
1446 "The late leaves down, which frozen where they fell\n"
1447 "And held in ice as dancers in a spell\n"
1448 "Fluttered all winter long into a lake...";
1449 const int start = !strcmp(ptr, "start");
1454 struct evbuffer_iovec v[1];
1457 tt_str_op(ptr, ==, "end");
1459 buf = evbuffer_new();
1460 tmp_buf = evbuffer_new();
1463 evbuffer_add(buf, string, strlen(string));
1464 evbuffer_freeze(buf, start); /* Freeze the start or the end.*/
1466 #define FREEZE_EQ(a, startcase, endcase) \
1469 tt_int_op((a), ==, (startcase)); \
1471 tt_int_op((a), ==, (endcase)); \
1476 orig_length = evbuffer_get_length(buf);
1478 /* These functions all manipulate the end of buf. */
1479 r = evbuffer_add(buf, "abc", 0);
1480 FREEZE_EQ(r, 0, -1);
1481 r = evbuffer_reserve_space(buf, 10, v, 1);
1482 FREEZE_EQ(r, 1, -1);
1484 memset(v[0].iov_base, 'X', 10);
1487 r = evbuffer_commit_space(buf, v, 1);
1488 FREEZE_EQ(r, 0, -1);
1489 r = evbuffer_add_reference(buf, string, 5, NULL, NULL);
1490 FREEZE_EQ(r, 0, -1);
1491 r = evbuffer_add_printf(buf, "Hello %s", "world");
1492 FREEZE_EQ(r, 11, -1);
1493 /* TODO: test add_buffer, add_file, read */
1496 tt_int_op(orig_length, ==, evbuffer_get_length(buf));
1498 orig_length = evbuffer_get_length(buf);
1500 /* These functions all manipulate the start of buf. */
1501 r = evbuffer_remove(buf, charbuf, 1);
1502 FREEZE_EQ(r, -1, 1);
1503 r = evbuffer_drain(buf, 3);
1504 FREEZE_EQ(r, -1, 0);
1505 r = evbuffer_prepend(buf, "dummy", 5);
1506 FREEZE_EQ(r, -1, 0);
1507 cp = evbuffer_readln(buf, NULL, EVBUFFER_EOL_LF);
1508 FREEZE_EQ(cp==NULL, 1, 0);
1511 /* TODO: Test remove_buffer, add_buffer, write, prepend_buffer */
1514 tt_int_op(orig_length, ==, evbuffer_get_length(buf));
1521 evbuffer_free(tmp_buf);
1525 setup_passthrough(const struct testcase_t *testcase)
1527 return testcase->setup_data;
1530 cleanup_passthrough(const struct testcase_t *testcase, void *ptr)
1536 static const struct testcase_setup_t nil_setup = {
1541 struct testcase_t evbuffer_testcases[] = {
1542 { "evbuffer", test_evbuffer, 0, NULL, NULL },
1543 { "reserve2", test_evbuffer_reserve2, 0, NULL, NULL },
1544 { "reserve_many", test_evbuffer_reserve_many, 0, NULL, NULL },
1545 { "reserve_many2", test_evbuffer_reserve_many, 0, &nil_setup, (void*)"add" },
1546 { "reserve_many3", test_evbuffer_reserve_many, 0, &nil_setup, (void*)"fill" },
1547 { "expand", test_evbuffer_expand, 0, NULL, NULL },
1548 { "reference", test_evbuffer_reference, 0, NULL, NULL },
1549 { "iterative", test_evbuffer_iterative, 0, NULL, NULL },
1550 { "readln", test_evbuffer_readln, TT_NO_LOGS, &basic_setup, NULL },
1551 { "find", test_evbuffer_find, 0, NULL, NULL },
1552 { "ptr_set", test_evbuffer_ptr_set, 0, NULL, NULL },
1553 { "search", test_evbuffer_search, 0, NULL, NULL },
1554 { "callbacks", test_evbuffer_callbacks, 0, NULL, NULL },
1555 { "add_reference", test_evbuffer_add_reference, 0, NULL, NULL },
1556 { "prepend", test_evbuffer_prepend, TT_FORK, NULL, NULL },
1557 { "peek", test_evbuffer_peek, 0, NULL, NULL },
1558 { "freeze_start", test_evbuffer_freeze, 0, &nil_setup, (void*)"start" },
1559 { "freeze_end", test_evbuffer_freeze, 0, &nil_setup, (void*)"end" },
1560 /* TODO: need a temp file implementation for Windows */
1561 { "add_file_sendfile", test_evbuffer_add_file, TT_FORK, &nil_setup,
1562 (void*)"sendfile" },
1563 { "add_file_mmap", test_evbuffer_add_file, TT_FORK, &nil_setup,
1565 { "add_file_linear", test_evbuffer_add_file, TT_FORK, &nil_setup,