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)); 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_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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 * 1189 failing_malloc(size_t how_much) 1190 { 1191 errno = ENOMEM; 1192 return NULL; 1193 } 1194 #endif 1195 1196 static void 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 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 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 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 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 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 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 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 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; 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 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 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 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 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 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 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 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 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 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 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 * 2486 setup_passthrough(const struct testcase_t *testcase) 2487 { 2488 return testcase->setup_data; 2489 } 2490 static int 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