• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "util-internal.h"
28 
29 #ifdef _WIN32
30 #include <winsock2.h>
31 #include <windows.h>
32 #endif
33 
34 #include "event2/event-config.h"
35 
36 #include <sys/types.h>
37 #include <sys/stat.h>
38 #ifdef EVENT__HAVE_SYS_TIME_H
39 #include <sys/time.h>
40 #endif
41 #include <sys/queue.h>
42 #ifndef _WIN32
43 #include <sys/socket.h>
44 #include <sys/wait.h>
45 #include <signal.h>
46 #include <unistd.h>
47 #include <netdb.h>
48 #endif
49 #include <stdlib.h>
50 #include <stdio.h>
51 #include <string.h>
52 #include <errno.h>
53 #include <assert.h>
54 
55 #include "event2/event.h"
56 #include "event2/buffer.h"
57 #include "event2/buffer_compat.h"
58 #include "event2/util.h"
59 
60 #include "defer-internal.h"
61 #include "evbuffer-internal.h"
62 #include "log-internal.h"
63 
64 #include "regress.h"
65 
66 #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
67 
68 /* Validates that an evbuffer is good. Returns false if it isn't, true if it
69  * is*/
70 static int
evbuffer_validate_(struct evbuffer * buf)71 evbuffer_validate_(struct evbuffer *buf)
72 {
73 	struct evbuffer_chain *chain;
74 	size_t sum = 0;
75 	int found_last_with_datap = 0;
76 
77 	if (buf->first == NULL) {
78 		tt_assert(buf->last == NULL);
79 		tt_assert(buf->total_len == 0);
80 	}
81 
82 	chain = buf->first;
83 
84 	tt_assert(buf->last_with_datap);
85 	if (buf->last_with_datap == &buf->first)
86 		found_last_with_datap = 1;
87 
88 	while (chain != NULL) {
89 		if (&chain->next == buf->last_with_datap)
90 			found_last_with_datap = 1;
91 		sum += chain->off;
92 		if (chain->next == NULL) {
93 			tt_assert(buf->last == chain);
94 		}
95 		tt_assert(chain->buffer_len >= chain->misalign + chain->off);
96 		chain = chain->next;
97 	}
98 
99 	if (buf->first)
100 		tt_assert(*buf->last_with_datap);
101 
102 	if (*buf->last_with_datap) {
103 		chain = *buf->last_with_datap;
104 		if (chain->off == 0 || buf->total_len == 0) {
105 			tt_assert(chain->off == 0)
106 			tt_assert(chain == buf->first);
107 			tt_assert(buf->total_len == 0);
108 		}
109 		chain = chain->next;
110 		while (chain != NULL) {
111 			tt_assert(chain->off == 0);
112 			chain = chain->next;
113 		}
114 	} else {
115 		tt_assert(buf->last_with_datap == &buf->first);
116 	}
117 	tt_assert(found_last_with_datap);
118 
119 	tt_assert(sum == buf->total_len);
120 	return 1;
121  end:
122 	return 0;
123 }
124 
125 static void
evbuffer_get_waste(struct evbuffer * buf,size_t * allocatedp,size_t * wastedp,size_t * usedp)126 evbuffer_get_waste(struct evbuffer *buf, size_t *allocatedp, size_t *wastedp, size_t *usedp)
127 {
128 	struct evbuffer_chain *chain;
129 	size_t a, w, u;
130 	int n = 0;
131 	u = a = w = 0;
132 
133 	chain = buf->first;
134 	/* skip empty at start */
135 	while (chain && chain->off==0) {
136 		++n;
137 		a += chain->buffer_len;
138 		chain = chain->next;
139 	}
140 	/* first nonempty chain: stuff at the end only is wasted. */
141 	if (chain) {
142 		++n;
143 		a += chain->buffer_len;
144 		u += chain->off;
145 		if (chain->next && chain->next->off)
146 			w += (size_t)(chain->buffer_len - (chain->misalign + chain->off));
147 		chain = chain->next;
148 	}
149 	/* subsequent nonempty chains */
150 	while (chain && chain->off) {
151 		++n;
152 		a += chain->buffer_len;
153 		w += (size_t)chain->misalign;
154 		u += chain->off;
155 		if (chain->next && chain->next->off)
156 			w += (size_t) (chain->buffer_len - (chain->misalign + chain->off));
157 		chain = chain->next;
158 	}
159 	/* subsequent empty chains */
160 	while (chain) {
161 		++n;
162 		a += chain->buffer_len;
163 	}
164 	*allocatedp = a;
165 	*wastedp = w;
166 	*usedp = u;
167 }
168 
169 #define evbuffer_validate(buf)			\
170 	TT_STMT_BEGIN if (!evbuffer_validate_(buf)) TT_DIE(("Buffer format invalid")); TT_STMT_END
171 
172 static void
test_evbuffer(void * ptr)173 test_evbuffer(void *ptr)
174 {
175 	static char buffer[512], *tmp;
176 	struct evbuffer *evb = evbuffer_new();
177 	struct evbuffer *evb_two = evbuffer_new();
178 	size_t sz_tmp;
179 	int i;
180 
181 	evbuffer_validate(evb);
182 	evbuffer_add_printf(evb, "%s/%d", "hello", 1);
183 	evbuffer_validate(evb);
184 
185 	tt_assert(evbuffer_get_length(evb) == 7);
186 	tt_assert(!memcmp((char*)EVBUFFER_DATA(evb), "hello/1", 1));
187 
188 	evbuffer_add_buffer(evb, evb_two);
189 	evbuffer_validate(evb);
190 
191 	evbuffer_drain(evb, strlen("hello/"));
192 	evbuffer_validate(evb);
193 	tt_assert(evbuffer_get_length(evb) == 1);
194 	tt_assert(!memcmp((char*)EVBUFFER_DATA(evb), "1", 1));
195 
196 	evbuffer_add_printf(evb_two, "%s", "/hello");
197 	evbuffer_validate(evb);
198 	evbuffer_add_buffer(evb, evb_two);
199 	evbuffer_validate(evb);
200 
201 	tt_assert(evbuffer_get_length(evb_two) == 0);
202 	tt_assert(evbuffer_get_length(evb) == 7);
203 	tt_assert(!memcmp((char*)EVBUFFER_DATA(evb), "1/hello", 7));
204 
205 	memset(buffer, 0, sizeof(buffer));
206 	evbuffer_add(evb, buffer, sizeof(buffer));
207 	evbuffer_validate(evb);
208 	tt_assert(evbuffer_get_length(evb) == 7 + 512);
209 
210 	tmp = (char *)evbuffer_pullup(evb, 7 + 512);
211 	tt_assert(tmp);
212 	tt_assert(!strncmp(tmp, "1/hello", 7));
213 	tt_assert(!memcmp(tmp + 7, buffer, sizeof(buffer)));
214 	evbuffer_validate(evb);
215 
216 	evbuffer_prepend(evb, "something", 9);
217 	evbuffer_validate(evb);
218 	evbuffer_prepend(evb, "else", 4);
219 	evbuffer_validate(evb);
220 
221 	tmp = (char *)evbuffer_pullup(evb, 4 + 9 + 7);
222 	tt_assert(!strncmp(tmp, "elsesomething1/hello", 4 + 9 + 7));
223 	evbuffer_validate(evb);
224 
225 	evbuffer_drain(evb, -1);
226 	evbuffer_validate(evb);
227 	evbuffer_drain(evb_two, -1);
228 	evbuffer_validate(evb);
229 
230 	for (i = 0; i < 3; ++i) {
231 		evbuffer_add(evb_two, buffer, sizeof(buffer));
232 		evbuffer_validate(evb_two);
233 		evbuffer_add_buffer(evb, evb_two);
234 		evbuffer_validate(evb);
235 		evbuffer_validate(evb_two);
236 	}
237 
238 	tt_assert(evbuffer_get_length(evb_two) == 0);
239 	tt_assert(evbuffer_get_length(evb) == i * sizeof(buffer));
240 
241 	/* test remove buffer */
242 	sz_tmp = (size_t)(sizeof(buffer)*2.5);
243 	evbuffer_remove_buffer(evb, evb_two, sz_tmp);
244 	tt_assert(evbuffer_get_length(evb_two) == sz_tmp);
245 	tt_assert(evbuffer_get_length(evb) == sizeof(buffer) / 2);
246 	evbuffer_validate(evb);
247 
248 	if (memcmp(evbuffer_pullup(
249 			   evb, -1), buffer, sizeof(buffer) / 2) != 0 ||
250 	    memcmp(evbuffer_pullup(
251 			   evb_two, -1), buffer, sizeof(buffer)) != 0)
252 		tt_abort_msg("Pullup did not preserve content");
253 
254 	evbuffer_validate(evb);
255 
256 
257 	/* testing one-vector reserve and commit */
258 	{
259 		struct evbuffer_iovec v[1];
260 		char *buf;
261 		int i, j, r;
262 
263 		for (i = 0; i < 3; ++i) {
264 			r = evbuffer_reserve_space(evb, 10000, v, 1);
265 			tt_int_op(r, ==, 1);
266 			tt_assert(v[0].iov_len >= 10000);
267 			tt_assert(v[0].iov_base != NULL);
268 
269 			evbuffer_validate(evb);
270 			buf = v[0].iov_base;
271 			for (j = 0; j < 10000; ++j) {
272 				buf[j] = j;
273 			}
274 			evbuffer_validate(evb);
275 
276 			tt_int_op(evbuffer_commit_space(evb, v, 1), ==, 0);
277 			evbuffer_validate(evb);
278 
279 			tt_assert(evbuffer_get_length(evb) >= 10000);
280 
281 			evbuffer_drain(evb, j * 5000);
282 			evbuffer_validate(evb);
283 		}
284 	}
285 
286  end:
287 	evbuffer_free(evb);
288 	evbuffer_free(evb_two);
289 }
290 
291 static void
no_cleanup(const void * data,size_t datalen,void * extra)292 no_cleanup(const void *data, size_t datalen, void *extra)
293 {
294 }
295 
296 static void
test_evbuffer_remove_buffer_with_empty(void * ptr)297 test_evbuffer_remove_buffer_with_empty(void *ptr)
298 {
299 	struct evbuffer *src = evbuffer_new();
300 	struct evbuffer *dst = evbuffer_new();
301 	char buf[2] = { 'A', 'A' };
302 
303 	evbuffer_validate(src);
304 	evbuffer_validate(dst);
305 
306 	/* setup the buffers */
307 	/* we need more data in src than we will move later */
308 	evbuffer_add_reference(src, buf, sizeof(buf), no_cleanup, NULL);
309 	evbuffer_add_reference(src, buf, sizeof(buf), no_cleanup, NULL);
310 	/* we need one buffer in dst and one empty buffer at the end */
311 	evbuffer_add(dst, buf, sizeof(buf));
312 	evbuffer_add_reference(dst, buf, 0, no_cleanup, NULL);
313 
314 	evbuffer_validate(src);
315 	evbuffer_validate(dst);
316 
317 	tt_mem_op(evbuffer_pullup(src, -1), ==, "AAAA", 4);
318 	tt_mem_op(evbuffer_pullup(dst, -1), ==, "AA", 2);
319 
320 	/* move three bytes over */
321 	evbuffer_remove_buffer(src, dst, 3);
322 
323 	evbuffer_validate(src);
324 	evbuffer_validate(dst);
325 
326 	tt_mem_op(evbuffer_pullup(src, -1), ==, "A", 1);
327 	tt_mem_op(evbuffer_pullup(dst, -1), ==, "AAAAA", 5);
328 
329  end:
330 	evbuffer_free(src);
331 	evbuffer_free(dst);
332 }
333 
334 static void
test_evbuffer_remove_buffer_with_empty2(void * ptr)335 test_evbuffer_remove_buffer_with_empty2(void *ptr)
336 {
337 	struct evbuffer *src = evbuffer_new();
338 	struct evbuffer *dst = evbuffer_new();
339 	struct evbuffer *buf = evbuffer_new();
340 
341 	evbuffer_add(buf, "foo", 3);
342 	evbuffer_add_reference(buf, "foo", 3, NULL, NULL);
343 
344 	evbuffer_add_reference(src, "foo", 3, NULL, NULL);
345 	evbuffer_add_reference(src, NULL, 0, NULL, NULL);
346 	evbuffer_add_buffer(src, buf);
347 
348 	evbuffer_add(buf, "foo", 3);
349 	evbuffer_add_reference(buf, "foo", 3, NULL, NULL);
350 
351 	evbuffer_add_reference(dst, "foo", 3, NULL, NULL);
352 	evbuffer_add_reference(dst, NULL, 0, NULL, NULL);
353 	evbuffer_add_buffer(dst, buf);
354 
355 	tt_int_op(evbuffer_get_length(src), ==, 9);
356 	tt_int_op(evbuffer_get_length(dst), ==, 9);
357 
358 	evbuffer_validate(src);
359 	evbuffer_validate(dst);
360 
361 	tt_mem_op(evbuffer_pullup(src, -1), ==, "foofoofoo", 9);
362 	tt_mem_op(evbuffer_pullup(dst, -1), ==, "foofoofoo", 9);
363 
364 	evbuffer_remove_buffer(src, dst, 8);
365 
366 	evbuffer_validate(src);
367 	evbuffer_validate(dst);
368 
369 	tt_int_op(evbuffer_get_length(src), ==, 1);
370 	tt_int_op(evbuffer_get_length(dst), ==, 17);
371 
372 	tt_mem_op(evbuffer_pullup(src, -1), ==, "o", 1);
373 	tt_mem_op(evbuffer_pullup(dst, -1), ==, "foofoofoofoofoofo", 17);
374 
375  end:
376 	evbuffer_free(src);
377 	evbuffer_free(dst);
378 	evbuffer_free(buf);
379 }
380 
381 static void
test_evbuffer_remove_buffer_with_empty3(void * ptr)382 test_evbuffer_remove_buffer_with_empty3(void *ptr)
383 {
384 	struct evbuffer *src = evbuffer_new();
385 	struct evbuffer *dst = evbuffer_new();
386 	struct evbuffer *buf = evbuffer_new();
387 
388 	evbuffer_add(buf, "foo", 3);
389 	evbuffer_add_reference(buf, NULL, 0, NULL, NULL);
390 
391 	evbuffer_add_reference(src, "foo", 3, NULL, NULL);
392 	evbuffer_add_reference(src, NULL, 0, NULL, NULL);
393 	evbuffer_prepend_buffer(src, buf);
394 
395 	evbuffer_add(buf, "foo", 3);
396 	evbuffer_add_reference(buf, NULL, 0, NULL, NULL);
397 
398 	evbuffer_add_reference(dst, "foo", 3, NULL, NULL);
399 	evbuffer_add_reference(dst, NULL, 0, NULL, NULL);
400 	evbuffer_prepend_buffer(dst, buf);
401 
402 	tt_int_op(evbuffer_get_length(src), ==, 6);
403 	tt_int_op(evbuffer_get_length(dst), ==, 6);
404 
405 	evbuffer_validate(src);
406 	evbuffer_validate(dst);
407 
408 	tt_mem_op(evbuffer_pullup(src, -1), ==, "foofoo", 6);
409 	tt_mem_op(evbuffer_pullup(dst, -1), ==, "foofoo", 6);
410 
411 	evbuffer_remove_buffer(src, dst, 5);
412 
413 	evbuffer_validate(src);
414 	evbuffer_validate(dst);
415 
416 	tt_int_op(evbuffer_get_length(src), ==, 1);
417 	tt_int_op(evbuffer_get_length(dst), ==, 11);
418 
419 	tt_mem_op(evbuffer_pullup(src, -1), ==, "o", 1);
420 	tt_mem_op(evbuffer_pullup(dst, -1), ==, "foofoofoofo", 11);
421 
422  end:
423 	evbuffer_free(src);
424 	evbuffer_free(dst);
425 	evbuffer_free(buf);
426 }
427 
428 static void
test_evbuffer_pullup_with_empty(void * ptr)429 test_evbuffer_pullup_with_empty(void *ptr)
430 {
431 	struct evbuffer *buf = NULL;
432 
433 	buf = evbuffer_new();
434 	evbuffer_add(buf, "foo", 3);
435 	evbuffer_add_reference(buf, NULL, 0, NULL, NULL);
436 	evbuffer_validate(buf);
437 	tt_int_op(evbuffer_get_length(buf), ==, 3);
438 	tt_mem_op(evbuffer_pullup(buf, -1), ==, "foo", 3);
439 
440 	evbuffer_free(buf);
441 	buf = evbuffer_new();
442 	evbuffer_validate(buf);
443 	tt_int_op(evbuffer_get_length(buf), ==, 0);
444 	tt_int_op(evbuffer_pullup(buf, -1), ==, NULL);
445 
446 	evbuffer_free(buf);
447 	buf = evbuffer_new();
448 	evbuffer_add(buf, "foo", 3);
449 	evbuffer_add_reference(buf, NULL, 0, NULL, NULL);
450 	evbuffer_validate(buf);
451 	tt_mem_op(evbuffer_pullup(buf, 3), ==, "foo", 3);
452 
453  end:
454 	if (buf)
455 		evbuffer_free(buf);
456 }
457 
458 static void
test_evbuffer_remove_buffer_with_empty_front(void * ptr)459 test_evbuffer_remove_buffer_with_empty_front(void *ptr)
460 {
461 	struct evbuffer *buf1 = NULL, *buf2 = NULL;
462 
463 	buf1 = evbuffer_new();
464 	tt_assert(buf1);
465 
466 	buf2 = evbuffer_new();
467 	tt_assert(buf2);
468 
469 	tt_int_op(evbuffer_add_reference(buf1, "foo", 3, NULL, NULL), ==, 0);
470 	tt_int_op(evbuffer_prepend(buf1, "", 0), ==, 0);
471 	tt_int_op(evbuffer_remove_buffer(buf1, buf2, 1), ==, 1);
472 	tt_int_op(evbuffer_add(buf1, "bar", 3), ==, 0);
473 	tt_mem_op(evbuffer_pullup(buf1, -1), ==, "oobar", 5);
474 
475 	evbuffer_validate(buf1);
476 	evbuffer_validate(buf2);
477 
478  end:
479 	if (buf1)
480 		evbuffer_free(buf1);
481 	if (buf2)
482 		evbuffer_free(buf2);
483 }
484 
485 static void
test_evbuffer_remove_buffer_adjust_last_with_datap_with_empty(void * ptr)486 test_evbuffer_remove_buffer_adjust_last_with_datap_with_empty(void *ptr)
487 {
488 	struct evbuffer *buf1 = NULL, *buf2 = NULL;
489 
490 	buf1 = evbuffer_new();
491 	tt_assert(buf1);
492 
493 	buf2 = evbuffer_new();
494 	tt_assert(buf2);
495 
496 	tt_int_op(evbuffer_add(buf1, "aaaaaa", 6), ==, 0);
497 
498 	// buf1: aaaaaab
499 	// buf2:
500 	{
501 		struct evbuffer_iovec iovecs[2];
502 		/** we want two chains, to leave one chain empty */
503 		tt_int_op(evbuffer_reserve_space(buf1, 971, iovecs, 2), ==, 2);
504 		tt_int_op(iovecs[0].iov_len, >=, 1);
505 		tt_int_op(iovecs[1].iov_len, >=, 1);
506 		tt_assert(*(char *)(iovecs[0].iov_base) = 'b');
507 		tt_assert(iovecs[0].iov_len = 1);
508 		tt_int_op(evbuffer_commit_space(buf1, iovecs, 1), ==, 0);
509 	}
510 
511 	// buf1: aaaaaab
512 	// buf2: dddcc
513 	tt_int_op(evbuffer_add(buf2, "cc", 2), ==, 0);
514 	tt_int_op(evbuffer_prepend(buf2, "ddd", 3), ==, 0);
515 
516 	// buf1:
517 	// buf2: aaaaaabdddcc
518 	tt_int_op(evbuffer_prepend_buffer(buf2, buf1), ==, 0);
519 
520 	// buf1: aaaaaabdddcc
521 	// buf2:
522 	tt_int_op(evbuffer_add_buffer(buf1, buf2), ==, 0);
523 
524 	// buf1: c
525 	// buf2: aaaaaabdddc
526 	tt_int_op(evbuffer_remove_buffer(buf1, buf2, 11), ==, 11);
527 
528 	// This fails today, we observe "aaaaaabcddd" instead!
529 	tt_mem_op(evbuffer_pullup(buf2, -1), ==, "aaaaaabdddc", 11);
530 
531 	evbuffer_validate(buf1);
532 	evbuffer_validate(buf2);
533 
534  end:
535 	if (buf1)
536 		evbuffer_free(buf1);
537 	if (buf2)
538 		evbuffer_free(buf2);
539 }
540 
541 static void
test_evbuffer_add_buffer_with_empty(void * ptr)542 test_evbuffer_add_buffer_with_empty(void *ptr)
543 {
544 	struct evbuffer *src = evbuffer_new();
545 	struct evbuffer *dst = evbuffer_new();
546 	struct evbuffer *buf = evbuffer_new();
547 
548 	evbuffer_add(buf, "foo", 3);
549 
550 	evbuffer_add_reference(src, "foo", 3, NULL, NULL);
551 	evbuffer_add_reference(src, NULL, 0, NULL, NULL);
552 	evbuffer_add_buffer(src, buf);
553 
554 	evbuffer_add(buf, "foo", 3);
555 
556 	evbuffer_add_reference(dst, "foo", 3, NULL, NULL);
557 	evbuffer_add_reference(dst, NULL, 0, NULL, NULL);
558 	evbuffer_add_buffer(dst, buf);
559 
560 	tt_int_op(evbuffer_get_length(src), ==, 6);
561 	tt_int_op(evbuffer_get_length(dst), ==, 6);
562 
563 	evbuffer_validate(src);
564 	evbuffer_validate(dst);
565 
566  end:
567 	evbuffer_free(src);
568 	evbuffer_free(dst);
569 	evbuffer_free(buf);
570 }
571 
572 static void
test_evbuffer_add_buffer_with_empty2(void * ptr)573 test_evbuffer_add_buffer_with_empty2(void *ptr)
574 {
575 	struct evbuffer *src = evbuffer_new();
576 	struct evbuffer *dst = evbuffer_new();
577 	struct evbuffer *buf = evbuffer_new();
578 
579 	evbuffer_add(buf, "foo", 3);
580 
581 	evbuffer_add_reference(src, NULL, 0, NULL, NULL);
582 	evbuffer_add_buffer(src, buf);
583 
584 	evbuffer_add(buf, "foo", 3);
585 
586 	evbuffer_add_reference(dst, NULL, 0, NULL, NULL);
587 	evbuffer_add_buffer(dst, buf);
588 
589 	tt_int_op(evbuffer_get_length(src), ==, 3);
590 	tt_int_op(evbuffer_get_length(dst), ==, 3);
591 
592 	evbuffer_validate(src);
593 	evbuffer_validate(dst);
594 
595  end:
596 	evbuffer_free(src);
597 	evbuffer_free(dst);
598 	evbuffer_free(buf);
599 }
600 
601 static void
test_evbuffer_reserve2(void * ptr)602 test_evbuffer_reserve2(void *ptr)
603 {
604 	/* Test the two-vector cases of reserve/commit. */
605 	struct evbuffer *buf = evbuffer_new();
606 	int n, i;
607 	struct evbuffer_iovec v[2];
608 	size_t remaining;
609 	char *cp, *cp2;
610 
611 	/* First chunk will necessarily be one chunk. Use 512 bytes of it.*/
612 	n = evbuffer_reserve_space(buf, 1024, v, 2);
613 	tt_int_op(n, ==, 1);
614 	tt_int_op(evbuffer_get_length(buf), ==, 0);
615 	tt_assert(v[0].iov_base != NULL);
616 	tt_int_op(v[0].iov_len, >=, 1024);
617 	memset(v[0].iov_base, 'X', 512);
618 	cp = v[0].iov_base;
619 	remaining = v[0].iov_len - 512;
620 	v[0].iov_len = 512;
621 	evbuffer_validate(buf);
622 	tt_int_op(0, ==, evbuffer_commit_space(buf, v, 1));
623 	tt_int_op(evbuffer_get_length(buf), ==, 512);
624 	evbuffer_validate(buf);
625 
626 	/* Ask for another same-chunk request, in an existing chunk. Use 8
627 	 * bytes of it. */
628 	n = evbuffer_reserve_space(buf, 32, v, 2);
629 	tt_int_op(n, ==, 1);
630 	tt_assert(cp + 512 == v[0].iov_base);
631 	tt_int_op(remaining, ==, v[0].iov_len);
632 	memset(v[0].iov_base, 'Y', 8);
633 	v[0].iov_len = 8;
634 	tt_int_op(0, ==, evbuffer_commit_space(buf, v, 1));
635 	tt_int_op(evbuffer_get_length(buf), ==, 520);
636 	remaining -= 8;
637 	evbuffer_validate(buf);
638 
639 	/* Now ask for a request that will be split. Use only one byte of it,
640 	   though. */
641 	n = evbuffer_reserve_space(buf, remaining+64, v, 2);
642 	tt_int_op(n, ==, 2);
643 	tt_assert(cp + 520 == v[0].iov_base);
644 	tt_int_op(remaining, ==, v[0].iov_len);
645 	tt_assert(v[1].iov_base);
646 	tt_assert(v[1].iov_len >= 64);
647 	cp2 = v[1].iov_base;
648 	memset(v[0].iov_base, 'Z', 1);
649 	v[0].iov_len = 1;
650 	tt_int_op(0, ==, evbuffer_commit_space(buf, v, 1));
651 	tt_int_op(evbuffer_get_length(buf), ==, 521);
652 	remaining -= 1;
653 	evbuffer_validate(buf);
654 
655 	/* Now ask for a request that will be split. Use some of the first
656 	 * part and some of the second. */
657 	n = evbuffer_reserve_space(buf, remaining+64, v, 2);
658 	evbuffer_validate(buf);
659 	tt_int_op(n, ==, 2);
660 	tt_assert(cp + 521 == v[0].iov_base);
661 	tt_int_op(remaining, ==, v[0].iov_len);
662 	tt_assert(v[1].iov_base == cp2);
663 	tt_assert(v[1].iov_len >= 64);
664 	memset(v[0].iov_base, 'W', 400);
665 	v[0].iov_len = 400;
666 	memset(v[1].iov_base, 'x', 60);
667 	v[1].iov_len = 60;
668 	tt_int_op(0, ==, evbuffer_commit_space(buf, v, 2));
669 	tt_int_op(evbuffer_get_length(buf), ==, 981);
670 	evbuffer_validate(buf);
671 
672 	/* Now peek to make sure stuff got made how we like. */
673 	memset(v,0,sizeof(v));
674 	n = evbuffer_peek(buf, -1, NULL, v, 2);
675 	tt_int_op(n, ==, 2);
676 	tt_int_op(v[0].iov_len, ==, 921);
677 	tt_int_op(v[1].iov_len, ==, 60);
678 
679 	cp = v[0].iov_base;
680 	for (i=0; i<512; ++i)
681 		tt_int_op(cp[i], ==, 'X');
682 	for (i=512; i<520; ++i)
683 		tt_int_op(cp[i], ==, 'Y');
684 	for (i=520; i<521; ++i)
685 		tt_int_op(cp[i], ==, 'Z');
686 	for (i=521; i<921; ++i)
687 		tt_int_op(cp[i], ==, 'W');
688 
689 	cp = v[1].iov_base;
690 	for (i=0; i<60; ++i)
691 		tt_int_op(cp[i], ==, 'x');
692 
693 end:
694 	evbuffer_free(buf);
695 }
696 
697 static void
test_evbuffer_reserve_many(void * ptr)698 test_evbuffer_reserve_many(void *ptr)
699 {
700 	/* This is a glass-box test to handle expanding a buffer with more
701 	 * chunks and reallocating chunks as needed */
702 	struct evbuffer *buf = evbuffer_new();
703 	struct evbuffer_iovec v[8];
704 	int n;
705 	size_t sz;
706 	int add_data = ptr && !strcmp(ptr, "add");
707 	int fill_first = ptr && !strcmp(ptr, "fill");
708 	char *cp1, *cp2;
709 
710 	/* When reserving the the first chunk, we just allocate it */
711 	n = evbuffer_reserve_space(buf, 128, v, 2);
712 	evbuffer_validate(buf);
713 	tt_int_op(n, ==, 1);
714 	tt_assert(v[0].iov_len >= 128);
715 	sz = v[0].iov_len;
716 	cp1 = v[0].iov_base;
717 	if (add_data) {
718 		*(char*)v[0].iov_base = 'X';
719 		v[0].iov_len = 1;
720 		n = evbuffer_commit_space(buf, v, 1);
721 		tt_int_op(n, ==, 0);
722 	} else if (fill_first) {
723 		memset(v[0].iov_base, 'X', v[0].iov_len);
724 		n = evbuffer_commit_space(buf, v, 1);
725 		tt_int_op(n, ==, 0);
726 		n = evbuffer_reserve_space(buf, 128, v, 2);
727 		tt_int_op(n, ==, 1);
728 		sz = v[0].iov_len;
729 		tt_assert(v[0].iov_base != cp1);
730 		cp1 = v[0].iov_base;
731 	}
732 
733 	/* Make another chunk get added. */
734 	n = evbuffer_reserve_space(buf, sz+128, v, 2);
735 	evbuffer_validate(buf);
736 	tt_int_op(n, ==, 2);
737 	sz = v[0].iov_len + v[1].iov_len;
738 	tt_int_op(sz, >=, v[0].iov_len+128);
739 	if (add_data) {
740 		tt_assert(v[0].iov_base == cp1 + 1);
741 	} else {
742 		tt_assert(v[0].iov_base == cp1);
743 	}
744 	cp1 = v[0].iov_base;
745 	cp2 = v[1].iov_base;
746 
747 	/* And a third chunk. */
748 	n = evbuffer_reserve_space(buf, sz+128, v, 3);
749 	evbuffer_validate(buf);
750 	tt_int_op(n, ==, 3);
751 	tt_assert(cp1 == v[0].iov_base);
752 	tt_assert(cp2 == v[1].iov_base);
753 	sz = v[0].iov_len + v[1].iov_len + v[2].iov_len;
754 
755 	/* Now force a reallocation by asking for more space in only 2
756 	 * buffers. */
757 	n = evbuffer_reserve_space(buf, sz+128, v, 2);
758 	evbuffer_validate(buf);
759 	if (add_data) {
760 		tt_int_op(n, ==, 2);
761 		tt_assert(cp1 == v[0].iov_base);
762 	} else {
763 		tt_int_op(n, ==, 1);
764 	}
765 
766 end:
767 	evbuffer_free(buf);
768 }
769 
770 static void
test_evbuffer_reserve_with_empty(void * ptr)771 test_evbuffer_reserve_with_empty(void *ptr)
772 {
773 	struct evbuffer *buf;
774 	struct evbuffer_iovec v[2];
775 
776 	tt_assert(buf = evbuffer_new());
777 	evbuffer_add(buf, "a", 1);
778 	tt_int_op(evbuffer_reserve_space(buf, 1<<12, v, 2), ==, 2);
779 	v[0].iov_len = 1;
780 	*(char *)v[0].iov_base = 'b';
781 	tt_int_op(evbuffer_commit_space(buf, v, 1), ==, 0);
782 	evbuffer_add(buf, "c", 1);
783 	tt_mem_op(evbuffer_pullup(buf, -1), ==, "abc", 2);
784 
785 	evbuffer_validate(buf);
786 
787  end:
788 	if (buf)
789 		evbuffer_free(buf);
790 }
791 
792 /* regression for evbuffer_expand_fast_() with invalid last_with_datap that has
793  * been left after evbuffer_prepend() with empty chain in it */
794 static void
test_evbuffer_reserve_invalid_last_with_datap(void * ptr)795 test_evbuffer_reserve_invalid_last_with_datap(void *ptr)
796 {
797 	struct evbuffer *buf = NULL;
798 	struct evbuffer_iovec vec[2];
799 	const int nvec = ARRAY_SIZE(vec);
800 	int i, avec;
801 
802 	buf = evbuffer_new();
803 	tt_assert(buf);
804 
805 	/* prepend with an empty chain */
806 	evbuffer_add_reference(buf, "", 0, NULL, NULL);
807 	evbuffer_prepend(buf, "foo", 3);
808 	/* after invalid last_with_datap will create new chain */
809 	evbuffer_add(buf, "", 0);
810 	/* we need to create at least 2 "used" (in evbuffer_expand_fast_()) chains */
811 	tt_int_op(avec = evbuffer_reserve_space(buf, 1<<12, vec, nvec), >=, 1);
812 	for (i = 0; i < avec; ++i)
813 		vec[i].iov_len = 0;
814 	tt_int_op(evbuffer_commit_space(buf, vec, avec), ==, 0);
815 
816 	/* and an actual problem, that triggers an assert(chain == buf->first) in
817 	 * evbuffer_expand_fast_() */
818 	tt_int_op(evbuffer_reserve_space(buf, 1<<13, vec, nvec), >=, 1);
819 
820 	evbuffer_validate(buf);
821 
822 end:
823 	if (buf)
824 		evbuffer_free(buf);
825 }
826 
827 static void
test_evbuffer_expand(void * ptr)828 test_evbuffer_expand(void *ptr)
829 {
830 	char data[4096];
831 	struct evbuffer *buf;
832 	size_t a,w,u;
833 	void *buffer;
834 
835 	memset(data, 'X', sizeof(data));
836 
837 	/* Make sure that expand() works on an empty buffer */
838 	buf = evbuffer_new();
839 	tt_int_op(evbuffer_expand(buf, 20000), ==, 0);
840 	evbuffer_validate(buf);
841 	a=w=u=0;
842 	evbuffer_get_waste(buf, &a,&w,&u);
843 	tt_assert(w == 0);
844 	tt_assert(u == 0);
845 	tt_assert(a >= 20000);
846 	tt_assert(buf->first);
847 	tt_assert(buf->first == buf->last);
848 	tt_assert(buf->first->off == 0);
849 	tt_assert(buf->first->buffer_len >= 20000);
850 
851 	/* Make sure that expand() works as a no-op when there's enough
852 	 * contiguous space already. */
853 	buffer = buf->first->buffer;
854 	evbuffer_add(buf, data, 1024);
855 	tt_int_op(evbuffer_expand(buf, 1024), ==, 0);
856 	tt_assert(buf->first->buffer == buffer);
857 	evbuffer_validate(buf);
858 	evbuffer_free(buf);
859 
860 	/* Make sure that expand() can work by moving misaligned data
861 	 * when it makes sense to do so. */
862 	buf = evbuffer_new();
863 	evbuffer_add(buf, data, 400);
864 	{
865 		int n = (int)(buf->first->buffer_len - buf->first->off - 1);
866 		tt_assert(n < (int)sizeof(data));
867 		evbuffer_add(buf, data, n);
868 	}
869 	tt_assert(buf->first == buf->last);
870 	tt_assert(buf->first->off == buf->first->buffer_len - 1);
871 	evbuffer_drain(buf, buf->first->off - 1);
872 	tt_assert(1 == evbuffer_get_length(buf));
873 	tt_assert(buf->first->misalign > 0);
874 	tt_assert(buf->first->off == 1);
875 	buffer = buf->first->buffer;
876 	tt_assert(evbuffer_expand(buf, 40) == 0);
877 	tt_assert(buf->first == buf->last);
878 	tt_assert(buf->first->off == 1);
879 	tt_assert(buf->first->buffer == buffer);
880 	tt_assert(buf->first->misalign == 0);
881 	evbuffer_validate(buf);
882 	evbuffer_free(buf);
883 
884 	/* add, expand, pull-up: This used to crash libevent. */
885 	buf = evbuffer_new();
886 
887 	evbuffer_add(buf, data, sizeof(data));
888 	evbuffer_add(buf, data, sizeof(data));
889 	evbuffer_add(buf, data, sizeof(data));
890 
891 	evbuffer_validate(buf);
892 	evbuffer_expand(buf, 1024);
893 	evbuffer_validate(buf);
894 	evbuffer_pullup(buf, -1);
895 	evbuffer_validate(buf);
896 
897 end:
898 	evbuffer_free(buf);
899 }
900 
901 static void
test_evbuffer_expand_overflow(void * ptr)902 test_evbuffer_expand_overflow(void *ptr)
903 {
904 	struct evbuffer *buf;
905 
906 	buf = evbuffer_new();
907 	evbuffer_add(buf, "1", 1);
908 	evbuffer_expand(buf, EVBUFFER_CHAIN_MAX);
909 	evbuffer_validate(buf);
910 
911 	evbuffer_expand(buf, EV_SIZE_MAX);
912 	evbuffer_validate(buf);
913 
914 end:
915 	evbuffer_free(buf);
916 }
917 
918 static void
test_evbuffer_add1(void * ptr)919 test_evbuffer_add1(void *ptr)
920 {
921 	struct evbuffer *buf;
922 	char *str;
923 
924 	buf = evbuffer_new();
925 	evbuffer_add(buf, "1", 1);
926 	evbuffer_validate(buf);
927 	evbuffer_expand(buf, 2048);
928 	evbuffer_validate(buf);
929 	evbuffer_add(buf, "2", 1);
930 	evbuffer_validate(buf);
931 	evbuffer_add_printf(buf, "3");
932 	evbuffer_validate(buf);
933 
934 	tt_assert(evbuffer_get_length(buf) == 3);
935 	str = (char *)evbuffer_pullup(buf, -1);
936 	tt_assert(str[0] == '1');
937 	tt_assert(str[1] == '2');
938 	tt_assert(str[2] == '3');
939 end:
940 	evbuffer_free(buf);
941 }
942 
943 static void
test_evbuffer_add2(void * ptr)944 test_evbuffer_add2(void *ptr)
945 {
946 	struct evbuffer *buf;
947 	static char data[4096];
948 	int data_len = MIN_BUFFER_SIZE-EVBUFFER_CHAIN_SIZE-10;
949 	char *str;
950 	int len;
951 
952 	memset(data, 'P', sizeof(data));
953 	buf = evbuffer_new();
954 	evbuffer_add(buf, data, data_len);
955 	evbuffer_validate(buf);
956 	evbuffer_expand(buf, 100);
957 	evbuffer_validate(buf);
958 	evbuffer_add(buf, "2", 1);
959 	evbuffer_validate(buf);
960 	evbuffer_add_printf(buf, "3");
961 	evbuffer_validate(buf);
962 
963 	len = evbuffer_get_length(buf);
964 	tt_assert(len == data_len+2);
965 	str = (char *)evbuffer_pullup(buf, -1);
966 	tt_assert(str[len-3] == 'P');
967 	tt_assert(str[len-2] == '2');
968 	tt_assert(str[len-1] == '3');
969 end:
970 	evbuffer_free(buf);
971 }
972 
973 static int reference_cb_called;
974 static void
reference_cb(const void * data,size_t len,void * extra)975 reference_cb(const void *data, size_t len, void *extra)
976 {
977 	tt_str_op(data, ==, "this is what we add as read-only memory.");
978 	tt_int_op(len, ==, strlen(data));
979 	tt_want(extra == (void *)0xdeadaffe);
980 	++reference_cb_called;
981 end:
982 	;
983 }
984 
985 static void
test_evbuffer_reference(void * ptr)986 test_evbuffer_reference(void *ptr)
987 {
988 	struct evbuffer *src = evbuffer_new();
989 	struct evbuffer *dst = evbuffer_new();
990 	struct evbuffer_iovec v[1];
991 	const char *data = "this is what we add as read-only memory.";
992 	reference_cb_called = 0;
993 
994 	tt_assert(evbuffer_add_reference(src, data, strlen(data),
995 		 reference_cb, (void *)0xdeadaffe) != -1);
996 
997 	evbuffer_reserve_space(dst, strlen(data), v, 1);
998 	tt_assert(evbuffer_remove(src, v[0].iov_base, 10) != -1);
999 
1000 	evbuffer_validate(src);
1001 	evbuffer_validate(dst);
1002 
1003 	/* make sure that we don't write data at the beginning */
1004 	evbuffer_prepend(src, "aaaaa", 5);
1005 	evbuffer_validate(src);
1006 	evbuffer_drain(src, 5);
1007 
1008 	tt_assert(evbuffer_remove(src, ((char*)(v[0].iov_base)) + 10,
1009 		strlen(data) - 10) != -1);
1010 
1011 	v[0].iov_len = strlen(data);
1012 
1013 	evbuffer_commit_space(dst, v, 1);
1014 	evbuffer_validate(src);
1015 	evbuffer_validate(dst);
1016 
1017 	tt_int_op(reference_cb_called, ==, 1);
1018 
1019 	tt_assert(!memcmp(evbuffer_pullup(dst, strlen(data)),
1020 			  data, strlen(data)));
1021 	evbuffer_validate(dst);
1022 
1023  end:
1024 	evbuffer_free(dst);
1025 	evbuffer_free(src);
1026 }
1027 
1028 static void
test_evbuffer_reference2(void * ptr)1029 test_evbuffer_reference2(void *ptr)
1030 {
1031 	struct evbuffer *buf;
1032 	static char data[4096];
1033 	int data_len = MIN_BUFFER_SIZE-EVBUFFER_CHAIN_SIZE-10;
1034 	char *str;
1035 	int len;
1036 
1037 	memset(data, 'P', sizeof(data));
1038 	buf = evbuffer_new();
1039 	evbuffer_add(buf, data, data_len);
1040 	evbuffer_validate(buf);
1041 	evbuffer_expand(buf, 100);
1042 	evbuffer_validate(buf);
1043 	evbuffer_add_reference(buf, "2", 1, no_cleanup, NULL);
1044 	evbuffer_validate(buf);
1045 	evbuffer_add_printf(buf, "3");
1046 	evbuffer_validate(buf);
1047 
1048 	len = evbuffer_get_length(buf);
1049 	tt_assert(len == data_len+2);
1050 	str = (char *)evbuffer_pullup(buf, -1);
1051 	tt_assert(str[len-3] == 'P');
1052 	tt_assert(str[len-2] == '2');
1053 	tt_assert(str[len-1] == '3');
1054 end:
1055 	evbuffer_free(buf);
1056 }
1057 
1058 static struct event_base *addfile_test_event_base;
1059 static int addfile_test_done_writing;
1060 static int addfile_test_total_written;
1061 static int addfile_test_total_read;
1062 
1063 static void
addfile_test_writecb(evutil_socket_t fd,short what,void * arg)1064 addfile_test_writecb(evutil_socket_t fd, short what, void *arg)
1065 {
1066 	struct evbuffer *b = arg;
1067 	int r;
1068 	evbuffer_validate(b);
1069 	while (evbuffer_get_length(b)) {
1070 		r = evbuffer_write(b, fd);
1071 		if (r > 0) {
1072 			addfile_test_total_written += r;
1073 			TT_BLATHER(("Wrote %d/%d bytes", r, addfile_test_total_written));
1074 		} else {
1075 			int e = evutil_socket_geterror(fd);
1076 			if (EVUTIL_ERR_RW_RETRIABLE(e))
1077 				return;
1078 			tt_fail_perror("write");
1079 			event_base_loopexit(addfile_test_event_base,NULL);
1080 		}
1081 		evbuffer_validate(b);
1082 	}
1083 	addfile_test_done_writing = 1;
1084 	return;
1085 end:
1086 	event_base_loopexit(addfile_test_event_base,NULL);
1087 }
1088 
1089 static void
addfile_test_readcb(evutil_socket_t fd,short what,void * arg)1090 addfile_test_readcb(evutil_socket_t fd, short what, void *arg)
1091 {
1092 	struct evbuffer *b = arg;
1093 	int e, r = 0;
1094 	do {
1095 		r = evbuffer_read(b, fd, 1024);
1096 		if (r > 0) {
1097 			addfile_test_total_read += r;
1098 			TT_BLATHER(("Read %d/%d bytes", r, addfile_test_total_read));
1099 		}
1100 	} while (r > 0);
1101 	if (r < 0) {
1102 		e = evutil_socket_geterror(fd);
1103 		if (! EVUTIL_ERR_RW_RETRIABLE(e)) {
1104 			tt_fail_perror("read");
1105 			event_base_loopexit(addfile_test_event_base,NULL);
1106 		}
1107 	}
1108 	if (addfile_test_done_writing &&
1109 	    addfile_test_total_read >= addfile_test_total_written) {
1110 		event_base_loopexit(addfile_test_event_base,NULL);
1111 	}
1112 }
1113 
1114 static void
test_evbuffer_add_file(void * ptr)1115 test_evbuffer_add_file(void *ptr)
1116 {
1117 	struct basic_test_data *testdata = ptr;
1118 	const char *impl = testdata->setup_data;
1119 	struct evbuffer *src = evbuffer_new(), *dest = evbuffer_new();
1120 	char *tmpfilename = NULL;
1121 	char *data = NULL;
1122 	const char *expect_data;
1123 	size_t datalen, expect_len;
1124 	const char *compare;
1125 	int fd = -1;
1126 	int want_ismapping = -1, want_cansendfile = -1;
1127 	unsigned flags = 0;
1128 	int use_segment = 1, use_bigfile = 0, map_from_offset = 0,
1129 	    view_from_offset = 0;
1130 	struct evbuffer_file_segment *seg = NULL;
1131 	ev_off_t starting_offset = 0, mapping_len = -1;
1132 	ev_off_t segment_offset = 0, segment_len = -1;
1133 	struct event *rev=NULL, *wev=NULL;
1134 	struct event_base *base = testdata->base;
1135 	evutil_socket_t pair[2] = {-1, -1};
1136 	struct evutil_weakrand_state seed = { 123456789U };
1137 
1138 	/* This test is highly parameterized based on substrings of its
1139 	 * argument.  The strings are: */
1140 	tt_assert(impl);
1141 	if (strstr(impl, "nosegment")) {
1142 		/* If nosegment is set, use the older evbuffer_add_file
1143 		 * interface */
1144 		use_segment = 0;
1145 	}
1146 	if (strstr(impl, "bigfile")) {
1147 		/* If bigfile is set, use a 512K file.  Else use a smaller
1148 		 * one. */
1149 		use_bigfile = 1;
1150 	}
1151 	if (strstr(impl, "map_offset")) {
1152 		/* If map_offset is set, we build the file segment starting
1153 		 * from a point other than byte 0 and ending somewhere other
1154 		 * than the last byte.  Otherwise we map the whole thing */
1155 		map_from_offset = 1;
1156 	}
1157 	if (strstr(impl, "offset_in_segment")) {
1158 		/* If offset_in_segment is set, we add a subsection of the
1159 		 * file semgment starting from a point other than byte 0 of
1160 		 * the segment. */
1161 		view_from_offset = 1;
1162 	}
1163 	if (strstr(impl, "sendfile")) {
1164 		/* If sendfile is set, we try to use a sendfile/splice style
1165 		 * backend. */
1166 		flags = EVBUF_FS_DISABLE_MMAP;
1167 		want_cansendfile = 1;
1168 		want_ismapping = 0;
1169 	} else if (strstr(impl, "mmap")) {
1170 		/* If sendfile is set, we try to use a mmap/CreateFileMapping
1171 		 * style backend. */
1172 		flags = EVBUF_FS_DISABLE_SENDFILE;
1173 		want_ismapping = 1;
1174 		want_cansendfile = 0;
1175 	} else if (strstr(impl, "linear")) {
1176 		/* If linear is set, we try to use a read-the-whole-thing
1177 		 * backend. */
1178 		flags = EVBUF_FS_DISABLE_SENDFILE|EVBUF_FS_DISABLE_MMAP;
1179 		want_ismapping = 0;
1180 		want_cansendfile = 0;
1181 	} else if (strstr(impl, "default")) {
1182 		/* The caller doesn't care which backend we use. */
1183 		;
1184 	} else {
1185 		/* The caller must choose a backend. */
1186 		TT_DIE(("Didn't recognize the implementation"));
1187 	}
1188 
1189 	if (use_bigfile) {
1190 		unsigned int i;
1191 		datalen = 1024*512;
1192 		data = malloc(1024*512);
1193 		tt_assert(data);
1194 		for (i = 0; i < datalen; ++i)
1195 			data[i] = (char)evutil_weakrand_(&seed);
1196 	} else {
1197 		data = strdup("here is a relatively small string.");
1198 		tt_assert(data);
1199 		datalen = strlen(data);
1200 	}
1201 
1202 	fd = regress_make_tmpfile(data, datalen, &tmpfilename);
1203 
1204 	if (map_from_offset) {
1205 		starting_offset = datalen/4 + 1;
1206 		mapping_len = datalen / 2 - 1;
1207 		expect_data = data + starting_offset;
1208 		expect_len = mapping_len;
1209 	} else {
1210 		expect_data = data;
1211 		expect_len = datalen;
1212 	}
1213 	if (view_from_offset) {
1214 		tt_assert(use_segment); /* Can't do this with add_file*/
1215 		segment_offset = expect_len / 3;
1216 		segment_len = expect_len / 2;
1217 		expect_data = expect_data + segment_offset;
1218 		expect_len = segment_len;
1219 	}
1220 
1221 	if (use_segment) {
1222 		seg = evbuffer_file_segment_new(fd, starting_offset,
1223 		    mapping_len, flags);
1224 		tt_assert(seg);
1225 		if (want_ismapping >= 0) {
1226 			if (seg->is_mapping != (unsigned)want_ismapping)
1227 				tt_skip();
1228 		}
1229 		if (want_cansendfile >= 0) {
1230 			if (seg->can_sendfile != (unsigned)want_cansendfile)
1231 				tt_skip();
1232 		}
1233 	}
1234 
1235 	/* Say that it drains to a fd so that we can use sendfile. */
1236 	evbuffer_set_flags(src, EVBUFFER_FLAG_DRAINS_TO_FD);
1237 
1238 #if defined(EVENT__HAVE_SENDFILE) && defined(__sun__) && defined(__svr4__)
1239 	/* We need to use a pair of AF_INET sockets, since Solaris
1240 	   doesn't support sendfile() over AF_UNIX. */
1241 	if (evutil_ersatz_socketpair_(AF_INET, SOCK_STREAM, 0, pair) == -1)
1242 		tt_abort_msg("ersatz_socketpair failed");
1243 #else
1244 	if (evutil_socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1)
1245 		tt_abort_msg("socketpair failed");
1246 #endif
1247 	evutil_make_socket_nonblocking(pair[0]);
1248 	evutil_make_socket_nonblocking(pair[1]);
1249 
1250 	tt_assert(fd != -1);
1251 
1252 	if (use_segment) {
1253 		tt_assert(evbuffer_add_file_segment(src, seg,
1254 			segment_offset, segment_len)!=-1);
1255 	} else {
1256 		tt_assert(evbuffer_add_file(src, fd, starting_offset,
1257 			mapping_len) != -1);
1258 	}
1259 
1260 	evbuffer_validate(src);
1261 
1262 	addfile_test_event_base = base;
1263 	addfile_test_done_writing = 0;
1264 	addfile_test_total_written = 0;
1265 	addfile_test_total_read = 0;
1266 
1267 	wev = event_new(base, pair[0], EV_WRITE|EV_PERSIST,
1268 	    addfile_test_writecb, src);
1269 	rev = event_new(base, pair[1], EV_READ|EV_PERSIST,
1270 	    addfile_test_readcb, dest);
1271 
1272 	event_add(wev, NULL);
1273 	event_add(rev, NULL);
1274 	event_base_dispatch(base);
1275 
1276 	evbuffer_validate(src);
1277 	evbuffer_validate(dest);
1278 
1279 	tt_assert(addfile_test_done_writing);
1280 	tt_int_op(addfile_test_total_written, ==, expect_len);
1281 	tt_int_op(addfile_test_total_read, ==, expect_len);
1282 
1283 	compare = (char *)evbuffer_pullup(dest, expect_len);
1284 	tt_assert(compare != NULL);
1285 	if (memcmp(compare, expect_data, expect_len)) {
1286 		tt_abort_msg("Data from add_file differs.");
1287 	}
1288 
1289 	evbuffer_validate(dest);
1290  end:
1291 	if (data)
1292 		free(data);
1293 	if (seg)
1294 		evbuffer_file_segment_free(seg);
1295 	if (src)
1296 		evbuffer_free(src);
1297 	if (dest)
1298 		evbuffer_free(dest);
1299 	if (pair[0] >= 0)
1300 		evutil_closesocket(pair[0]);
1301 	if (pair[1] >= 0)
1302 		evutil_closesocket(pair[1]);
1303 	if (wev)
1304 		event_free(wev);
1305 	if (rev)
1306 		event_free(rev);
1307 	if (tmpfilename) {
1308 		unlink(tmpfilename);
1309 		free(tmpfilename);
1310 	}
1311 }
1312 
1313 static int file_segment_cleanup_cb_called_count = 0;
1314 static struct evbuffer_file_segment const* file_segment_cleanup_cb_called_with = NULL;
1315 static int file_segment_cleanup_cb_called_with_flags = 0;
1316 static void* file_segment_cleanup_cb_called_with_arg = NULL;
1317 static void
file_segment_cleanup_cp(struct evbuffer_file_segment const * seg,int flags,void * arg)1318 file_segment_cleanup_cp(struct evbuffer_file_segment const* seg, int flags, void* arg)
1319 {
1320 	++file_segment_cleanup_cb_called_count;
1321 	file_segment_cleanup_cb_called_with = seg;
1322 	file_segment_cleanup_cb_called_with_flags = flags;
1323 	file_segment_cleanup_cb_called_with_arg = arg;
1324 }
1325 
1326 static void
test_evbuffer_file_segment_add_cleanup_cb(void * ptr)1327 test_evbuffer_file_segment_add_cleanup_cb(void* ptr)
1328 {
1329 	char *tmpfilename = NULL;
1330 	int fd = -1;
1331 	struct evbuffer *evb = NULL;
1332 	struct evbuffer_file_segment *seg = NULL, *segptr;
1333 	char const* arg = "token";
1334 
1335 	fd = regress_make_tmpfile("file_segment_test_file", 22, &tmpfilename);
1336 	tt_int_op(fd, >=, 0);
1337 
1338 	evb = evbuffer_new();
1339 	tt_assert(evb);
1340 
1341 	segptr = seg = evbuffer_file_segment_new(fd, 0, -1, 0);
1342 	tt_assert(seg);
1343 
1344 	evbuffer_file_segment_add_cleanup_cb(
1345 	  seg, &file_segment_cleanup_cp, (void*)arg);
1346 
1347 	tt_assert(fd != -1);
1348 
1349 	tt_assert(evbuffer_add_file_segment(evb, seg, 0, -1)!=-1);
1350 
1351 	evbuffer_validate(evb);
1352 
1353 	tt_int_op(file_segment_cleanup_cb_called_count, ==, 0);
1354 	evbuffer_file_segment_free(seg);
1355 	seg = NULL; /* Prevent double-free. */
1356 
1357 	tt_int_op(file_segment_cleanup_cb_called_count, ==, 0);
1358 	evbuffer_free(evb);
1359 	evb = NULL; /* pevent double-free */
1360 
1361 	tt_int_op(file_segment_cleanup_cb_called_count, ==, 1);
1362 	tt_assert(file_segment_cleanup_cb_called_with == segptr);
1363 	tt_assert(file_segment_cleanup_cb_called_with_flags == 0);
1364 	tt_assert(file_segment_cleanup_cb_called_with_arg == (void*)arg);
1365 
1366 end:
1367 	if (evb)
1368 		evbuffer_free(evb);
1369 	if (seg)
1370 		evbuffer_file_segment_free(seg);
1371 	if (tmpfilename) {
1372 		unlink(tmpfilename);
1373 		free(tmpfilename);
1374 	}
1375 }
1376 
1377 #ifndef EVENT__DISABLE_MM_REPLACEMENT
1378 static void *
failing_malloc(size_t how_much)1379 failing_malloc(size_t how_much)
1380 {
1381 	errno = ENOMEM;
1382 	return NULL;
1383 }
1384 #endif
1385 
1386 static void
test_evbuffer_readln(void * ptr)1387 test_evbuffer_readln(void *ptr)
1388 {
1389 	struct evbuffer *evb = evbuffer_new();
1390 	struct evbuffer *evb_tmp = evbuffer_new();
1391 	const char *s;
1392 	char *cp = NULL;
1393 	size_t sz;
1394 
1395 #define tt_line_eq(content)						\
1396 	TT_STMT_BEGIN							\
1397 	if (!cp || sz != strlen(content) || strcmp(cp, content)) {	\
1398 		TT_DIE(("Wanted %s; got %s [%d]", content, cp, (int)sz)); \
1399 	}								\
1400 	TT_STMT_END
1401 
1402 	/* Test EOL_ANY. */
1403 	s = "complex silly newline\r\n\n\r\n\n\rmore\0\n";
1404 	evbuffer_add(evb, s, strlen(s)+2);
1405 	evbuffer_validate(evb);
1406 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_ANY);
1407 	tt_line_eq("complex silly newline");
1408 	free(cp);
1409 	evbuffer_validate(evb);
1410 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_ANY);
1411 	if (!cp || sz != 5 || memcmp(cp, "more\0\0", 6))
1412 		tt_abort_msg("Not as expected");
1413 	tt_uint_op(evbuffer_get_length(evb), ==, 0);
1414 	evbuffer_validate(evb);
1415 	s = "\nno newline";
1416 	evbuffer_add(evb, s, strlen(s));
1417 	free(cp);
1418 	evbuffer_validate(evb);
1419 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_ANY);
1420 	tt_line_eq("");
1421 	free(cp);
1422 	evbuffer_validate(evb);
1423 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_ANY);
1424 	tt_assert(!cp);
1425 	evbuffer_validate(evb);
1426 	evbuffer_drain(evb, evbuffer_get_length(evb));
1427 	tt_assert(evbuffer_get_length(evb) == 0);
1428 	evbuffer_validate(evb);
1429 
1430 	/* Test EOL_CRLF */
1431 	s = "Line with\rin the middle\nLine with good crlf\r\n\nfinal\n";
1432 	evbuffer_add(evb, s, strlen(s));
1433 	evbuffer_validate(evb);
1434 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF);
1435 	tt_line_eq("Line with\rin the middle");
1436 	free(cp);
1437 	evbuffer_validate(evb);
1438 
1439 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF);
1440 	tt_line_eq("Line with good crlf");
1441 	free(cp);
1442 	evbuffer_validate(evb);
1443 
1444 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF);
1445 	tt_line_eq("");
1446 	free(cp);
1447 	evbuffer_validate(evb);
1448 
1449 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF);
1450 	tt_line_eq("final");
1451 	s = "x";
1452 	evbuffer_validate(evb);
1453 	evbuffer_add(evb, s, 1);
1454 	evbuffer_validate(evb);
1455 	free(cp);
1456 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF);
1457 	tt_assert(!cp);
1458 	evbuffer_validate(evb);
1459 
1460 	/* Test CRLF_STRICT */
1461 	s = " and a bad crlf\nand a good one\r\n\r\nMore\r";
1462 	evbuffer_add(evb, s, strlen(s));
1463 	evbuffer_validate(evb);
1464 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
1465 	tt_line_eq("x and a bad crlf\nand a good one");
1466 	free(cp);
1467 	evbuffer_validate(evb);
1468 
1469 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
1470 	tt_line_eq("");
1471 	free(cp);
1472 	evbuffer_validate(evb);
1473 
1474 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
1475 	tt_assert(!cp);
1476 	evbuffer_validate(evb);
1477 	evbuffer_add(evb, "\n", 1);
1478 	evbuffer_validate(evb);
1479 
1480 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
1481 	tt_line_eq("More");
1482 	free(cp);
1483 	tt_assert(evbuffer_get_length(evb) == 0);
1484 	evbuffer_validate(evb);
1485 
1486 	s = "An internal CR\r is not an eol\r\nNor is a lack of one";
1487 	evbuffer_add(evb, s, strlen(s));
1488 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
1489 	tt_line_eq("An internal CR\r is not an eol");
1490 	free(cp);
1491 	evbuffer_validate(evb);
1492 
1493 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
1494 	tt_assert(!cp);
1495 	evbuffer_validate(evb);
1496 
1497 	evbuffer_add(evb, "\r\n", 2);
1498 	evbuffer_validate(evb);
1499 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
1500 	tt_line_eq("Nor is a lack of one");
1501 	free(cp);
1502 	tt_assert(evbuffer_get_length(evb) == 0);
1503 	evbuffer_validate(evb);
1504 
1505 	/* Test LF */
1506 	s = "An\rand a nl\n\nText";
1507 	evbuffer_add(evb, s, strlen(s));
1508 	evbuffer_validate(evb);
1509 
1510 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
1511 	tt_line_eq("An\rand a nl");
1512 	free(cp);
1513 	evbuffer_validate(evb);
1514 
1515 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
1516 	tt_line_eq("");
1517 	free(cp);
1518 	evbuffer_validate(evb);
1519 
1520 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
1521 	tt_assert(!cp);
1522 	free(cp);
1523 	evbuffer_add(evb, "\n", 1);
1524 	evbuffer_validate(evb);
1525 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
1526 	tt_line_eq("Text");
1527 	free(cp);
1528 	evbuffer_validate(evb);
1529 
1530 	/* Test NUL */
1531 	tt_int_op(evbuffer_get_length(evb), ==, 0);
1532 	{
1533 		char x[] =
1534 		    "NUL\n\0\0"
1535 		    "The all-zeros character which may serve\0"
1536 		    "to accomplish time fill\0and media fill";
1537 		/* Add all but the final NUL of x. */
1538 		evbuffer_add(evb, x, sizeof(x)-1);
1539 	}
1540 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_NUL);
1541 	tt_line_eq("NUL\n");
1542 	free(cp);
1543 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_NUL);
1544 	tt_line_eq("");
1545 	free(cp);
1546 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_NUL);
1547 	tt_line_eq("The all-zeros character which may serve");
1548 	free(cp);
1549 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_NUL);
1550 	tt_line_eq("to accomplish time fill");
1551 	free(cp);
1552 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_NUL);
1553 	tt_ptr_op(cp, ==, NULL);
1554 	evbuffer_drain(evb, -1);
1555 
1556 	/* Test CRLF_STRICT - across boundaries*/
1557 	s = " and a bad crlf\nand a good one\r";
1558 	evbuffer_add(evb_tmp, s, strlen(s));
1559 	evbuffer_validate(evb);
1560 	evbuffer_add_buffer(evb, evb_tmp);
1561 	evbuffer_validate(evb);
1562 	s = "\n\r";
1563 	evbuffer_add(evb_tmp, s, strlen(s));
1564 	evbuffer_validate(evb);
1565 	evbuffer_add_buffer(evb, evb_tmp);
1566 	evbuffer_validate(evb);
1567 	s = "\nMore\r";
1568 	evbuffer_add(evb_tmp, s, strlen(s));
1569 	evbuffer_validate(evb);
1570 	evbuffer_add_buffer(evb, evb_tmp);
1571 	evbuffer_validate(evb);
1572 
1573 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
1574 	tt_line_eq(" and a bad crlf\nand a good one");
1575 	free(cp);
1576 	evbuffer_validate(evb);
1577 
1578 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
1579 	tt_line_eq("");
1580 	free(cp);
1581 	evbuffer_validate(evb);
1582 
1583 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
1584 	tt_assert(!cp);
1585 	free(cp);
1586 	evbuffer_validate(evb);
1587 	evbuffer_add(evb, "\n", 1);
1588 	evbuffer_validate(evb);
1589 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
1590 	tt_line_eq("More");
1591 	free(cp); cp = NULL;
1592 	evbuffer_validate(evb);
1593 	tt_assert(evbuffer_get_length(evb) == 0);
1594 
1595 	/* Test memory problem*/
1596 	s = "one line\ntwo line\nblue line";
1597 	evbuffer_add(evb_tmp, s, strlen(s));
1598 	evbuffer_validate(evb);
1599 	evbuffer_add_buffer(evb, evb_tmp);
1600 	evbuffer_validate(evb);
1601 
1602 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
1603 	tt_line_eq("one line");
1604 	free(cp); cp = NULL;
1605 	evbuffer_validate(evb);
1606 
1607 	/* the next call to readline should fail */
1608 #ifndef EVENT__DISABLE_MM_REPLACEMENT
1609 	event_set_mem_functions(failing_malloc, realloc, free);
1610 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
1611 	tt_assert(cp == NULL);
1612 	evbuffer_validate(evb);
1613 
1614 	/* now we should get the next line back */
1615 	event_set_mem_functions(malloc, realloc, free);
1616 #endif
1617 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
1618 	tt_line_eq("two line");
1619 	free(cp); cp = NULL;
1620 	evbuffer_validate(evb);
1621 
1622  end:
1623 	evbuffer_free(evb);
1624 	evbuffer_free(evb_tmp);
1625 	if (cp) free(cp);
1626 }
1627 
1628 static void
test_evbuffer_search_eol(void * ptr)1629 test_evbuffer_search_eol(void *ptr)
1630 {
1631 	struct evbuffer *buf = evbuffer_new();
1632 	struct evbuffer_ptr ptr1, ptr2;
1633 	const char *s;
1634 	size_t eol_len;
1635 
1636 	s = "string! \r\n\r\nx\n";
1637 	evbuffer_add(buf, s, strlen(s));
1638 	eol_len = -1;
1639 	ptr1 = evbuffer_search_eol(buf, NULL, &eol_len, EVBUFFER_EOL_CRLF);
1640 	tt_int_op(ptr1.pos, ==, 8);
1641 	tt_int_op(eol_len, ==, 2);
1642 
1643 	eol_len = -1;
1644 	ptr2 = evbuffer_search_eol(buf, &ptr1, &eol_len, EVBUFFER_EOL_CRLF);
1645 	tt_int_op(ptr2.pos, ==, 8);
1646 	tt_int_op(eol_len, ==, 2);
1647 
1648 	evbuffer_ptr_set(buf, &ptr1, 1, EVBUFFER_PTR_ADD);
1649 	eol_len = -1;
1650 	ptr2 = evbuffer_search_eol(buf, &ptr1, &eol_len, EVBUFFER_EOL_CRLF);
1651 	tt_int_op(ptr2.pos, ==, 9);
1652 	tt_int_op(eol_len, ==, 1);
1653 
1654 	eol_len = -1;
1655 	ptr2 = evbuffer_search_eol(buf, &ptr1, &eol_len, EVBUFFER_EOL_CRLF_STRICT);
1656 	tt_int_op(ptr2.pos, ==, 10);
1657 	tt_int_op(eol_len, ==, 2);
1658 
1659 	eol_len = -1;
1660 	ptr1 = evbuffer_search_eol(buf, NULL, &eol_len, EVBUFFER_EOL_LF);
1661 	tt_int_op(ptr1.pos, ==, 9);
1662 	tt_int_op(eol_len, ==, 1);
1663 
1664 	eol_len = -1;
1665 	ptr2 = evbuffer_search_eol(buf, &ptr1, &eol_len, EVBUFFER_EOL_LF);
1666 	tt_int_op(ptr2.pos, ==, 9);
1667 	tt_int_op(eol_len, ==, 1);
1668 
1669 	evbuffer_ptr_set(buf, &ptr1, 1, EVBUFFER_PTR_ADD);
1670 	eol_len = -1;
1671 	ptr2 = evbuffer_search_eol(buf, &ptr1, &eol_len, EVBUFFER_EOL_LF);
1672 	tt_int_op(ptr2.pos, ==, 11);
1673 	tt_int_op(eol_len, ==, 1);
1674 
1675 	tt_assert(evbuffer_ptr_set(buf, &ptr1, evbuffer_get_length(buf), EVBUFFER_PTR_SET) == 0);
1676 	eol_len = -1;
1677 	ptr2 = evbuffer_search_eol(buf, &ptr1, &eol_len, EVBUFFER_EOL_LF);
1678 	tt_int_op(ptr2.pos, ==, -1);
1679 	tt_int_op(eol_len, ==, 0);
1680 
1681 end:
1682 	evbuffer_free(buf);
1683 }
1684 
1685 static void
test_evbuffer_iterative(void * ptr)1686 test_evbuffer_iterative(void *ptr)
1687 {
1688 	struct evbuffer *buf = evbuffer_new();
1689 	const char *abc = "abcdefghijklmnopqrstvuwxyzabcdefghijklmnopqrstvuwxyzabcdefghijklmnopqrstvuwxyzabcdefghijklmnopqrstvuwxyz";
1690 	unsigned i, j, sum, n;
1691 
1692 	sum = 0;
1693 	n = 0;
1694 	for (i = 0; i < 1000; ++i) {
1695 		for (j = 1; j < strlen(abc); ++j) {
1696 			char format[32];
1697 			evutil_snprintf(format, sizeof(format), "%%%u.%us", j, j);
1698 			evbuffer_add_printf(buf, format, abc);
1699 
1700 			/* Only check for rep violations every so often.
1701 			   Walking over the whole list of chains can get
1702 			   pretty expensive as it gets long.
1703 			 */
1704 			if ((n % 337) == 0)
1705 				evbuffer_validate(buf);
1706 
1707 			sum += j;
1708 			n++;
1709 		}
1710 	}
1711 	evbuffer_validate(buf);
1712 
1713 	tt_uint_op(sum, ==, evbuffer_get_length(buf));
1714 
1715 	{
1716 		size_t a,w,u;
1717 		a=w=u=0;
1718 		evbuffer_get_waste(buf, &a, &w, &u);
1719 		if (0)
1720 			printf("Allocated: %u.\nWasted: %u.\nUsed: %u.",
1721 			    (unsigned)a, (unsigned)w, (unsigned)u);
1722 		tt_assert( ((double)w)/a < .125);
1723 	}
1724  end:
1725 	evbuffer_free(buf);
1726 
1727 }
1728 
1729 static void
test_evbuffer_find(void * ptr)1730 test_evbuffer_find(void *ptr)
1731 {
1732 	unsigned char* p;
1733 	const char* test1 = "1234567890\r\n";
1734 	const char* test2 = "1234567890\r";
1735 #define EVBUFFER_INITIAL_LENGTH 256
1736 	char test3[EVBUFFER_INITIAL_LENGTH];
1737 	unsigned int i;
1738 	struct evbuffer * buf = evbuffer_new();
1739 
1740 	tt_assert(buf);
1741 
1742 	/* make sure evbuffer_find doesn't match past the end of the buffer */
1743 	evbuffer_add(buf, (unsigned char*)test1, strlen(test1));
1744 	evbuffer_validate(buf);
1745 	evbuffer_drain(buf, strlen(test1));
1746 	evbuffer_validate(buf);
1747 	evbuffer_add(buf, (unsigned char*)test2, strlen(test2));
1748 	evbuffer_validate(buf);
1749 	p = evbuffer_find(buf, (unsigned char*)"\r\n", 2);
1750 	tt_want(p == NULL);
1751 
1752 	/*
1753 	 * drain the buffer and do another find; in r309 this would
1754 	 * read past the allocated buffer causing a valgrind error.
1755 	 */
1756 	evbuffer_drain(buf, strlen(test2));
1757 	evbuffer_validate(buf);
1758 	for (i = 0; i < EVBUFFER_INITIAL_LENGTH; ++i)
1759 		test3[i] = 'a';
1760 	test3[EVBUFFER_INITIAL_LENGTH - 1] = 'x';
1761 	evbuffer_add(buf, (unsigned char *)test3, EVBUFFER_INITIAL_LENGTH);
1762 	evbuffer_validate(buf);
1763 	p = evbuffer_find(buf, (unsigned char *)"xy", 2);
1764 	tt_want(p == NULL);
1765 
1766 	/* simple test for match at end of allocated buffer */
1767 	p = evbuffer_find(buf, (unsigned char *)"ax", 2);
1768 	tt_assert(p != NULL);
1769 	tt_want(strncmp((char*)p, "ax", 2) == 0);
1770 
1771 end:
1772 	if (buf)
1773 		evbuffer_free(buf);
1774 }
1775 
1776 static void
test_evbuffer_ptr_set(void * ptr)1777 test_evbuffer_ptr_set(void *ptr)
1778 {
1779 	struct evbuffer *buf = evbuffer_new();
1780 	struct evbuffer_ptr pos;
1781 	struct evbuffer_iovec v[1];
1782 
1783 	tt_assert(buf);
1784 
1785 	tt_int_op(evbuffer_get_length(buf), ==, 0);
1786 
1787 	tt_assert(evbuffer_ptr_set(buf, &pos, 0, EVBUFFER_PTR_SET) == 0);
1788 	tt_assert(pos.pos == 0);
1789 	tt_assert(evbuffer_ptr_set(buf, &pos, 1, EVBUFFER_PTR_ADD) == -1);
1790 	tt_assert(pos.pos == -1);
1791 	tt_assert(evbuffer_ptr_set(buf, &pos, 1, EVBUFFER_PTR_SET) == -1);
1792 	tt_assert(pos.pos == -1);
1793 
1794 	/* create some chains */
1795 	evbuffer_reserve_space(buf, 5000, v, 1);
1796 	v[0].iov_len = 5000;
1797 	memset(v[0].iov_base, 1, v[0].iov_len);
1798 	evbuffer_commit_space(buf, v, 1);
1799 	evbuffer_validate(buf);
1800 
1801 	evbuffer_reserve_space(buf, 4000, v, 1);
1802 	v[0].iov_len = 4000;
1803 	memset(v[0].iov_base, 2, v[0].iov_len);
1804 	evbuffer_commit_space(buf, v, 1);
1805 
1806 	evbuffer_reserve_space(buf, 3000, v, 1);
1807 	v[0].iov_len = 3000;
1808 	memset(v[0].iov_base, 3, v[0].iov_len);
1809 	evbuffer_commit_space(buf, v, 1);
1810 	evbuffer_validate(buf);
1811 
1812 	tt_int_op(evbuffer_get_length(buf), ==, 12000);
1813 
1814 	tt_assert(evbuffer_ptr_set(buf, &pos, 13000, EVBUFFER_PTR_SET) == -1);
1815 	tt_assert(pos.pos == -1);
1816 	tt_assert(evbuffer_ptr_set(buf, &pos, 0, EVBUFFER_PTR_SET) == 0);
1817 	tt_assert(pos.pos == 0);
1818 	tt_assert(evbuffer_ptr_set(buf, &pos, 13000, EVBUFFER_PTR_ADD) == -1);
1819 
1820 	tt_assert(evbuffer_ptr_set(buf, &pos, 0, EVBUFFER_PTR_SET) == 0);
1821 	tt_assert(pos.pos == 0);
1822 	tt_assert(evbuffer_ptr_set(buf, &pos, 10000, EVBUFFER_PTR_ADD) == 0);
1823 	tt_assert(pos.pos == 10000);
1824 	tt_assert(evbuffer_ptr_set(buf, &pos, 1000, EVBUFFER_PTR_ADD) == 0);
1825 	tt_assert(pos.pos == 11000);
1826 	tt_assert(evbuffer_ptr_set(buf, &pos, 1000, EVBUFFER_PTR_ADD) == 0);
1827 	tt_assert(pos.pos == 12000);
1828 	tt_assert(evbuffer_ptr_set(buf, &pos, 1000, EVBUFFER_PTR_ADD) == -1);
1829 	tt_assert(pos.pos == -1);
1830 
1831 end:
1832 	if (buf)
1833 		evbuffer_free(buf);
1834 }
1835 
1836 static void
test_evbuffer_search(void * ptr)1837 test_evbuffer_search(void *ptr)
1838 {
1839 	struct evbuffer *buf = evbuffer_new();
1840 	struct evbuffer *tmp = evbuffer_new();
1841 	struct evbuffer_ptr pos, end;
1842 
1843 	tt_assert(buf);
1844 	tt_assert(tmp);
1845 
1846 	pos = evbuffer_search(buf, "x", 1, NULL);
1847 	tt_int_op(pos.pos, ==, -1);
1848 	tt_assert(evbuffer_ptr_set(buf, &pos, 0, EVBUFFER_PTR_SET) == 0);
1849 	pos = evbuffer_search(buf, "x", 1, &pos);
1850 	tt_int_op(pos.pos, ==, -1);
1851 	tt_assert(evbuffer_ptr_set(buf, &pos, 0, EVBUFFER_PTR_SET) == 0);
1852 	pos = evbuffer_search_range(buf, "x", 1, &pos, &pos);
1853 	tt_int_op(pos.pos, ==, -1);
1854 	tt_assert(evbuffer_ptr_set(buf, &pos, 0, EVBUFFER_PTR_SET) == 0);
1855 	pos = evbuffer_search_range(buf, "x", 1, &pos, NULL);
1856 	tt_int_op(pos.pos, ==, -1);
1857 
1858 	/* set up our chains */
1859 	evbuffer_add_printf(tmp, "hello");  /* 5 chars */
1860 	evbuffer_add_buffer(buf, tmp);
1861 	evbuffer_add_printf(tmp, "foo");    /* 3 chars */
1862 	evbuffer_add_buffer(buf, tmp);
1863 	evbuffer_add_printf(tmp, "cat");    /* 3 chars */
1864 	evbuffer_add_buffer(buf, tmp);
1865 	evbuffer_add_printf(tmp, "attack");
1866 	evbuffer_add_buffer(buf, tmp);
1867 
1868 	pos = evbuffer_search(buf, "attack", 6, NULL);
1869 	tt_int_op(pos.pos, ==, 11);
1870 	pos = evbuffer_search(buf, "attacker", 8, NULL);
1871 	tt_int_op(pos.pos, ==, -1);
1872 
1873 	/* test continuing search */
1874 	pos = evbuffer_search(buf, "oc", 2, NULL);
1875 	tt_int_op(pos.pos, ==, 7);
1876 	pos = evbuffer_search(buf, "cat", 3, &pos);
1877 	tt_int_op(pos.pos, ==, 8);
1878 	pos = evbuffer_search(buf, "tacking", 7, &pos);
1879 	tt_int_op(pos.pos, ==, -1);
1880 
1881 	evbuffer_ptr_set(buf, &pos, 5, EVBUFFER_PTR_SET);
1882 	pos = evbuffer_search(buf, "foo", 3, &pos);
1883 	tt_int_op(pos.pos, ==, 5);
1884 
1885 	evbuffer_ptr_set(buf, &pos, 2, EVBUFFER_PTR_ADD);
1886 	pos = evbuffer_search(buf, "tat", 3, &pos);
1887 	tt_int_op(pos.pos, ==, 10);
1888 
1889 	/* test bounded search. */
1890 	/* Set "end" to the first t in "attack". */
1891 	evbuffer_ptr_set(buf, &end, 12, EVBUFFER_PTR_SET);
1892 	pos = evbuffer_search_range(buf, "foo", 3, NULL, &end);
1893 	tt_int_op(pos.pos, ==, 5);
1894 	pos = evbuffer_search_range(buf, "foocata", 7, NULL, &end);
1895 	tt_int_op(pos.pos, ==, 5);
1896 	pos = evbuffer_search_range(buf, "foocatat", 8, NULL, &end);
1897 	tt_int_op(pos.pos, ==, -1);
1898 	pos = evbuffer_search_range(buf, "ack", 3, NULL, &end);
1899 	tt_int_op(pos.pos, ==, -1);
1900 
1901 	/* Set "end" after the last byte in the buffer. */
1902 	tt_assert(evbuffer_ptr_set(buf, &end, 17, EVBUFFER_PTR_SET) == 0);
1903 
1904 	pos = evbuffer_search_range(buf, "attack", 6, NULL, &end);
1905 	tt_int_op(pos.pos, ==, 11);
1906 	tt_assert(evbuffer_ptr_set(buf, &pos, 11, EVBUFFER_PTR_SET) == 0);
1907 	pos = evbuffer_search_range(buf, "attack", 6, &pos, &end);
1908 	tt_int_op(pos.pos, ==, 11);
1909 	tt_assert(evbuffer_ptr_set(buf, &pos, 17, EVBUFFER_PTR_SET) == 0);
1910 	pos = evbuffer_search_range(buf, "attack", 6, &pos, &end);
1911 	tt_int_op(pos.pos, ==, -1);
1912 	tt_assert(evbuffer_ptr_set(buf, &pos, 17, EVBUFFER_PTR_SET) == 0);
1913 	pos = evbuffer_search_range(buf, "attack", 6, &pos, NULL);
1914 	tt_int_op(pos.pos, ==, -1);
1915 
1916 end:
1917 	if (buf)
1918 		evbuffer_free(buf);
1919 	if (tmp)
1920 		evbuffer_free(tmp);
1921 }
1922 
1923 static void
log_change_callback(struct evbuffer * buffer,const struct evbuffer_cb_info * cbinfo,void * arg)1924 log_change_callback(struct evbuffer *buffer,
1925     const struct evbuffer_cb_info *cbinfo,
1926     void *arg)
1927 {
1928 
1929 	size_t old_len = cbinfo->orig_size;
1930 	size_t new_len = old_len + cbinfo->n_added - cbinfo->n_deleted;
1931 	struct evbuffer *out = arg;
1932 	evbuffer_add_printf(out, "%lu->%lu; ", (unsigned long)old_len,
1933 			    (unsigned long)new_len);
1934 }
1935 static void
self_draining_callback(struct evbuffer * evbuffer,size_t old_len,size_t new_len,void * arg)1936 self_draining_callback(struct evbuffer *evbuffer, size_t old_len,
1937 		size_t new_len, void *arg)
1938 {
1939 	if (new_len > old_len)
1940 		evbuffer_drain(evbuffer, new_len);
1941 }
1942 
1943 static void
test_evbuffer_callbacks(void * ptr)1944 test_evbuffer_callbacks(void *ptr)
1945 {
1946 	struct evbuffer *buf = evbuffer_new();
1947 	struct evbuffer *buf_out1 = evbuffer_new();
1948 	struct evbuffer *buf_out2 = evbuffer_new();
1949 	struct evbuffer_cb_entry *cb1, *cb2;
1950 
1951 	tt_assert(buf);
1952 	tt_assert(buf_out1);
1953 	tt_assert(buf_out2);
1954 
1955 	cb1 = evbuffer_add_cb(buf, log_change_callback, buf_out1);
1956 	cb2 = evbuffer_add_cb(buf, log_change_callback, buf_out2);
1957 
1958 	/* Let's run through adding and deleting some stuff from the buffer
1959 	 * and turning the callbacks on and off and removing them.  The callback
1960 	 * adds a summary of length changes to buf_out1/buf_out2 when called. */
1961 	/* size: 0-> 36. */
1962 	evbuffer_add_printf(buf, "The %d magic words are spotty pudding", 2);
1963 	evbuffer_validate(buf);
1964 	evbuffer_cb_clear_flags(buf, cb2, EVBUFFER_CB_ENABLED);
1965 	evbuffer_drain(buf, 10); /*36->26*/
1966 	evbuffer_validate(buf);
1967 	evbuffer_prepend(buf, "Hello", 5);/*26->31*/
1968 	evbuffer_cb_set_flags(buf, cb2, EVBUFFER_CB_ENABLED);
1969 	evbuffer_add_reference(buf, "Goodbye", 7, NULL, NULL); /*31->38*/
1970 	evbuffer_remove_cb_entry(buf, cb1);
1971 	evbuffer_validate(buf);
1972 	evbuffer_drain(buf, evbuffer_get_length(buf)); /*38->0*/;
1973 	tt_assert(-1 == evbuffer_remove_cb(buf, log_change_callback, NULL));
1974 	evbuffer_add(buf, "X", 1); /* 0->1 */
1975 	tt_assert(!evbuffer_remove_cb(buf, log_change_callback, buf_out2));
1976 	evbuffer_validate(buf);
1977 
1978 	tt_str_op((const char *) evbuffer_pullup(buf_out1, -1), ==,
1979 		  "0->36; 36->26; 26->31; 31->38; ");
1980 	tt_str_op((const char *) evbuffer_pullup(buf_out2, -1), ==,
1981 		  "0->36; 31->38; 38->0; 0->1; ");
1982 	evbuffer_drain(buf_out1, evbuffer_get_length(buf_out1));
1983 	evbuffer_drain(buf_out2, evbuffer_get_length(buf_out2));
1984 	/* Let's test the obsolete buffer_setcb function too. */
1985 	cb1 = evbuffer_add_cb(buf, log_change_callback, buf_out1);
1986 	tt_assert(cb1 != NULL);
1987 	cb2 = evbuffer_add_cb(buf, log_change_callback, buf_out2);
1988 	tt_assert(cb2 != NULL);
1989 	tt_int_op(evbuffer_setcb(buf, self_draining_callback, NULL), ==, 0);
1990 	evbuffer_add_printf(buf, "This should get drained right away.");
1991 	tt_uint_op(evbuffer_get_length(buf), ==, 0);
1992 	tt_uint_op(evbuffer_get_length(buf_out1), ==, 0);
1993 	tt_uint_op(evbuffer_get_length(buf_out2), ==, 0);
1994 	tt_int_op(evbuffer_setcb(buf, NULL, NULL), ==, 0);
1995 	evbuffer_add_printf(buf, "This will not.");
1996 	tt_str_op((const char *) evbuffer_pullup(buf, -1), ==, "This will not.");
1997 	evbuffer_validate(buf);
1998 	evbuffer_drain(buf, evbuffer_get_length(buf));
1999 	evbuffer_validate(buf);
2000 #if 0
2001 	/* Now let's try a suspended callback. */
2002 	cb1 = evbuffer_add_cb(buf, log_change_callback, buf_out1);
2003 	cb2 = evbuffer_add_cb(buf, log_change_callback, buf_out2);
2004 	evbuffer_cb_suspend(buf,cb2);
2005 	evbuffer_prepend(buf,"Hello world",11); /*0->11*/
2006 	evbuffer_validate(buf);
2007 	evbuffer_cb_suspend(buf,cb1);
2008 	evbuffer_add(buf,"more",4); /* 11->15 */
2009 	evbuffer_cb_unsuspend(buf,cb2);
2010 	evbuffer_drain(buf, 4); /* 15->11 */
2011 	evbuffer_cb_unsuspend(buf,cb1);
2012 	evbuffer_drain(buf, evbuffer_get_length(buf)); /* 11->0 */
2013 
2014 	tt_str_op(evbuffer_pullup(buf_out1, -1), ==,
2015 		  "0->11; 11->11; 11->0; ");
2016 	tt_str_op(evbuffer_pullup(buf_out2, -1), ==,
2017 		  "0->15; 15->11; 11->0; ");
2018 #endif
2019 
2020 	/* the next call to readline should fail */
2021 #ifndef EVENT__DISABLE_MM_REPLACEMENT
2022 	event_set_mem_functions(failing_malloc, realloc, free);
2023 	tt_int_op(evbuffer_setcb(buf, self_draining_callback, NULL), ==, -1);
2024 	evbuffer_validate(buf);
2025 	event_set_mem_functions(malloc, realloc, free);
2026 #endif
2027 
2028  end:
2029 	if (buf)
2030 		evbuffer_free(buf);
2031 	if (buf_out1)
2032 		evbuffer_free(buf_out1);
2033 	if (buf_out2)
2034 		evbuffer_free(buf_out2);
2035 }
2036 
2037 static int ref_done_cb_called_count = 0;
2038 static void *ref_done_cb_called_with = NULL;
2039 static const void *ref_done_cb_called_with_data = NULL;
2040 static size_t ref_done_cb_called_with_len = 0;
ref_done_cb(const void * data,size_t len,void * info)2041 static void ref_done_cb(const void *data, size_t len, void *info)
2042 {
2043 	++ref_done_cb_called_count;
2044 	ref_done_cb_called_with = info;
2045 	ref_done_cb_called_with_data = data;
2046 	ref_done_cb_called_with_len = len;
2047 }
2048 
2049 static void
test_evbuffer_add_reference(void * ptr)2050 test_evbuffer_add_reference(void *ptr)
2051 {
2052 	const char chunk1[] = "If you have found the answer to such a problem";
2053 	const char chunk2[] = "you ought to write it up for publication";
2054 			  /* -- Knuth's "Notes on the Exercises" from TAOCP */
2055 	char tmp[16];
2056 	size_t len1 = strlen(chunk1), len2=strlen(chunk2);
2057 
2058 	struct evbuffer *buf1 = NULL, *buf2 = NULL;
2059 
2060 	buf1 = evbuffer_new();
2061 	tt_assert(buf1);
2062 
2063 	evbuffer_add_reference(buf1, chunk1, len1, ref_done_cb, (void*)111);
2064 	evbuffer_add(buf1, ", ", 2);
2065 	evbuffer_add_reference(buf1, chunk2, len2, ref_done_cb, (void*)222);
2066 	tt_int_op(evbuffer_get_length(buf1), ==, len1+len2+2);
2067 
2068 	/* Make sure we can drain a little from a reference. */
2069 	tt_int_op(evbuffer_remove(buf1, tmp, 6), ==, 6);
2070 	tt_int_op(memcmp(tmp, "If you", 6), ==, 0);
2071 	tt_int_op(evbuffer_remove(buf1, tmp, 5), ==, 5);
2072 	tt_int_op(memcmp(tmp, " have", 5), ==, 0);
2073 
2074 	/* Make sure that prepending does not meddle with immutable data */
2075 	tt_int_op(evbuffer_prepend(buf1, "I have ", 7), ==, 0);
2076 	tt_int_op(memcmp(chunk1, "If you", 6), ==, 0);
2077 	evbuffer_validate(buf1);
2078 
2079 	/* Make sure that when the chunk is over, the callback is invoked. */
2080 	evbuffer_drain(buf1, 7); /* Remove prepended stuff. */
2081 	evbuffer_drain(buf1, len1-11-1); /* remove all but one byte of chunk1 */
2082 	tt_int_op(ref_done_cb_called_count, ==, 0);
2083 	evbuffer_remove(buf1, tmp, 1);
2084 	tt_int_op(tmp[0], ==, 'm');
2085 	tt_assert(ref_done_cb_called_with == (void*)111);
2086 	tt_assert(ref_done_cb_called_with_data == chunk1);
2087 	tt_assert(ref_done_cb_called_with_len == len1);
2088 	tt_int_op(ref_done_cb_called_count, ==, 1);
2089 	evbuffer_validate(buf1);
2090 
2091 	/* Drain some of the remaining chunk, then add it to another buffer */
2092 	evbuffer_drain(buf1, 6); /* Remove the ", you ". */
2093 	buf2 = evbuffer_new();
2094 	tt_assert(buf2);
2095 	tt_int_op(ref_done_cb_called_count, ==, 1);
2096 	evbuffer_add(buf2, "I ", 2);
2097 
2098 	evbuffer_add_buffer(buf2, buf1);
2099 	tt_int_op(ref_done_cb_called_count, ==, 1);
2100 	evbuffer_remove(buf2, tmp, 16);
2101 	tt_int_op(memcmp("I ought to write", tmp, 16), ==, 0);
2102 	evbuffer_drain(buf2, evbuffer_get_length(buf2));
2103 	tt_int_op(ref_done_cb_called_count, ==, 2);
2104 	tt_assert(ref_done_cb_called_with == (void*)222);
2105 	evbuffer_validate(buf2);
2106 
2107 	/* Now add more stuff to buf1 and make sure that it gets removed on
2108 	 * free. */
2109 	evbuffer_add(buf1, "You shake and shake the ", 24);
2110 	evbuffer_add_reference(buf1, "ketchup bottle", 14, ref_done_cb,
2111 	    (void*)3333);
2112 	evbuffer_add(buf1, ". Nothing comes and then a lot'll.", 35);
2113 	evbuffer_free(buf1);
2114 	buf1 = NULL;
2115 	tt_int_op(ref_done_cb_called_count, ==, 3);
2116 	tt_assert(ref_done_cb_called_with == (void*)3333);
2117 
2118 end:
2119 	if (buf1)
2120 		evbuffer_free(buf1);
2121 	if (buf2)
2122 		evbuffer_free(buf2);
2123 }
2124 
2125 static void
test_evbuffer_multicast(void * ptr)2126 test_evbuffer_multicast(void *ptr)
2127 {
2128 	const char chunk1[] = "If you have found the answer to such a problem";
2129 	const char chunk2[] = "you ought to write it up for publication";
2130 			  /* -- Knuth's "Notes on the Exercises" from TAOCP */
2131 	char tmp[16];
2132 	size_t len1 = strlen(chunk1), len2=strlen(chunk2);
2133 
2134 	struct evbuffer *buf1 = NULL, *buf2 = NULL;
2135 
2136 	buf1 = evbuffer_new();
2137 	tt_assert(buf1);
2138 
2139 	evbuffer_add(buf1, chunk1, len1);
2140 	evbuffer_add(buf1, ", ", 2);
2141 	evbuffer_add(buf1, chunk2, len2);
2142 	tt_int_op(evbuffer_get_length(buf1), ==, len1+len2+2);
2143 
2144 	buf2 = evbuffer_new();
2145 	tt_assert(buf2);
2146 
2147 	tt_int_op(evbuffer_add_buffer_reference(buf2, buf1), ==, 0);
2148 	/* nested references are not allowed */
2149 	tt_int_op(evbuffer_add_buffer_reference(buf2, buf2), ==, -1);
2150 	tt_int_op(evbuffer_add_buffer_reference(buf1, buf2), ==, -1);
2151 
2152 	/* both buffers contain the same amount of data */
2153 	tt_int_op(evbuffer_get_length(buf1), ==, evbuffer_get_length(buf1));
2154 
2155 	/* Make sure we can drain a little from the first buffer. */
2156 	tt_int_op(evbuffer_remove(buf1, tmp, 6), ==, 6);
2157 	tt_int_op(memcmp(tmp, "If you", 6), ==, 0);
2158 	tt_int_op(evbuffer_remove(buf1, tmp, 5), ==, 5);
2159 	tt_int_op(memcmp(tmp, " have", 5), ==, 0);
2160 
2161 	/* Make sure that prepending does not meddle with immutable data */
2162 	tt_int_op(evbuffer_prepend(buf1, "I have ", 7), ==, 0);
2163 	tt_int_op(memcmp(chunk1, "If you", 6), ==, 0);
2164 	evbuffer_validate(buf1);
2165 
2166 	/* Make sure we can drain a little from the second buffer. */
2167 	tt_int_op(evbuffer_remove(buf2, tmp, 6), ==, 6);
2168 	tt_int_op(memcmp(tmp, "If you", 6), ==, 0);
2169 	tt_int_op(evbuffer_remove(buf2, tmp, 5), ==, 5);
2170 	tt_int_op(memcmp(tmp, " have", 5), ==, 0);
2171 
2172 	/* Make sure that prepending does not meddle with immutable data */
2173 	tt_int_op(evbuffer_prepend(buf2, "I have ", 7), ==, 0);
2174 	tt_int_op(memcmp(chunk1, "If you", 6), ==, 0);
2175 	evbuffer_validate(buf2);
2176 
2177 	/* Make sure the data can be read from the second buffer when the first is freed */
2178 	evbuffer_free(buf1);
2179 	buf1 = NULL;
2180 
2181 	tt_int_op(evbuffer_remove(buf2, tmp, 6), ==, 6);
2182 	tt_int_op(memcmp(tmp, "I have", 6), ==, 0);
2183 
2184 	tt_int_op(evbuffer_remove(buf2, tmp, 6), ==, 6);
2185 	tt_int_op(memcmp(tmp, "  foun", 6), ==, 0);
2186 
2187 end:
2188 	if (buf1)
2189 		evbuffer_free(buf1);
2190 	if (buf2)
2191 		evbuffer_free(buf2);
2192 }
2193 
2194 static void
test_evbuffer_multicast_drain(void * ptr)2195 test_evbuffer_multicast_drain(void *ptr)
2196 {
2197 	const char chunk1[] = "If you have found the answer to such a problem";
2198 	const char chunk2[] = "you ought to write it up for publication";
2199 			  /* -- Knuth's "Notes on the Exercises" from TAOCP */
2200 	size_t len1 = strlen(chunk1), len2=strlen(chunk2);
2201 
2202 	struct evbuffer *buf1 = NULL, *buf2 = NULL;
2203 
2204 	buf1 = evbuffer_new();
2205 	tt_assert(buf1);
2206 
2207 	evbuffer_add(buf1, chunk1, len1);
2208 	evbuffer_add(buf1, ", ", 2);
2209 	evbuffer_add(buf1, chunk2, len2);
2210 	tt_int_op(evbuffer_get_length(buf1), ==, len1+len2+2);
2211 
2212 	buf2 = evbuffer_new();
2213 	tt_assert(buf2);
2214 
2215 	tt_int_op(evbuffer_add_buffer_reference(buf2, buf1), ==, 0);
2216 	tt_int_op(evbuffer_get_length(buf2), ==, len1+len2+2);
2217 	tt_int_op(evbuffer_drain(buf1, evbuffer_get_length(buf1)), ==, 0);
2218 	tt_int_op(evbuffer_get_length(buf2), ==, len1+len2+2);
2219 	tt_int_op(evbuffer_drain(buf2, evbuffer_get_length(buf2)), ==, 0);
2220 	evbuffer_validate(buf1);
2221 	evbuffer_validate(buf2);
2222 
2223 end:
2224 	if (buf1)
2225 		evbuffer_free(buf1);
2226 	if (buf2)
2227 		evbuffer_free(buf2);
2228 }
2229 
2230 static void
check_prepend(struct evbuffer * buffer,const struct evbuffer_cb_info * cbinfo,void * arg)2231 check_prepend(struct evbuffer *buffer,
2232     const struct evbuffer_cb_info *cbinfo,
2233     void *arg)
2234 {
2235 	tt_int_op(cbinfo->orig_size, ==, 3);
2236 	tt_int_op(cbinfo->n_added, ==, 8096);
2237 	tt_int_op(cbinfo->n_deleted, ==, 0);
2238 end:
2239 	;
2240 }
2241 /* Some cases that we didn't get in test_evbuffer() above, for more coverage. */
2242 static void
test_evbuffer_prepend(void * ptr)2243 test_evbuffer_prepend(void *ptr)
2244 {
2245 	struct evbuffer *buf1 = NULL, *buf2 = NULL;
2246 	char tmp[128], *buffer = malloc(8096);
2247 	int n;
2248 
2249 	buf1 = evbuffer_new();
2250 	tt_assert(buf1);
2251 
2252 	/* Case 0: The evbuffer is entirely empty. */
2253 	evbuffer_prepend(buf1, "This string has 29 characters", 29);
2254 	evbuffer_validate(buf1);
2255 
2256 	/* Case 1: Prepend goes entirely in new chunk. */
2257 	evbuffer_prepend(buf1, "Short.", 6);
2258 	evbuffer_validate(buf1);
2259 
2260 	/* Case 2: prepend goes entirely in first chunk. */
2261 	evbuffer_drain(buf1, 6+11);
2262 	evbuffer_prepend(buf1, "it", 2);
2263 	evbuffer_validate(buf1);
2264 	tt_assert(!memcmp(buf1->first->buffer+buf1->first->misalign,
2265 		"it has", 6));
2266 
2267 	/* Case 3: prepend is split over multiple chunks. */
2268 	evbuffer_prepend(buf1, "It is no longer true to say ", 28);
2269 	evbuffer_validate(buf1);
2270 	n = evbuffer_remove(buf1, tmp, sizeof(tmp)-1);
2271 	tt_int_op(n, >=, 0);
2272 	tmp[n]='\0';
2273 	tt_str_op(tmp,==,"It is no longer true to say it has 29 characters");
2274 
2275 	buf2 = evbuffer_new();
2276 	tt_assert(buf2);
2277 
2278 	/* Case 4: prepend a buffer to an empty buffer. */
2279 	n = 999;
2280 	evbuffer_add_printf(buf1, "Here is string %d. ", n++);
2281 	evbuffer_prepend_buffer(buf2, buf1);
2282 	evbuffer_validate(buf2);
2283 
2284 	/* Case 5: prepend a buffer to a nonempty buffer. */
2285 	evbuffer_add_printf(buf1, "Here is string %d. ", n++);
2286 	evbuffer_prepend_buffer(buf2, buf1);
2287 	evbuffer_validate(buf2);
2288 	evbuffer_validate(buf1);
2289 	n = evbuffer_remove(buf2, tmp, sizeof(tmp)-1);
2290 	tt_int_op(n, >=, 0);
2291 	tmp[n]='\0';
2292 	tt_str_op(tmp,==,"Here is string 1000. Here is string 999. ");
2293 
2294 	/* Case 5: evbuffer_prepend() will need a new buffer, with callbacks */
2295 	memset(buffer, 'A', 8096);
2296 	evbuffer_free(buf2);
2297 	buf2 = evbuffer_new();
2298 	tt_assert(buf2);
2299 	evbuffer_prepend(buf2, "foo", 3);
2300 	evbuffer_add_cb(buf2, check_prepend, NULL);
2301 	evbuffer_prepend(buf2, buffer, 8096);
2302 	evbuffer_remove_cb(buf2, check_prepend, NULL);
2303 	evbuffer_validate(buf2);
2304 	tt_nstr_op(8096,(char *)evbuffer_pullup(buf2, 8096),==,buffer);
2305 	evbuffer_drain(buf2, 8096);
2306 	tt_nstr_op(3,(char *)evbuffer_pullup(buf2, 3),==,"foo");
2307 	evbuffer_drain(buf2, 3);
2308 
2309 end:
2310 	free(buffer);
2311 	if (buf1)
2312 		evbuffer_free(buf1);
2313 	if (buf2)
2314 		evbuffer_free(buf2);
2315 
2316 }
2317 
2318 static void
test_evbuffer_empty_reference_prepend(void * ptr)2319 test_evbuffer_empty_reference_prepend(void *ptr)
2320 {
2321 	struct evbuffer *buf = NULL;
2322 
2323 	buf = evbuffer_new();
2324 	tt_assert(buf);
2325 
2326 	/** empty chain could leave invalid last_with_datap */
2327 	evbuffer_add_reference(buf, "", 0, NULL, NULL);
2328 	evbuffer_validate(buf);
2329 	evbuffer_prepend(buf, "foo", 3);
2330 
2331 	evbuffer_validate(buf);
2332 	tt_assert(!strncmp((char *)evbuffer_pullup(buf, -1), "foo", 3));
2333 	evbuffer_validate(buf);
2334 
2335 end:
2336 	if (buf)
2337 		evbuffer_free(buf);
2338 }
2339 static void
test_evbuffer_empty_reference_prepend_buffer(void * ptr)2340 test_evbuffer_empty_reference_prepend_buffer(void *ptr)
2341 {
2342 	struct evbuffer *buf1 = NULL, *buf2 = NULL;
2343 
2344 	buf1 = evbuffer_new();
2345 	tt_assert(buf1);
2346 	buf2 = evbuffer_new();
2347 	tt_assert(buf2);
2348 
2349 	/** empty chain could leave invalid last_with_datap */
2350 	evbuffer_add_reference(buf1, "", 0, NULL, NULL);
2351 	evbuffer_validate(buf1);
2352 	evbuffer_add(buf2, "foo", 3);
2353 	evbuffer_validate(buf2);
2354 	evbuffer_prepend_buffer(buf2, buf1);
2355 	evbuffer_validate(buf2);
2356 
2357 	tt_assert(!strncmp((char *)evbuffer_pullup(buf2, -1), "foo", 3));
2358 	evbuffer_validate(buf2);
2359 
2360 	tt_assert(evbuffer_pullup(buf1, -1) == NULL);
2361 	evbuffer_validate(buf2);
2362 
2363 end:
2364 	if (buf1)
2365 		evbuffer_free(buf1);
2366 	if (buf2)
2367 		evbuffer_free(buf2);
2368 }
2369 
2370 static void
test_evbuffer_peek_first_gt(void * info)2371 test_evbuffer_peek_first_gt(void *info)
2372 {
2373 	struct evbuffer *buf = NULL, *tmp_buf = NULL;
2374 	struct evbuffer_ptr ptr;
2375 	struct evbuffer_iovec v[2];
2376 
2377 	buf = evbuffer_new();
2378 	tmp_buf = evbuffer_new();
2379 	evbuffer_add_printf(tmp_buf, "Contents of chunk 100\n");
2380 	evbuffer_add_buffer(buf, tmp_buf);
2381 	evbuffer_add_printf(tmp_buf, "Contents of chunk 1\n");
2382 	evbuffer_add_buffer(buf, tmp_buf);
2383 
2384 	evbuffer_ptr_set(buf, &ptr, 0, EVBUFFER_PTR_SET);
2385 
2386 	/** The only case that matters*/
2387 	tt_int_op(evbuffer_peek(buf, -1, &ptr, NULL, 0), ==, 2);
2388 	/** Just in case */
2389 	tt_int_op(evbuffer_peek(buf, -1, &ptr, v, 2), ==, 2);
2390 
2391 	evbuffer_ptr_set(buf, &ptr, 20, EVBUFFER_PTR_ADD);
2392 	tt_int_op(evbuffer_peek(buf, -1, &ptr, NULL, 0), ==, 2);
2393 	tt_int_op(evbuffer_peek(buf, -1, &ptr, v, 2), ==, 2);
2394 	tt_int_op(evbuffer_peek(buf, 2, &ptr, NULL, 0), ==, 1);
2395 	tt_int_op(evbuffer_peek(buf, 2, &ptr, v, 2), ==, 1);
2396 	tt_int_op(evbuffer_peek(buf, 3, &ptr, NULL, 0), ==, 2);
2397 	tt_int_op(evbuffer_peek(buf, 3, &ptr, v, 2), ==, 2);
2398 
2399 end:
2400 	if (buf)
2401 		evbuffer_free(buf);
2402 	if (tmp_buf)
2403 		evbuffer_free(tmp_buf);
2404 }
2405 
2406 static void
test_evbuffer_peek(void * info)2407 test_evbuffer_peek(void *info)
2408 {
2409 	struct evbuffer *buf = NULL, *tmp_buf = NULL;
2410 	int i;
2411 	struct evbuffer_iovec v[20];
2412 	struct evbuffer_ptr ptr;
2413 
2414 #define tt_iov_eq(v, s)						\
2415 	tt_int_op((v)->iov_len, ==, strlen(s));			\
2416 	tt_assert(!memcmp((v)->iov_base, (s), strlen(s)))
2417 
2418 	/* Let's make a very fragmented buffer. */
2419 	buf = evbuffer_new();
2420 	tmp_buf = evbuffer_new();
2421 	for (i = 0; i < 16; ++i) {
2422 		evbuffer_add_printf(tmp_buf, "Contents of chunk [%d]\n", i);
2423 		evbuffer_add_buffer(buf, tmp_buf);
2424 	}
2425 
2426 	/* How many chunks do we need for everything? */
2427 	i = evbuffer_peek(buf, -1, NULL, NULL, 0);
2428 	tt_int_op(i, ==, 16);
2429 
2430 	/* Simple peek: get everything. */
2431 	i = evbuffer_peek(buf, -1, NULL, v, 20);
2432 	tt_int_op(i, ==, 16); /* we used only 16 chunks. */
2433 	tt_iov_eq(&v[0], "Contents of chunk [0]\n");
2434 	tt_iov_eq(&v[3], "Contents of chunk [3]\n");
2435 	tt_iov_eq(&v[12], "Contents of chunk [12]\n");
2436 	tt_iov_eq(&v[15], "Contents of chunk [15]\n");
2437 
2438 	/* Just get one chunk worth. */
2439 	memset(v, 0, sizeof(v));
2440 	i = evbuffer_peek(buf, -1, NULL, v, 1);
2441 	tt_int_op(i, ==, 1);
2442 	tt_iov_eq(&v[0], "Contents of chunk [0]\n");
2443 	tt_assert(v[1].iov_base == NULL);
2444 
2445 	/* Suppose we want at least the first 40 bytes. */
2446 	memset(v, 0, sizeof(v));
2447 	i = evbuffer_peek(buf, 40, NULL, v, 16);
2448 	tt_int_op(i, ==, 2);
2449 	tt_iov_eq(&v[0], "Contents of chunk [0]\n");
2450 	tt_iov_eq(&v[1], "Contents of chunk [1]\n");
2451 	tt_assert(v[2].iov_base == NULL);
2452 
2453 	/* How many chunks do we need for 100 bytes? */
2454 	memset(v, 0, sizeof(v));
2455 	i = evbuffer_peek(buf, 100, NULL, NULL, 0);
2456 	tt_int_op(i, ==, 5);
2457 	tt_assert(v[0].iov_base == NULL);
2458 
2459 	/* Now we ask for more bytes than we provide chunks for */
2460 	memset(v, 0, sizeof(v));
2461 	i = evbuffer_peek(buf, 60, NULL, v, 1);
2462 	tt_int_op(i, ==, 3);
2463 	tt_iov_eq(&v[0], "Contents of chunk [0]\n");
2464 	tt_assert(v[1].iov_base == NULL);
2465 
2466 	/* Now we ask for more bytes than the buffer has. */
2467 	memset(v, 0, sizeof(v));
2468 	i = evbuffer_peek(buf, 65536, NULL, v, 20);
2469 	tt_int_op(i, ==, 16); /* we used only 16 chunks. */
2470 	tt_iov_eq(&v[0], "Contents of chunk [0]\n");
2471 	tt_iov_eq(&v[3], "Contents of chunk [3]\n");
2472 	tt_iov_eq(&v[12], "Contents of chunk [12]\n");
2473 	tt_iov_eq(&v[15], "Contents of chunk [15]\n");
2474 	tt_assert(v[16].iov_base == NULL);
2475 
2476 	/* What happens if we try an empty buffer? */
2477 	memset(v, 0, sizeof(v));
2478 	i = evbuffer_peek(tmp_buf, -1, NULL, v, 20);
2479 	tt_int_op(i, ==, 0);
2480 	tt_assert(v[0].iov_base == NULL);
2481 	memset(v, 0, sizeof(v));
2482 	i = evbuffer_peek(tmp_buf, 50, NULL, v, 20);
2483 	tt_int_op(i, ==, 0);
2484 	tt_assert(v[0].iov_base == NULL);
2485 
2486 	/* Okay, now time to have fun with pointers. */
2487 	memset(v, 0, sizeof(v));
2488 	evbuffer_ptr_set(buf, &ptr, 30, EVBUFFER_PTR_SET);
2489 	i = evbuffer_peek(buf, 50, &ptr, v, 20);
2490 	tt_int_op(i, ==, 3);
2491 	tt_iov_eq(&v[0], " of chunk [1]\n");
2492 	tt_iov_eq(&v[1], "Contents of chunk [2]\n");
2493 	tt_iov_eq(&v[2], "Contents of chunk [3]\n"); /*more than we asked for*/
2494 
2495 	/* advance to the start of another chain. */
2496 	memset(v, 0, sizeof(v));
2497 	evbuffer_ptr_set(buf, &ptr, 14, EVBUFFER_PTR_ADD);
2498 	i = evbuffer_peek(buf, 44, &ptr, v, 20);
2499 	tt_int_op(i, ==, 2);
2500 	tt_iov_eq(&v[0], "Contents of chunk [2]\n");
2501 	tt_iov_eq(&v[1], "Contents of chunk [3]\n"); /*more than we asked for*/
2502 
2503 	/* peek at the end of the buffer */
2504 	memset(v, 0, sizeof(v));
2505 	tt_assert(evbuffer_ptr_set(buf, &ptr, evbuffer_get_length(buf), EVBUFFER_PTR_SET) == 0);
2506 	i = evbuffer_peek(buf, 44, &ptr, v, 20);
2507 	tt_int_op(i, ==, 0);
2508 	tt_assert(v[0].iov_base == NULL);
2509 
2510 end:
2511 	if (buf)
2512 		evbuffer_free(buf);
2513 	if (tmp_buf)
2514 		evbuffer_free(tmp_buf);
2515 }
2516 
2517 /* Check whether evbuffer freezing works right.  This is called twice,
2518    once with the argument "start" and once with the argument "end".
2519    When we test "start", we freeze the start of an evbuffer and make sure
2520    that modifying the start of the buffer doesn't work.  When we test
2521    "end", we freeze the end of an evbuffer and make sure that modifying
2522    the end of the buffer doesn't work.
2523  */
2524 static void
test_evbuffer_freeze(void * ptr)2525 test_evbuffer_freeze(void *ptr)
2526 {
2527 	struct basic_test_data *testdata = ptr;
2528 	evutil_socket_t *pair = testdata->pair;
2529 	struct evbuffer *buf = NULL, *buf_two = NULL, *tmp_buf = NULL;
2530 	const char string[] = /* Year's End, Richard Wilbur */
2531 	    "I've known the wind by water banks to shake\n"
2532 	    "The late leaves down, which frozen where they fell\n"
2533 	    "And held in ice as dancers in a spell\n"
2534 	    "Fluttered all winter long into a lake...";
2535 	const int start = !strcmp(testdata->setup_data, "start");
2536 	const char tmpfilecontent[] = "file_freeze_test_file";
2537 	char *cp;
2538 	char charbuf[128];
2539 	char *tmpfilename = NULL;
2540 	int fd = -1;
2541 	int r;
2542 	size_t orig_length, len;
2543 	struct evbuffer_iovec v[1];
2544 
2545 	if (!start)
2546 		tt_str_op(testdata->setup_data, ==, "end");
2547 
2548 	buf = evbuffer_new();
2549 	buf_two = evbuffer_new();
2550 	tmp_buf = evbuffer_new();
2551 	tt_assert(tmp_buf);
2552 
2553 	evbuffer_add(buf, string, strlen(string));
2554 	evbuffer_add(buf_two, "abc", 3);
2555 	evbuffer_add(tmp_buf, "xyz", 3);
2556 	evbuffer_freeze(buf, start); /* Freeze the start or the end.*/
2557 	evbuffer_freeze(buf_two, start);
2558 
2559 #define FREEZE_EQ(a, startcase, endcase)		\
2560 	do {						\
2561 	    if (start) {				\
2562 		    tt_int_op((a), ==, (startcase));	\
2563 	    } else {					\
2564 		    tt_int_op((a), ==, (endcase));	\
2565 	    }						\
2566 	} while (0)
2567 
2568 
2569 	orig_length = evbuffer_get_length(buf);
2570 
2571 	/* These functions all manipulate the end of buf. */
2572 	r = evbuffer_add(buf, "abc", 0);
2573 	FREEZE_EQ(r, 0, -1);
2574 	r = evbuffer_reserve_space(buf, 10, v, 1);
2575 	FREEZE_EQ(r, 1, -1);
2576 	if (r == 1) {
2577 		memset(v[0].iov_base, 'X', 10);
2578 		v[0].iov_len = 10;
2579 	}
2580 	r = evbuffer_commit_space(buf, v, 1);
2581 	FREEZE_EQ(r, 0, -1);
2582 	r = evbuffer_add_reference(buf, string, 5, NULL, NULL);
2583 	FREEZE_EQ(r, 0, -1);
2584 	r = evbuffer_add_printf(buf, "Hello %s", "world");
2585 	FREEZE_EQ(r, 11, -1);
2586 
2587 	r = evbuffer_add_buffer(buf, tmp_buf);
2588 	FREEZE_EQ(r, 0, -1);
2589 	len = strlen(tmpfilecontent);
2590 	fd = regress_make_tmpfile(tmpfilecontent, len, &tmpfilename);
2591 	r = evbuffer_add_file(buf, fd, 0, len);
2592 	FREEZE_EQ(r, 0, -1);
2593 
2594 	if (start)
2595 		evbuffer_add(tmp_buf, "xyz", 3);
2596 
2597 	tt_assert(evbuffer_get_length(tmp_buf));
2598 	len = evbuffer_get_length(tmp_buf);
2599 	evbuffer_write(tmp_buf, pair[0]);
2600 	r = evbuffer_read(buf, pair[1], -1);
2601 	FREEZE_EQ(r, len, -1);
2602 
2603 	if (!start)
2604 		tt_int_op(orig_length, ==, evbuffer_get_length(buf));
2605 
2606 	orig_length = evbuffer_get_length(buf);
2607 
2608 	/* These functions all manipulate the start of buf. */
2609 	r = evbuffer_remove(buf, charbuf, 1);
2610 	FREEZE_EQ(r, -1, 1);
2611 	r = evbuffer_drain(buf, 3);
2612 	FREEZE_EQ(r, -1, 0);
2613 	r = evbuffer_prepend(buf, "dummy", 5);
2614 	FREEZE_EQ(r, -1, 0);
2615 	cp = evbuffer_readln(buf, NULL, EVBUFFER_EOL_LF);
2616 	FREEZE_EQ(cp==NULL, 1, 0);
2617 	if (cp)
2618 		free(cp);
2619 
2620 	evbuffer_add(tmp_buf, "xyz", 3);
2621 	tt_assert(evbuffer_get_length(tmp_buf));
2622 	r = evbuffer_remove_buffer(buf, tmp_buf, 3);
2623 	FREEZE_EQ(r, -1, 3);
2624 	r = evbuffer_drain(buf, 3);
2625 	FREEZE_EQ(r, -1, 0);
2626 	r = evbuffer_prepend_buffer(buf, tmp_buf);
2627 	FREEZE_EQ(r, -1, 0);
2628 
2629 	len = evbuffer_get_length(buf);
2630 	r = evbuffer_write(buf, pair[0]);
2631 	evbuffer_read(tmp_buf, pair[1], -1);
2632 	FREEZE_EQ(r, -1, len);
2633 	len = evbuffer_get_length(buf_two);
2634 	r = evbuffer_write_atmost(buf_two, pair[0], -1);
2635 	evbuffer_read(tmp_buf, pair[1], -1);
2636 	FREEZE_EQ(r, -1, len);
2637 
2638 	if (start)
2639 		tt_int_op(orig_length, ==, evbuffer_get_length(buf));
2640 
2641 end:
2642 	if (buf)
2643 		evbuffer_free(buf);
2644 
2645 	if (buf_two)
2646 		evbuffer_free(buf_two);
2647 
2648 	if (tmp_buf)
2649 		evbuffer_free(tmp_buf);
2650 
2651 	if (tmpfilename) {
2652 		unlink(tmpfilename);
2653 		free(tmpfilename);
2654 	}
2655 }
2656 
2657 static void
test_evbuffer_add_iovec(void * ptr)2658 test_evbuffer_add_iovec(void * ptr)
2659 {
2660 	struct evbuffer * buf = NULL;
2661 	struct evbuffer_iovec vec[4];
2662 	const char * data[] = {
2663 		"Guilt resembles a sword with two edges.",
2664 		"On the one hand, it cuts for Justice, imposing practical morality upon those who fear it.",
2665 		"Conscience does not always adhere to rational judgment.",
2666 		"Guilt is always a self-imposed burden, but it is not always rightly imposed."
2667 		/* -- R.A. Salvatore, _Sojurn_ */
2668 	};
2669 	size_t expected_length = 0;
2670 	size_t returned_length = 0;
2671 	int i;
2672 
2673 	buf = evbuffer_new();
2674 
2675 	tt_assert(buf);
2676 
2677 	for (i = 0; i < 4; i++) {
2678 		vec[i].iov_len  = strlen(data[i]);
2679 		vec[i].iov_base = (char*) data[i];
2680 		expected_length += vec[i].iov_len;
2681 	}
2682 
2683 	returned_length = evbuffer_add_iovec(buf, vec, 4);
2684 
2685 	tt_int_op(returned_length, ==, evbuffer_get_length(buf));
2686 	tt_int_op(evbuffer_get_length(buf), ==, expected_length);
2687 
2688 	for (i = 0; i < 4; i++) {
2689 		char charbuf[1024];
2690 
2691 		memset(charbuf, 0, 1024);
2692 		evbuffer_remove(buf, charbuf, strlen(data[i]));
2693 		tt_assert(strcmp(charbuf, data[i]) == 0);
2694 	}
2695 
2696 	tt_assert(evbuffer_get_length(buf) == 0);
2697 end:
2698 	if (buf) {
2699 		evbuffer_free(buf);
2700 	}
2701 }
2702 
2703 static void
test_evbuffer_copyout(void * dummy)2704 test_evbuffer_copyout(void *dummy)
2705 {
2706 	const char string[] =
2707 	    "Still they skirmish to and fro, men my messmates on the snow "
2708 	    "When we headed off the aurochs turn for turn; "
2709 	    "When the rich Allobrogenses never kept amanuenses, "
2710 	    "And our only plots were piled in lakes at Berne.";
2711 	/* -- Kipling, "In The Neolithic Age" */
2712 	char tmp[1024];
2713 	struct evbuffer_ptr ptr;
2714 	struct evbuffer *buf;
2715 
2716 	(void)dummy;
2717 
2718 	buf = evbuffer_new();
2719 	tt_assert(buf);
2720 
2721 	tt_int_op(strlen(string), ==, 206);
2722 
2723 	/* Ensure separate chains */
2724 	evbuffer_add_reference(buf, string, 80, no_cleanup, NULL);
2725 	evbuffer_add_reference(buf, string+80, 80, no_cleanup, NULL);
2726 	evbuffer_add(buf, string+160, strlen(string)-160);
2727 
2728 	tt_int_op(206, ==, evbuffer_get_length(buf));
2729 
2730 	/* First, let's test plain old copyout. */
2731 
2732 	/* Copy a little from the beginning. */
2733 	tt_int_op(10, ==, evbuffer_copyout(buf, tmp, 10));
2734 	tt_int_op(0, ==, memcmp(tmp, "Still they", 10));
2735 
2736 	/* Now copy more than a little from the beginning */
2737 	memset(tmp, 0, sizeof(tmp));
2738 	tt_int_op(100, ==, evbuffer_copyout(buf, tmp, 100));
2739 	tt_int_op(0, ==, memcmp(tmp, string, 100));
2740 
2741 	/* Copy too much; ensure truncation. */
2742 	memset(tmp, 0, sizeof(tmp));
2743 	tt_int_op(206, ==, evbuffer_copyout(buf, tmp, 230));
2744 	tt_int_op(0, ==, memcmp(tmp, string, 206));
2745 
2746 	/* That was supposed to be nondestructive, btw */
2747 	tt_int_op(206, ==, evbuffer_get_length(buf));
2748 
2749 	/* Now it's time to test copyout_from!  First, let's start in the
2750 	 * first chain. */
2751 	evbuffer_ptr_set(buf, &ptr, 15, EVBUFFER_PTR_SET);
2752 	memset(tmp, 0, sizeof(tmp));
2753 	tt_int_op(10, ==, evbuffer_copyout_from(buf, &ptr, tmp, 10));
2754 	tt_int_op(0, ==, memcmp(tmp, "mish to an", 10));
2755 
2756 	/* Right up to the end of the first chain */
2757 	memset(tmp, 0, sizeof(tmp));
2758 	tt_int_op(65, ==, evbuffer_copyout_from(buf, &ptr, tmp, 65));
2759 	tt_int_op(0, ==, memcmp(tmp, string+15, 65));
2760 
2761 	/* Span into the second chain */
2762 	memset(tmp, 0, sizeof(tmp));
2763 	tt_int_op(90, ==, evbuffer_copyout_from(buf, &ptr, tmp, 90));
2764 	tt_int_op(0, ==, memcmp(tmp, string+15, 90));
2765 
2766 	/* Span into the third chain */
2767 	memset(tmp, 0, sizeof(tmp));
2768 	tt_int_op(160, ==, evbuffer_copyout_from(buf, &ptr, tmp, 160));
2769 	tt_int_op(0, ==, memcmp(tmp, string+15, 160));
2770 
2771 	/* Overrun */
2772 	memset(tmp, 0, sizeof(tmp));
2773 	tt_int_op(206-15, ==, evbuffer_copyout_from(buf, &ptr, tmp, 999));
2774 	tt_int_op(0, ==, memcmp(tmp, string+15, 206-15));
2775 
2776 	/* That was supposed to be nondestructive, too */
2777 	tt_int_op(206, ==, evbuffer_get_length(buf));
2778 
2779 end:
2780 	if (buf)
2781 		evbuffer_free(buf);
2782 }
2783 
2784 static void *
setup_passthrough(const struct testcase_t * testcase)2785 setup_passthrough(const struct testcase_t *testcase)
2786 {
2787 	return testcase->setup_data;
2788 }
2789 static int
cleanup_passthrough(const struct testcase_t * testcase,void * ptr)2790 cleanup_passthrough(const struct testcase_t *testcase, void *ptr)
2791 {
2792 	(void) ptr;
2793 	return 1;
2794 }
2795 
2796 static const struct testcase_setup_t nil_setup = {
2797 	setup_passthrough,
2798 	cleanup_passthrough
2799 };
2800 
2801 struct testcase_t evbuffer_testcases[] = {
2802 	{ "evbuffer", test_evbuffer, 0, NULL, NULL },
2803 	{ "remove_buffer_with_empty", test_evbuffer_remove_buffer_with_empty, 0, NULL, NULL },
2804 	{ "remove_buffer_with_empty2", test_evbuffer_remove_buffer_with_empty2, 0, NULL, NULL },
2805 	{ "remove_buffer_with_empty3", test_evbuffer_remove_buffer_with_empty3, 0, NULL, NULL },
2806 	{ "remove_buffer_with_empty_front", test_evbuffer_remove_buffer_with_empty_front, 0, NULL, NULL },
2807 	{ "remove_buffer_adjust_last_with_datap_with_empty",
2808 	  test_evbuffer_remove_buffer_adjust_last_with_datap_with_empty, 0, NULL, NULL },
2809 	{ "add_buffer_with_empty", test_evbuffer_add_buffer_with_empty, 0, NULL, NULL },
2810 	{ "add_buffer_with_empty2", test_evbuffer_add_buffer_with_empty2, 0, NULL, NULL },
2811 	{ "reserve2", test_evbuffer_reserve2, 0, NULL, NULL },
2812 	{ "reserve_many", test_evbuffer_reserve_many, 0, NULL, NULL },
2813 	{ "reserve_many2", test_evbuffer_reserve_many, 0, &nil_setup, (void*)"add" },
2814 	{ "reserve_many3", test_evbuffer_reserve_many, 0, &nil_setup, (void*)"fill" },
2815 	{ "reserve_with_empty", test_evbuffer_reserve_with_empty, 0, NULL, NULL },
2816 	{ "reserve_invalid_last_with_datap", test_evbuffer_reserve_invalid_last_with_datap, TT_FORK, NULL, NULL },
2817 	{ "expand", test_evbuffer_expand, 0, NULL, NULL },
2818 	{ "expand_overflow", test_evbuffer_expand_overflow, 0, NULL, NULL },
2819 	{ "add1", test_evbuffer_add1, 0, NULL, NULL },
2820 	{ "add2", test_evbuffer_add2, 0, NULL, NULL },
2821 	{ "reference", test_evbuffer_reference, 0, NULL, NULL },
2822 	{ "reference2", test_evbuffer_reference2, 0, NULL, NULL },
2823 	{ "iterative", test_evbuffer_iterative, 0, NULL, NULL },
2824 	{ "readln", test_evbuffer_readln, TT_NO_LOGS, &basic_setup, NULL },
2825 	{ "search_eol", test_evbuffer_search_eol, 0, NULL, NULL },
2826 	{ "find", test_evbuffer_find, 0, NULL, NULL },
2827 	{ "ptr_set", test_evbuffer_ptr_set, 0, NULL, NULL },
2828 	{ "search", test_evbuffer_search, 0, NULL, NULL },
2829 	{ "callbacks", test_evbuffer_callbacks, 0, NULL, NULL },
2830 	{ "add_reference", test_evbuffer_add_reference, 0, NULL, NULL },
2831 	{ "multicast", test_evbuffer_multicast, 0, NULL, NULL },
2832 	{ "multicast_drain", test_evbuffer_multicast_drain, 0, NULL, NULL },
2833 	{ "prepend", test_evbuffer_prepend, TT_FORK, NULL, NULL },
2834 	{ "empty_reference_prepend", test_evbuffer_empty_reference_prepend, TT_FORK, NULL, NULL },
2835 	{ "empty_reference_prepend_buffer", test_evbuffer_empty_reference_prepend_buffer, TT_FORK, NULL, NULL },
2836 	{ "peek", test_evbuffer_peek, 0, NULL, NULL },
2837 	{ "peek_first_gt", test_evbuffer_peek_first_gt, 0, NULL, NULL },
2838 	{ "freeze_start", test_evbuffer_freeze, TT_NEED_SOCKETPAIR, &basic_setup, (void*)"start" },
2839 	{ "freeze_end", test_evbuffer_freeze, TT_NEED_SOCKETPAIR, &basic_setup, (void*)"end" },
2840 	{ "add_iovec", test_evbuffer_add_iovec, 0, NULL, NULL},
2841 	{ "copyout", test_evbuffer_copyout, 0, NULL, NULL},
2842 	{ "file_segment_add_cleanup_cb", test_evbuffer_file_segment_add_cleanup_cb, 0, NULL, NULL },
2843 	{ "pullup_with_empty", test_evbuffer_pullup_with_empty, 0, NULL, NULL },
2844 
2845 #define ADDFILE_TEST(name, parameters)					\
2846 	{ name, test_evbuffer_add_file, TT_FORK|TT_NEED_BASE,		\
2847 	  &basic_setup, (void*)(parameters) }
2848 
2849 #define ADDFILE_TEST_GROUP(name, parameters)			\
2850 	ADDFILE_TEST(name "_sendfile", "sendfile " parameters), \
2851 	ADDFILE_TEST(name "_mmap", "mmap " parameters),		\
2852 	ADDFILE_TEST(name "_linear", "linear " parameters)
2853 
2854 	ADDFILE_TEST_GROUP("add_file", ""),
2855 	ADDFILE_TEST("add_file_nosegment", "default nosegment"),
2856 
2857 	ADDFILE_TEST_GROUP("add_big_file", "bigfile"),
2858 	ADDFILE_TEST("add_big_file_nosegment", "default nosegment bigfile"),
2859 
2860 	ADDFILE_TEST_GROUP("add_file_offset", "bigfile map_offset"),
2861 	ADDFILE_TEST("add_file_offset_nosegment",
2862 	    "default nosegment bigfile map_offset"),
2863 
2864 	ADDFILE_TEST_GROUP("add_file_offset2", "bigfile offset_in_segment"),
2865 
2866 	ADDFILE_TEST_GROUP("add_file_offset3",
2867 	    "bigfile offset_in_segment map_offset"),
2868 
2869 	END_OF_TESTCASES
2870 };
2871