From 4461f1a096621db8b24edafac409e0f05072d35a Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Mon, 6 Jun 2011 15:11:28 -0400 Subject: [PATCH] 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. --- buffer.c | 2 +- test/regress_buffer.c | 54 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 54 insertions(+), 2 deletions(-) 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 },