diff options
author | Gary Kramlich <grim@reaperworld.com> | 2017-11-17 03:03:28 +0000 |
---|---|---|
committer | Gary Kramlich <grim@reaperworld.com> | 2017-11-17 03:03:28 +0000 |
commit | 26e3275def6cb74df652bcc82683995cbe3a1f72 (patch) | |
tree | c5a723baeb61900673bf2e49020e684b25a7c5ae | |
parent | 8f39c69cdda6059b8a5869f1a155c31ec5f7ab9e (diff) | |
parent | a7632f62255ff67c802742c0d0a2270adfa12228 (diff) | |
download | pidgin-26e3275def6cb74df652bcc82683995cbe3a1f72.tar.gz |
Merged in slingamn/pidgin_main/bug_12562 (pull request #272)
fixes to IRC buffer handling, replaces #256
Approved-by: Eion Robb <eionrobb@gmail.com>
Approved-by: Gary Kramlich <grim@reaperworld.com>
Approved-by: Ethan Blanton <elb@kb8ojh.net>
-rw-r--r-- | libpurple/protocols/irc/irc.c | 45 | ||||
-rw-r--r-- | libpurple/protocols/irc/irc.h | 3 |
2 files changed, 31 insertions, 17 deletions
diff --git a/libpurple/protocols/irc/irc.c b/libpurple/protocols/irc/irc.c index 2078985d90..133c4d1aa0 100644 --- a/libpurple/protocols/irc/irc.c +++ b/libpurple/protocols/irc/irc.c @@ -685,31 +685,38 @@ static void irc_input_cb_ssl(gpointer data, PurpleSslConnection *gsc, return; } - if (irc->inbuflen < irc->inbufused + IRC_INITIAL_BUFSIZE) { - irc->inbuflen += IRC_INITIAL_BUFSIZE; - irc->inbuf = g_realloc(irc->inbuf, irc->inbuflen); - } + do { + // resize buffer upwards so we have at least IRC_BUFSIZE_INCREMENT + // bytes free in inbuf + if (irc->inbuflen < irc->inbufused + IRC_BUFSIZE_INCREMENT) { + if (irc->inbuflen + IRC_BUFSIZE_INCREMENT <= IRC_MAX_BUFSIZE) { + irc->inbuflen += IRC_BUFSIZE_INCREMENT; + irc->inbuf = g_realloc(irc->inbuf, irc->inbuflen); + } else { + // discard unparseable data from the buffer + irc->inbufused = 0; + } + } - len = purple_ssl_read(gsc, irc->inbuf + irc->inbufused, IRC_INITIAL_BUFSIZE - 1); + len = purple_ssl_read(gsc, irc->inbuf + irc->inbufused, irc->inbuflen - irc->inbufused - 1); + if (len > 0) { + read_input(irc, len); + } + } while (len > 0); - if (len < 0 && errno == EAGAIN) { - /* Try again later */ - return; - } else if (len < 0) { + if (len < 0 && errno != EAGAIN) { gchar *tmp = g_strdup_printf(_("Lost connection with server: %s"), g_strerror(errno)); purple_connection_error_reason (gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp); g_free(tmp); - return; } else if (len == 0) { purple_connection_error_reason (gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Server closed the connection")); - return; } - read_input(irc, len); + /* else: len < 0 && errno == EAGAIN; this is fine, try again later */ } static void irc_input_cb(gpointer data, gint source, PurpleInputCondition cond) @@ -718,12 +725,18 @@ static void irc_input_cb(gpointer data, gint source, PurpleInputCondition cond) struct irc_conn *irc = gc->proto_data; int len; - if (irc->inbuflen < irc->inbufused + IRC_INITIAL_BUFSIZE) { - irc->inbuflen += IRC_INITIAL_BUFSIZE; - irc->inbuf = g_realloc(irc->inbuf, irc->inbuflen); + /* see irc_input_cb_ssl */ + if (irc->inbuflen < irc->inbufused + IRC_BUFSIZE_INCREMENT) { + if (irc->inbuflen + IRC_BUFSIZE_INCREMENT <= IRC_MAX_BUFSIZE) { + irc->inbuflen += IRC_BUFSIZE_INCREMENT; + irc->inbuf = g_realloc(irc->inbuf, irc->inbuflen); + } else { + irc->inbufused = 0; + } } - len = read(irc->fd, irc->inbuf + irc->inbufused, IRC_INITIAL_BUFSIZE - 1); + len = read(irc->fd, irc->inbuf + irc->inbufused, irc->inbuflen - irc->inbufused - 1); + if (len < 0 && errno == EAGAIN) { return; } else if (len < 0) { diff --git a/libpurple/protocols/irc/irc.h b/libpurple/protocols/irc/irc.h index fde35c42c7..f587790d60 100644 --- a/libpurple/protocols/irc/irc.h +++ b/libpurple/protocols/irc/irc.h @@ -44,7 +44,8 @@ #define IRC_DEFAULT_QUIT "Leaving." -#define IRC_INITIAL_BUFSIZE 1024 +#define IRC_BUFSIZE_INCREMENT 1024 +#define IRC_MAX_BUFSIZE 16384 #define IRC_MAX_MSG_SIZE 512 |