]> granicus.if.org Git - libevent/commitdiff
fix evbuffer_find off by one; found by Ken Cox; regression test by him
authorNiels Provos <provos@gmail.com>
Thu, 19 Apr 2007 03:13:12 +0000 (03:13 +0000)
committerNiels Provos <provos@gmail.com>
Thu, 19 Apr 2007 03:13:12 +0000 (03:13 +0000)
and fix by me

svn:r353

buffer.c
configure.in
test/regress.c

index 77efd0cfa3e207d76d28fc49cea55a3fd605d6f9..53c0bf8cb2f604ce9aa39887a61d2be2ea5b1887 100644 (file)
--- 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);
index c4faf015a5a208e5fd94de2e5efb3486f72156a1..16517521740fed6ff233481a9db161ef211f3051 100644 (file)
@@ -2,7 +2,7 @@ dnl configure.in for libevent
 dnl Dug Song <dugsong@monkey.org>
 AC_INIT(event.c)
 
-AM_INIT_AUTOMAKE(libevent,1.3a)
+AM_INIT_AUTOMAKE(libevent,1.3b)
 AM_CONFIG_HEADER(config.h)
 AM_MAINTAINER_MODE
 
index 9cd739da70772a277aedd10a578ddbf9058db02b..dbf0fe02e7ba60c44901d957102bfebed5df0b8b 100644 (file)
@@ -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);