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