From: Nick Mathewson Date: Mon, 6 Jun 2011 19:11:28 +0000 (-0400) Subject: Fix incorrect results from evbuffer_search_eol(EOL_LF) X-Git-Tag: release-2.0.13-stable~23 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4461f1a096621db8b24edafac409e0f05072d35a;p=libevent Fix incorrect results from evbuffer_search_eol(EOL_LF) Our evbuffer_strchr() function [which was only used for search_eol(EOL_LF) could give incorrect results if it found its answer in the first chunk but didn't start searching from the front of the chunk. Also, this patch adds unit tests for evbuffer_search_eol, particularly in those cases that evbuffer_readln() tests didn't exercise. --- diff --git a/buffer.c b/buffer.c index 50908b19..ee600cac 100644 --- a/buffer.c +++ b/buffer.c @@ -1249,7 +1249,7 @@ evbuffer_strchr(struct evbuffer_ptr *it, const char chr) if (cp) { it->_internal.chain = chain; it->_internal.pos_in_chain = cp - buffer; - it->pos += (cp - buffer); + it->pos += (cp - buffer - i); return it->pos; } it->pos += chain->off - i; diff --git a/test/regress_buffer.c b/test/regress_buffer.c index 327210b0..4deaef57 100644 --- a/test/regress_buffer.c +++ b/test/regress_buffer.c @@ -881,13 +881,63 @@ test_evbuffer_readln(void *ptr) free(cp); cp = NULL; evbuffer_validate(evb); - test_ok = 1; end: evbuffer_free(evb); evbuffer_free(evb_tmp); if (cp) free(cp); } +static void +test_evbuffer_search_eol(void *ptr) +{ + struct evbuffer *buf = evbuffer_new(); + struct evbuffer_ptr ptr1, ptr2; + const char *s; + size_t eol_len; + + s = "string! \r\n\r\nx\n"; + evbuffer_add(buf, s, strlen(s)); + eol_len = -1; + ptr1 = evbuffer_search_eol(buf, NULL, &eol_len, EVBUFFER_EOL_CRLF); + tt_int_op(ptr1.pos, ==, 8); + tt_int_op(eol_len, ==, 2); + + eol_len = -1; + ptr2 = evbuffer_search_eol(buf, &ptr1, &eol_len, EVBUFFER_EOL_CRLF); + tt_int_op(ptr2.pos, ==, 8); + tt_int_op(eol_len, ==, 2); + + evbuffer_ptr_set(buf, &ptr1, 1, EVBUFFER_PTR_ADD); + eol_len = -1; + ptr2 = evbuffer_search_eol(buf, &ptr1, &eol_len, EVBUFFER_EOL_CRLF); + tt_int_op(ptr2.pos, ==, 9); + tt_int_op(eol_len, ==, 1); + + eol_len = -1; + ptr2 = evbuffer_search_eol(buf, &ptr1, &eol_len, EVBUFFER_EOL_CRLF_STRICT); + tt_int_op(ptr2.pos, ==, 10); + tt_int_op(eol_len, ==, 2); + + eol_len = -1; + ptr1 = evbuffer_search_eol(buf, NULL, &eol_len, EVBUFFER_EOL_LF); + tt_int_op(ptr1.pos, ==, 9); + tt_int_op(eol_len, ==, 1); + + eol_len = -1; + ptr2 = evbuffer_search_eol(buf, &ptr1, &eol_len, EVBUFFER_EOL_LF); + tt_int_op(ptr2.pos, ==, 9); + tt_int_op(eol_len, ==, 1); + + evbuffer_ptr_set(buf, &ptr1, 1, EVBUFFER_PTR_ADD); + eol_len = -1; + ptr2 = evbuffer_search_eol(buf, &ptr1, &eol_len, EVBUFFER_EOL_LF); + tt_int_op(ptr2.pos, ==, 11); + tt_int_op(eol_len, ==, 1); + +end: + evbuffer_free(buf); +} + static void test_evbuffer_iterative(void *ptr) { @@ -1074,6 +1124,7 @@ test_evbuffer_search(void *ptr) pos = evbuffer_search_range(buf, "ack", 3, NULL, &end); tt_int_op(pos.pos, ==, -1); + end: if (buf) evbuffer_free(buf); @@ -1548,6 +1599,7 @@ struct testcase_t evbuffer_testcases[] = { { "reference", test_evbuffer_reference, 0, NULL, NULL }, { "iterative", test_evbuffer_iterative, 0, NULL, NULL }, { "readln", test_evbuffer_readln, TT_NO_LOGS, &basic_setup, NULL }, + { "search_eol", test_evbuffer_search_eol, 0, NULL, NULL }, { "find", test_evbuffer_find, 0, NULL, NULL }, { "ptr_set", test_evbuffer_ptr_set, 0, NULL, NULL }, { "search", test_evbuffer_search, 0, NULL, NULL },