From 4408a5f8fc5028c67fc847e34a10891cb3523351 Mon Sep 17 00:00:00 2001 From: Niels Provos Date: Thu, 19 Apr 2007 03:13:12 +0000 Subject: [PATCH] fix evbuffer_find off by one; found by Ken Cox; regression test by him and fix by me svn:r353 --- buffer.c | 9 ++++--- configure.in | 2 +- test/regress.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 65 insertions(+), 10 deletions(-) diff --git a/buffer.c b/buffer.c index 77efd0cf..53c0bf8c 100644 --- a/buffer.c +++ b/buffer.c @@ -431,13 +431,12 @@ evbuffer_write(struct evbuffer *buffer, int fd) u_char * evbuffer_find(struct evbuffer *buffer, const u_char *what, size_t len) { - size_t remain = buffer->off; - u_char *search = buffer->buffer; + u_char *search = buffer->buffer, *end = search + buffer->off; u_char *p; - while ((p = memchr(search, *what, remain)) != NULL) { - remain = buffer->off - (size_t)(search - buffer->buffer); - if (remain < len) + while (search < end && + (p = memchr(search, *what, end - search)) != NULL) { + if (p + len > end) break; if (memcmp(p, what, len) == 0) return (p); diff --git a/configure.in b/configure.in index c4faf015..16517521 100644 --- a/configure.in +++ b/configure.in @@ -2,7 +2,7 @@ dnl configure.in for libevent dnl Dug Song AC_INIT(event.c) -AM_INIT_AUTOMAKE(libevent,1.3a) +AM_INIT_AUTOMAKE(libevent,1.3b) AM_CONFIG_HEADER(config.h) AM_MAINTAINER_MODE diff --git a/test/regress.c b/test/regress.c index 9cd739da..dbf0fe02 100644 --- a/test/regress.c +++ b/test/regress.c @@ -604,6 +604,61 @@ test_evbuffer(void) { cleanup_test(); } +void +test_evbuffer_find(void) +{ + u_char* p; + char* test1 = "1234567890\r\n"; + char* test2 = "1234567890\r"; +#define EVBUFFER_INITIAL_LENGTH 256 + char test3[EVBUFFER_INITIAL_LENGTH]; + unsigned int i; + struct evbuffer * buf = evbuffer_new(); + + /* make sure evbuffer_find doesn't match past the end of the buffer */ + fprintf(stdout, "Testing evbuffer_find 1: "); + evbuffer_add(buf, (u_char*)test1, strlen(test1)); + evbuffer_drain(buf, strlen(test1)); + evbuffer_add(buf, (u_char*)test2, strlen(test2)); + p = evbuffer_find(buf, (u_char*)"\r\n", 2); + if (p == NULL) { + fprintf(stdout, "OK\n"); + } else { + fprintf(stdout, "FAILED\n"); + exit(1); + } + + /* + * drain the buffer and do another find; in r309 this would + * read past the allocated buffer causing a valgrind error. + */ + fprintf(stdout, "Testing evbuffer_find 2: "); + evbuffer_drain(buf, strlen(test2)); + for (i = 0; i < EVBUFFER_INITIAL_LENGTH; ++i) + test3[i] = 'a'; + test3[EVBUFFER_INITIAL_LENGTH - 1] = 'x'; + evbuffer_add(buf, (u_char *)test3, EVBUFFER_INITIAL_LENGTH); + p = evbuffer_find(buf, (u_char *)"xy", 2); + if (p == NULL) { + printf("OK\n"); + } else { + fprintf(stdout, "FAILED\n"); + exit(1); + } + + /* simple test for match at end of allocated buffer */ + fprintf(stdout, "Testing evbuffer_find 3: "); + p = evbuffer_find(buf, (u_char *)"ax", 2); + if (p != NULL && strncmp(p, "ax", 2) == 0) { + printf("OK\n"); + } else { + fprintf(stdout, "FAILED\n"); + exit(1); + } + + evbuffer_free(buf); +} + void readcb(struct bufferevent *bev, void *arg) { @@ -988,6 +1043,11 @@ main (int argc, char **argv) /* Initalize the event library */ event_base = event_init(); + test_evbuffer(); + test_evbuffer_find(); + + test_bufferevent(); + http_suite(); rpc_suite(); @@ -1011,10 +1071,6 @@ main (int argc, char **argv) #endif test_loopexit(); - test_evbuffer(); - - test_bufferevent(); - test_priorities(1); test_priorities(2); test_priorities(3);