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