diff --git a/Makefile.am b/Makefile.am index baf15247..24853c9e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -156,6 +156,9 @@ SYS_INCLUDES = endif +if STRLCPY_IMPL +SYS_SRC += strlcpy.c +endif if SELECT_BACKEND SYS_SRC += select.c endif @@ -200,7 +203,6 @@ CORE_SRC = \ evutil_time.c \ listener.c \ log.c \ - strlcpy.c \ $(SYS_SRC) EXTRAS_SRC = \ diff --git a/configure.ac b/configure.ac index 9da77fc9..dd79e4da 100644 --- a/configure.ac +++ b/configure.ac @@ -362,6 +362,7 @@ AC_CHECK_FUNCS([ \ usleep \ vasprintf \ ]) +AM_CONDITIONAL(STRLCPY_IMPL, [test x"$ac_cv_func_strlcpy" = xno]) AC_CACHE_CHECK( [for getaddrinfo], diff --git a/event.c b/event.c index 51e34a99..9286c36f 100644 --- a/event.c +++ b/event.c @@ -2378,12 +2378,18 @@ event_add_nolock_(struct event *ev, const struct timeval *tv, common_timeout_schedule(ctl, &now, ev); } } else { + struct event* top = NULL; /* See if the earliest timeout is now earlier than it * was before: if so, we will need to tell the main - * thread to wake up earlier than it would - * otherwise. */ + * thread to wake up earlier than it would otherwise. + * We double check the timeout of the top element to + * handle time distortions due to system suspension. + */ if (min_heap_elt_is_top_(ev)) notify = 1; + else if ((top = min_heap_top_(&base->timeheap)) != NULL && + evutil_timercmp(&top->ev_timeout, &now, <)) + notify = 1; } } diff --git a/http-internal.h b/http-internal.h index 83aa6ef1..0d4475f5 100644 --- a/http-internal.h +++ b/http-internal.h @@ -197,4 +197,7 @@ void evhttp_start_read_(struct evhttp_connection *); void evhttp_response_code_(struct evhttp_request *, int, const char *); void evhttp_send_page_(struct evhttp_request *, struct evbuffer *); +int evhttp_decode_uri_internal(const char *uri, size_t length, + char *ret, int decode_plus); + #endif /* _HTTP_H */ diff --git a/http.c b/http.c index b94fed8c..f571d356 100644 --- a/http.c +++ b/http.c @@ -193,8 +193,6 @@ static void evhttp_make_header(struct evhttp_connection *, struct evhttp_request static void evhttp_read_cb(struct bufferevent *, void *); static void evhttp_write_cb(struct bufferevent *, void *); static void evhttp_error_cb(struct bufferevent *bufev, short what, void *arg); -static int evhttp_decode_uri_internal(const char *uri, size_t length, - char *ret, int decode_plus); static int evhttp_find_vhost(struct evhttp *http, struct evhttp **outhttp, const char *hostname); @@ -2873,7 +2871,7 @@ evhttp_encode_uri(const char *str) * a ?. -1 is deprecated. * @return the number of bytes written to 'ret'. */ -static int +int evhttp_decode_uri_internal( const char *uri, size_t length, char *ret, int decode_plus_ctl) { @@ -2889,8 +2887,8 @@ evhttp_decode_uri_internal( decode_plus = 1; } else if (c == '+' && decode_plus) { c = ' '; - } else if (c == '%' && EVUTIL_ISXDIGIT_(uri[i+1]) && - EVUTIL_ISXDIGIT_(uri[i+2])) { + } else if ((i + 2) < length && c == '%' && + EVUTIL_ISXDIGIT_(uri[i+1]) && EVUTIL_ISXDIGIT_(uri[i+2])) { char tmp[3]; tmp[0] = uri[i+1]; tmp[1] = uri[i+2]; diff --git a/include/event2/buffer.h b/include/event2/buffer.h index 3791e92d..712e4d79 100644 --- a/include/event2/buffer.h +++ b/include/event2/buffer.h @@ -939,12 +939,13 @@ void evbuffer_cb_unsuspend(struct evbuffer *buffer, struct evbuffer_cb_entry *cb #endif /** - Makes the data at the begging of an evbuffer contiguous. + Makes the data at the beginning of an evbuffer contiguous. @param buf the evbuffer to make contiguous @param size the number of bytes to make contiguous, or -1 to make the entire buffer contiguous. - @return a pointer to the contiguous memory array + @return a pointer to the contiguous memory array, or NULL if param size + requested more data than is present in the buffer. */ unsigned char *evbuffer_pullup(struct evbuffer *buf, ev_ssize_t size); diff --git a/sample/https-client.c b/sample/https-client.c index a9aded00..99abc692 100644 --- a/sample/https-client.c +++ b/sample/https-client.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include @@ -73,9 +72,11 @@ http_request_done(struct evhttp_request *req, void *ctx) } fprintf(stderr, "Response line: %d %s\n", - req->response_code, req->response_code_line); + evhttp_request_get_response_code(req), + evhttp_request_get_response_code_line(req)); - while ((nread = evbuffer_remove(req->input_buffer, buffer, sizeof(buffer))) + while ((nread = evbuffer_remove(evhttp_request_get_input_buffer(req), + buffer, sizeof(buffer))) > 0) { /* These are just arbitrary chunks of 256 bytes. * They are not lines, so we can't treat them as such. */ @@ -187,6 +188,7 @@ main(int argc, char **argv) struct bufferevent *bev; struct evhttp_connection *evcon; struct evhttp_request *req; + struct evkeyvalq *output_headers; int i; @@ -341,8 +343,9 @@ main(int argc, char **argv) return 1; } - evhttp_add_header(req->output_headers, "Host", host); - evhttp_add_header(req->output_headers, "Connection", "close"); + output_headers = evhttp_request_get_output_headers(req); + evhttp_add_header(output_headers, "Host", host); + evhttp_add_header(output_headers, "Connection", "close"); if (data_file) { FILE * f = fopen(data_file, "rb"); diff --git a/test/include.am b/test/include.am index 82cfe4eb..324df347 100644 --- a/test/include.am +++ b/test/include.am @@ -29,12 +29,10 @@ TESTPROGRAMS = \ test/test-weof \ test/regress -noinst_PROGRAMS += $(TESTPROGRAMS) - if BUILD_REGRESS -noinst_PROGRAMS += test/regress -endif +noinst_PROGRAMS += $(TESTPROGRAMS) EXTRA_PROGRAMS+= test/regress +endif noinst_HEADERS+= \ test/regress.h \ @@ -47,7 +45,7 @@ noinst_HEADERS+= \ TESTS = test/test-script.sh test/test-script.sh: test/test.sh - cp $< $@ + cp $(top_srcdir)/test/test.sh $@ DISTCLEANFILES += test/test-script.sh diff --git a/test/regress.c b/test/regress.c index 86b3d197..bfd2e78b 100644 --- a/test/regress.c +++ b/test/regress.c @@ -1406,6 +1406,13 @@ test_active_later(void *ptr) tt_int_op(n_write_a_byte_cb, >, 100); tt_int_op(n_read_and_drain_cb, >, 100); tt_int_op(n_activate_other_event_cb, >, 100); + + /* Now leave this one around, so that event_free sees it and removes + * it. */ + event_active_later_(&ev3, EV_READ); + event_base_assert_ok_(data->base); + event_base_free(data->base); + data->base = NULL; end: ; } diff --git a/test/regress_http.c b/test/regress_http.c index 3ed314a0..70b40d17 100644 --- a/test/regress_http.c +++ b/test/regress_http.c @@ -2396,6 +2396,7 @@ http_uriencode_test(void *ptr) { char *s=NULL, *s2=NULL; size_t sz; + int bytes_decoded; #define ENC(from,want,plus) do { \ s = evhttp_uriencode((from), -1, (plus)); \ @@ -2452,6 +2453,15 @@ http_uriencode_test(void *ptr) free(s); s = NULL; + /* Now try decoding just part of string. */ + s = malloc(6 + 1 /* NUL byte */); + bytes_decoded = evhttp_decode_uri_internal("hello%20%20", 6, s, 0); + tt_assert(s); + tt_int_op(bytes_decoded,==,6); + tt_str_op(s,==,"hello%"); + free(s); + s = NULL; + /* Now try out some decoding cases that we don't generate with * encode_uri: Make sure that malformed stuff doesn't crash... */ DEC("%%xhello th+ere \xff", diff --git a/test/regress_main.c b/test/regress_main.c index 11e5f8d9..a47a78ae 100644 --- a/test/regress_main.c +++ b/test/regress_main.c @@ -438,6 +438,9 @@ main(int argc, const char **argv) evthread_enable_lock_debugging(); #endif + if (getenv("EVENT_DEBUG_MODE")) + event_enable_debug_mode(); + tinytest_set_aliases(testaliases); if (tinytest_main(argc,argv,testgroups))