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