From: Vsevolod Stakhov Date: Fri, 6 Feb 2009 17:04:54 +0000 (+0300) Subject: * Try to fix reading a line from user (using pools) X-Git-Tag: 0.2.7~313 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=acec2b42286f734eacb7bab14d7d20e1110f4545;p=thirdparty%2Frspamd.git * Try to fix reading a line from user (using pools) --- diff --git a/src/controller.c b/src/controller.c index 104b8d7cab..d49a68b47c 100644 --- a/src/controller.c +++ b/src/controller.c @@ -368,7 +368,7 @@ read_socket (struct bufferevent *bev, void *arg) switch (session->state) { case STATE_COMMAND: - s = evbuffer_readline (EVBUFFER_INPUT (bev)); + s = buffer_readline (session->session_pool, EVBUFFER_INPUT (bev)); msg_debug ("read_socket: got '%s' string from user", s); if (s != NULL && *s != 0) { len = strlen (s); @@ -412,9 +412,6 @@ read_socket (struct bufferevent *bev, void *arg) else { bufferevent_enable (bev, EV_WRITE); } - if (s != NULL) { - free (s); - } break; case STATE_LEARN: i = bufferevent_read (bev, session->learn_buf->pos, session->learn_buf->free); diff --git a/src/util.c b/src/util.c index 9444592cf2..0cda8a8c84 100644 --- a/src/util.c +++ b/src/util.c @@ -893,6 +893,51 @@ resolve_stat_filename (memory_pool_t *pool, char *pattern, char *rcpt, char *fro return new; } +/* + * These functions are from libevent where they are static and not exported anywhere + * XXX: think how to avoid this + */ + +char * +buffer_readline (memory_pool_t *pool, struct evbuffer *buf) +{ + u_char *data = EVBUFFER_DATA (buf); + size_t len = EVBUFFER_LENGTH (buf); + char *line, fch, sch; + unsigned int i; + + for (i = 0; i < len; i++) { + if (data[i] == '\r' || data[i] == '\n') { + break; + } + } + + if (i == len) { + return (NULL); + } + + line = memory_pool_alloc (pool, i + 1); + + memcpy (line, data, i); + line[i] = '\0'; + + /* + * Some protocols terminate a line with '\r\n', so check for + * that, too. + */ + if ( i < len - 1 ) { + fch = data[i], sch = data[i+1]; + + /* Drain one more character if needed */ + if ( (sch == '\r' || sch == '\n') && sch != fch ) + i += 1; + } + + evbuffer_drain (buf, i + 1); + + return (line); +} + /* * vi:ts=4 */ diff --git a/src/util.h b/src/util.h index c0fb77eeb3..3036d37fd0 100644 --- a/src/util.h +++ b/src/util.h @@ -66,5 +66,8 @@ void file_log_function (const gchar *log_domain, GLogLevelFlags log_level, const /* Replace %r with rcpt value and %f with from value, new string is allocated in pool */ char* resolve_stat_filename (memory_pool_t *pool, char *pattern, char *rcpt, char *from); +/* Replace libevent evbuffer_readline with memory_pool variant */ +char* buffer_readline (memory_pool_t *pool, struct evbuffer *buf); + #endif diff --git a/src/worker.c b/src/worker.c index 2cd7a05ffe..7e6699c930 100644 --- a/src/worker.c +++ b/src/worker.c @@ -128,7 +128,11 @@ read_socket (struct bufferevent *bev, void *arg) switch (task->state) { case READ_COMMAND: case READ_HEADER: - s = evbuffer_readline (EVBUFFER_INPUT (bev)); + s = buffer_readline (task->task_pool, EVBUFFER_INPUT (bev)); + if (s == NULL) { + msg_debug ("read_socket: got incomplete line from user"); + return; + } if (read_rspamd_input_line (task, s) != 0) { task->last_error = "Read error"; task->error_code = RSPAMD_NETWORK_ERROR; @@ -138,7 +142,6 @@ read_socket (struct bufferevent *bev, void *arg) bufferevent_enable (bev, EV_WRITE); bufferevent_disable (bev, EV_READ); } - free (s); break; case READ_MESSAGE: r = bufferevent_read (bev, task->msg->pos, task->msg->free);