summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGary Kramlich <grim@reaperworld.com>2017-11-17 03:03:28 +0000
committerGary Kramlich <grim@reaperworld.com>2017-11-17 03:03:28 +0000
commit26e3275def6cb74df652bcc82683995cbe3a1f72 (patch)
treec5a723baeb61900673bf2e49020e684b25a7c5ae
parent8f39c69cdda6059b8a5869f1a155c31ec5f7ab9e (diff)
parenta7632f62255ff67c802742c0d0a2270adfa12228 (diff)
downloadpidgin-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.c45
-rw-r--r--libpurple/protocols/irc/irc.h3
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