1 /*
2  * Copyright (c) 2003-2007 Niels Provos <provos@citi.umich.edu>
3  * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
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.
15  *
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.
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 /* Validates that an evbuffer is good. Returns false if it isn't, true if it
65  * is*/
66 static int
_evbuffer_validate(struct evbuffer * buf)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
evbuffer_get_waste(struct evbuffer * buf,size_t * allocatedp,size_t * wastedp,size_t * usedp)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 	/* skip empty at start */
131 	while (chain && chain->off==0) {
132 		++n;
133 		a += chain->buffer_len;
134 		chain = chain->next;
135 	}
136 	/* first nonempty chain: stuff at the end only is wasted. */
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 	/* subsequent nonempty chains */
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 	/* subsequent empty chains */
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
test_evbuffer(void * ptr)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 	/* 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);
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 	/* testing one-vector reserve and commit */
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
no_cleanup(const void * data,size_t datalen,void * extra)288 no_cleanup(const void *data, size_t datalen, void *extra)
289 {
290 }
291 
292 static void
test_evbuffer_remove_buffer_with_empty(void * ptr)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     /* setup the buffers */
303     /* we need more data in src than we will move later */
304     evbuffer_add_reference(src, buf, sizeof(buf), no_cleanup, NULL);
305     evbuffer_add_reference(src, buf, sizeof(buf), no_cleanup, NULL);
306     /* we need one buffer in dst and one empty buffer at the end */
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     /* move three bytes over */
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
test_evbuffer_reserve2(void * ptr)325 test_evbuffer_reserve2(void *ptr)
326 {
327 	/* Test the two-vector cases of reserve/commit. */
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 	/* First chunk will necessarily be one chunk. Use 512 bytes of it.*/
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 	/* Ask for another same-chunk request, in an existing chunk. Use 8
350 	 * bytes of it. */
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 	/* Now ask for a request that will be split. Use only one byte of it,
363 	   though. */
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 	/* Now ask for a request that will be split. Use some of the first
379 	 * part and some of the second. */
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 	/* Now peek to make sure stuff got made how we like. */
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
test_evbuffer_reserve_many(void * ptr)421 test_evbuffer_reserve_many(void *ptr)
422 {
423 	/* This is a glass-box test to handle expanding a buffer with more
424 	 * chunks and reallocating chunks as needed */
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 	/* When reserving the the first chunk, we just allocate it */
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 	/* Make another chunk get added. */
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 	/* And a third chunk. */
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 	/* Now force a reallocation by asking for more space in only 2
479 	 * buffers. */
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
test_evbuffer_expand(void * ptr)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 	/* Make sure that expand() works on an empty buffer */
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 	/* Make sure that expand() works as a no-op when there's enough
518 	 * contiguous space already. */
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 	/* Make sure that expand() can work by moving misaligned data
527 	 * when it makes sense to do so. */
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 	/* add, expand, pull-up: This used to crash libevent. */
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
reference_cb(const void * data,size_t len,void * extra)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
test_evbuffer_reference(void * ptr)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 	/* make sure that we don't write data at the beginning */
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
test_evbuffer_add_file(void * ptr)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 	/* Add a test for a big file. XXXX */
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 	/* Say that it drains to a fd so that we can use sendfile. */
659 	evbuffer_set_flags(src, EVBUFFER_FLAG_DRAINS_TO_FD);
660 
661 #if defined(_EVENT_HAVE_SENDFILE) && defined(__sun__) && defined(__svr4__)
662 	/* We need to use a pair of AF_INET sockets, since Solaris
663 	   doesn't support sendfile() over AF_UNIX. */
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 *
failing_malloc(size_t how_much)707 failing_malloc(size_t how_much)
708 {
709 	errno = ENOMEM;
710 	return NULL;
711 }
712 #endif
713 
714 static void
test_evbuffer_readln(void * ptr)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 	/* Test EOL_ANY. */
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 	/* Test EOL_CRLF */
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 	/* Test CRLF_STRICT */
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 	/* Test LF */
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 	/* Test CRLF_STRICT - across boundaries*/
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 	/* Test memory problem*/
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 	/* the next call to readline should fail */
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 	/* now we should get the next line back */
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
test_evbuffer_search_eol(void * ptr)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
test_evbuffer_iterative(void * ptr)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 			/* Only check for rep violations every so often.
997 			   Walking over the whole list of chains can get
998 			   pretty expensive as it gets long.
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
test_evbuffer_find(void * ptr)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 	/* make sure evbuffer_find doesn't match past the end of the buffer */
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 	 * drain the buffer and do another find; in r309 this would
1050 	 * read past the allocated buffer causing a valgrind error.
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 	/* simple test for match at end of allocated buffer */
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
test_evbuffer_ptr_set(void * ptr)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 	/* create some chains */
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
test_evbuffer_search(void * ptr)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 	/* set up our chains */
1132 	evbuffer_add_printf(tmp, "hello");  /* 5 chars */
1133 	evbuffer_add_buffer(buf, tmp);
1134 	evbuffer_add_printf(tmp, "foo");    /* 3 chars */
1135 	evbuffer_add_buffer(buf, tmp);
1136 	evbuffer_add_printf(tmp, "cat");    /* 3 chars */
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 	/* test continuing search */
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 	/* test bounded search. */
1163 	/* Set "end" to the first t in "attack". */
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
log_change_callback(struct evbuffer * buffer,const struct evbuffer_cb_info * cbinfo,void * arg)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
self_draining_callback(struct evbuffer * evbuffer,size_t old_len,size_t new_len,void * arg)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
test_evbuffer_callbacks(void * ptr)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 	/* Let's run through adding and deleting some stuff from the buffer
1218 	 * and turning the callbacks on and off and removing them.  The callback
1219 	 * adds a summary of length changes to buf_out1/buf_out2 when called. */
1220 	/* size: 0-> 36. */
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); /*36->26*/
1225 	evbuffer_validate(buf);
1226 	evbuffer_prepend(buf, "Hello", 5);/*26->31*/
1227 	evbuffer_cb_set_flags(buf, cb2, EVBUFFER_CB_ENABLED);
1228 	evbuffer_add_reference(buf, "Goodbye", 7, NULL, NULL); /*31->38*/
1229 	evbuffer_remove_cb_entry(buf, cb1);
1230 	evbuffer_validate(buf);
1231 	evbuffer_drain(buf, evbuffer_get_length(buf)); /*38->0*/;
1232 	tt_assert(-1 == evbuffer_remove_cb(buf, log_change_callback, NULL));
1233 	evbuffer_add(buf, "X", 1); /* 0->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 	/* Let's test the obsolete buffer_setcb function too. */
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 	/* Now let's try a suspended callback. */
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); /*0->11*/
1265 	evbuffer_validate(buf);
1266 	evbuffer_cb_suspend(buf,cb1);
1267 	evbuffer_add(buf,"more",4); /* 11->15 */
1268 	evbuffer_cb_unsuspend(buf,cb2);
1269 	evbuffer_drain(buf, 4); /* 15->11 */
1270 	evbuffer_cb_unsuspend(buf,cb1);
1271 	evbuffer_drain(buf, evbuffer_get_length(buf)); /* 11->0 */
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;
ref_done_cb(const void * data,size_t len,void * info)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
test_evbuffer_add_reference(void * ptr)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 			  /* -- Knuth's "Notes on the Exercises" from TAOCP */
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 	/* Make sure we can drain a little from a reference. */
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 	/* Make sure that prepending does not meddle with immutable data */
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 	/* Make sure that when the chunk is over, the callback is invoked. */
1331 	evbuffer_drain(buf1, 7); /* Remove prepended stuff. */
1332 	evbuffer_drain(buf1, len1-11-1); /* remove all but one byte of chunk1 */
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 	/* Drain some of the remaining chunk, then add it to another buffer */
1343 	evbuffer_drain(buf1, 6); /* Remove the ", you ". */
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 	/* Now add more stuff to buf1 and make sure that it gets removed on
1359 	 * free. */
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 /* Some cases that we didn't get in test_evbuffer() above, for more coverage. */
1377 static void
test_evbuffer_prepend(void * ptr)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 	/* Case 0: The evbuffer is entirely empty. */
1388 	evbuffer_prepend(buf1, "This string has 29 characters", 29);
1389 	evbuffer_validate(buf1);
1390 
1391 	/* Case 1: Prepend goes entirely in new chunk. */
1392 	evbuffer_prepend(buf1, "Short.", 6);
1393 	evbuffer_validate(buf1);
1394 
1395 	/* Case 2: prepend goes entirely in first chunk. */
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 	/* Case 3: prepend is split over multiple chunks. */
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 	/* Case 4: prepend a buffer to an empty buffer. */
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 	/* Case 5: prepend a buffer to a nonempty buffer. */
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
test_evbuffer_peek(void * info)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 	/* Let's make a very fragmented buffer. */
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 	/* How many chunks do we need for everything? */
1456 	i = evbuffer_peek(buf, -1, NULL, NULL, 0);
1457 	tt_int_op(i, ==, 16);
1458 
1459 	/* Simple peek: get everything. */
1460 	i = evbuffer_peek(buf, -1, NULL, v, 20);
1461 	tt_int_op(i, ==, 16); /* we used only 16 chunks. */
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 	/* Just get one chunk worth. */
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 	/* Suppose we want at least the first 40 bytes. */
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 	/* How many chunks do we need for 100 bytes? */
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 	/* Now we ask for more bytes than we provide chunks for */
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 	/* Now we ask for more bytes than the buffer has. */
1496 	memset(v, 0, sizeof(v));
1497 	i = evbuffer_peek(buf, 65536, NULL, v, 20);
1498 	tt_int_op(i, ==, 16); /* we used only 16 chunks. */
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 	/* What happens if we try an empty buffer? */
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 	/* Okay, now time to have fun with pointers. */
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"); /*more than we asked for*/
1523 
1524 	/* advance to the start of another chain. */
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"); /*more than we asked for*/
1531 
1532 end:
1533 	if (buf)
1534 		evbuffer_free(buf);
1535 	if (tmp_buf)
1536 		evbuffer_free(tmp_buf);
1537 }
1538 
1539 /* Check whether evbuffer freezing works right.  This is called twice,
1540    once with the argument "start" and once with the argument "end".
1541    When we test "start", we freeze the start of an evbuffer and make sure
1542    that modifying the start of the buffer doesn't work.  When we test
1543    "end", we freeze the end of an evbuffer and make sure that modifying
1544    the end of the buffer doesn't work.
1545  */
1546 static void
test_evbuffer_freeze(void * ptr)1547 test_evbuffer_freeze(void *ptr)
1548 {
1549 	struct evbuffer *buf = NULL, *tmp_buf=NULL;
1550 	const char string[] = /* Year's End, Richard Wilbur */
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); /* Freeze the start or the end.*/
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 	/* These functions all manipulate the end of buf. */
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 	/* TODO: test add_buffer, add_file, read */
1600 
1601 	if (!start)
1602 		tt_int_op(orig_length, ==, evbuffer_get_length(buf));
1603 
1604 	orig_length = evbuffer_get_length(buf);
1605 
1606 	/* These functions all manipulate the start of buf. */
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 	/* TODO: Test remove_buffer, add_buffer, write, prepend_buffer */
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 *
setup_passthrough(const struct testcase_t * testcase)1631 setup_passthrough(const struct testcase_t *testcase)
1632 {
1633 	return testcase->setup_data;
1634 }
1635 static int
cleanup_passthrough(const struct testcase_t * testcase,void * ptr)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 	/* TODO: need a temp file implementation for Windows */
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 };
1678