]> granicus.if.org Git - libevent/commitdiff
Do not drop data from evbuffer when out of memory; reported by Jacek Masiulaniec
authorNiels Provos <provos@gmail.com>
Thu, 24 Sep 2009 22:18:19 +0000 (22:18 +0000)
committerNiels Provos <provos@gmail.com>
Thu, 24 Sep 2009 22:18:19 +0000 (22:18 +0000)
svn:r1436

ChangeLog
buffer.c
test/regress_buffer.c

index d005b2141bb7d05ab2ac0b8371c85867f5527d48..ff45f1a5cfe70ca3c1b8598c536a1a636d83eae0 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -22,6 +22,7 @@ Changes in 2.0.3-alpha:
  o Do not allocate the maximum event queue for the epoll backend at startup.  Instead, start out accepting 32 events at a time, and double the queue's size when it seems that the OS is generating events faster than we're requesting them.  Saves up to 374K per epoll-based event_base.  Resolves bug 2839240.
  o Treat an event with a negative fd as valid but untriggerable by Libevent.  This is useful for applications that want to manually activate events.
  o Fix compilation on Android, which forgot to define fd_mask in its sys/select.h
+ o Do not drop data from evbuffer when out of memory; reported by Jacek Masiulaniec
  
 
 Changes in 2.0.2-alpha:
index 370823e2ba912f1f354ca2396d39122a58cbc98a..979bc7d08b422886b0e776422cc359537ddcb989 100644 (file)
--- a/buffer.c
+++ b/buffer.c
@@ -1172,7 +1172,6 @@ evbuffer_readln(struct evbuffer *buffer, size_t *n_read_out,
 
        if ((line = mm_malloc(n_to_copy+1)) == NULL) {
                event_warn("%s: out of memory\n", __func__);
-               evbuffer_drain(buffer, n_to_copy + extra_drain);
                goto done;
        }
 
index a6031a026831675840186884eb146e50c670d039..ff0b97227b26019faf116b5f32d43d313372c9fc 100644 (file)
@@ -403,6 +403,12 @@ test_evbuffer_add_file(void *ptr)
 }
 #endif
 
+static void *
+failing_malloc(size_t how_much)
+{
+       return NULL;
+}
+
 static void
 test_evbuffer_readln(void *ptr)
 {
@@ -586,6 +592,31 @@ test_evbuffer_readln(void *ptr)
        evbuffer_validate(evb);
        tt_assert(evbuffer_get_length(evb) == 0);
 
+       /* Test memory problem*/
+       s = "one line\ntwo line\nblue line";
+       evbuffer_add(evb_tmp, s, strlen(s));
+       evbuffer_validate(evb);
+       evbuffer_add_buffer(evb, evb_tmp);
+       evbuffer_validate(evb);
+
+       cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
+       tt_line_eq("one line");
+       free(cp); cp = NULL;
+       evbuffer_validate(evb);
+
+       /* the next call to readline should fail */
+       event_set_mem_functions(failing_malloc, realloc, free);
+       cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
+       tt_assert(cp == NULL);
+       evbuffer_validate(evb);
+
+       /* now we should get the next line back */
+       event_set_mem_functions(malloc, realloc, free);
+       cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
+       tt_line_eq("two line");
+       free(cp); cp = NULL;
+       evbuffer_validate(evb);
+
        test_ok = 1;
  end:
        evbuffer_free(evb);